diff options
Diffstat (limited to 'lib/public/DB')
-rw-r--r-- | lib/public/DB/Events/AddMissingColumnsEvent.php | 43 | ||||
-rw-r--r-- | lib/public/DB/Events/AddMissingIndicesEvent.php | 100 | ||||
-rw-r--r-- | lib/public/DB/Events/AddMissingPrimaryKeyEvent.php | 43 | ||||
-rw-r--r-- | lib/public/DB/Exception.php | 30 | ||||
-rw-r--r-- | lib/public/DB/IPreparedStatement.php | 21 | ||||
-rw-r--r-- | lib/public/DB/IResult.php | 22 | ||||
-rw-r--r-- | lib/public/DB/ISchemaWrapper.php | 22 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/ICompositeExpression.php | 23 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/IExpressionBuilder.php | 57 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/IFunctionBuilder.php | 24 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/ILiteral.php | 24 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/IParameter.php | 24 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/IQueryBuilder.php | 190 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/IQueryFunction.php | 24 | ||||
-rw-r--r-- | lib/public/DB/QueryBuilder/Sharded/IShardMapper.php | 25 | ||||
-rw-r--r-- | lib/public/DB/Types.php | 98 |
16 files changed, 486 insertions, 284 deletions
diff --git a/lib/public/DB/Events/AddMissingColumnsEvent.php b/lib/public/DB/Events/AddMissingColumnsEvent.php new file mode 100644 index 00000000000..178a24c0c30 --- /dev/null +++ b/lib/public/DB/Events/AddMissingColumnsEvent.php @@ -0,0 +1,43 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\DB\Events; + +/** + * Event to allow apps to register information about missing database columns + * + * This event will be dispatched for checking on the admin settings and when running + * occ db:add-missing-columns which will then create those columns + * + * @since 28.0.0 + */ +class AddMissingColumnsEvent extends \OCP\EventDispatcher\Event { + /** @var array<array-key, array{tableName: string, columnName: string, typeName: string, options: array{}}> */ + private array $missingColumns = []; + + /** + * @param mixed[] $options + * @since 28.0.0 + */ + public function addMissingColumn(string $tableName, string $columnName, string $typeName, array $options): void { + $this->missingColumns[] = [ + 'tableName' => $tableName, + 'columnName' => $columnName, + 'typeName' => $typeName, + 'options' => $options, + ]; + } + + /** + * @since 28.0.0 + * @return array<array-key, array{tableName: string, columnName: string, typeName: string, options: array{}}> + */ + public function getMissingColumns(): array { + return $this->missingColumns; + } +} diff --git a/lib/public/DB/Events/AddMissingIndicesEvent.php b/lib/public/DB/Events/AddMissingIndicesEvent.php new file mode 100644 index 00000000000..a8d4c5e6db5 --- /dev/null +++ b/lib/public/DB/Events/AddMissingIndicesEvent.php @@ -0,0 +1,100 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\DB\Events; + +/** + * Event to allow apps to register information about missing database indices + * + * This event will be dispatched for checking on the admin settings and when running + * occ db:add-missing-indices which will then create those indices + * + * @since 28.0.0 + */ +class AddMissingIndicesEvent extends \OCP\EventDispatcher\Event { + /** @var array<array-key, array{tableName: string, indexName: string, columns: string[], options: array{}, dropUnnamedIndex: bool, uniqueIndex: bool}> */ + private array $missingIndices = []; + + /** @var array<array-key, array{tableName: string, oldIndexNames: array, newIndexName: string, columns: string[], uniqueIndex: bool, options: array{}}> */ + private array $toReplaceIndices = []; + + /** + * @param string[] $columns + * @since 28.0.0 + */ + public function addMissingIndex(string $tableName, string $indexName, array $columns, array $options = [], bool $dropUnnamedIndex = false): void { + $this->missingIndices[] = [ + 'tableName' => $tableName, + 'indexName' => $indexName, + 'columns' => $columns, + 'options' => $options, + 'dropUnnamedIndex' => $dropUnnamedIndex, + 'uniqueIndex' => false, + ]; + } + /** + * @param string[] $columns + * @since 28.0.0 + */ + public function addMissingUniqueIndex(string $tableName, string $indexName, array $columns, array $options = [], bool $dropUnnamedIndex = false): void { + $this->missingIndices[] = [ + 'tableName' => $tableName, + 'indexName' => $indexName, + 'columns' => $columns, + 'options' => $options, + 'dropUnnamedIndex' => $dropUnnamedIndex, + 'uniqueIndex' => true, + ]; + } + + /** + * @since 28.0.0 + * @return array<array-key, array{tableName: string, indexName: string, columns: string[], options: array{}, dropUnnamedIndex: bool, uniqueIndex: bool}> + */ + public function getMissingIndices(): array { + return $this->missingIndices; + } + + /** + * Replace one or more existing indices with a new one. Can be used to make an index unique afterwards or merge two indices into a multicolumn index. + * + * Note: Make sure to not use the same index name for the new index as for old indices. + * + * Example: + * + * <code> + * $event->replaceIndex( + * 'my_table', + * ['old_index_col_a', 'old_index_col_b'], + * 'new_index_col_a_b', + * ['column_a', 'column_b'], + * false + * ); + * </code> + * + * @since 29.0.0 + */ + public function replaceIndex(string $tableName, array $oldIndexNames, string $newIndexName, array $columns, bool $unique, array $options = []): void { + $this->toReplaceIndices[] = [ + 'tableName' => $tableName, + 'oldIndexNames' => $oldIndexNames, + 'newIndexName' => $newIndexName, + 'columns' => $columns, + 'uniqueIndex' => $unique, + 'options' => $options, + ]; + } + + /** + * @since 29.0.0 + * @return array<array-key, array{tableName: string, oldIndexNames: array, newIndexName: string, columns: string[], uniqueIndex: bool, options: array{}}> + */ + public function getIndicesToReplace(): array { + return $this->toReplaceIndices; + } +} diff --git a/lib/public/DB/Events/AddMissingPrimaryKeyEvent.php b/lib/public/DB/Events/AddMissingPrimaryKeyEvent.php new file mode 100644 index 00000000000..66c638e66e0 --- /dev/null +++ b/lib/public/DB/Events/AddMissingPrimaryKeyEvent.php @@ -0,0 +1,43 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\DB\Events; + +/** + * Event to allow apps to register information about missing database primary keys + * + * This event will be dispatched for checking on the admin settings and when running + * occ db:add-missing-primary-keys which will then create those keys + * + * @since 28.0.0 + */ +class AddMissingPrimaryKeyEvent extends \OCP\EventDispatcher\Event { + /** @var array<array-key, array{tableName: string, primaryKeyName: string, columns: string[], formerIndex: null|string}> */ + private array $missingPrimaryKeys = []; + + /** + * @param string[] $columns + * @since 28.0.0 + */ + public function addMissingPrimaryKey(string $tableName, string $primaryKeyName, array $columns, ?string $formerIndex = null): void { + $this->missingPrimaryKeys[] = [ + 'tableName' => $tableName, + 'primaryKeyName' => $primaryKeyName, + 'columns' => $columns, + 'formerIndex' => $formerIndex, + ]; + } + + /** + * @since 28.0.0 + * @return array<array-key, array{tableName: string, primaryKeyName: string, columns: string[], formerIndex: null|string}> + */ + public function getMissingPrimaryKeys(): array { + return $this->missingPrimaryKeys; + } +} diff --git a/lib/public/DB/Exception.php b/lib/public/DB/Exception.php index 105cbd188d7..6b908382aea 100644 --- a/lib/public/DB/Exception.php +++ b/lib/public/DB/Exception.php @@ -3,25 +3,8 @@ declare(strict_types=1); /** - * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\DB; @@ -110,7 +93,7 @@ class Exception extends BaseException { public const REASON_NON_UNIQUE_FIELD_NAME = 10; /** - * A not null contraint was violated + * A not null constraint was violated * * @since 21.0.0 */ @@ -138,6 +121,13 @@ class Exception extends BaseException { public const REASON_UNIQUE_CONSTRAINT_VIOLATION = 14; /** + * The lock wait timeout was exceeded + * + * @since 30.0.0 + */ + public const REASON_LOCK_WAIT_TIMEOUT = 15; + + /** * @return int|null * @psalm-return Exception::REASON_* * @since 21.0.0 diff --git a/lib/public/DB/IPreparedStatement.php b/lib/public/DB/IPreparedStatement.php index 2ef5cf7fc46..887451a1caf 100644 --- a/lib/public/DB/IPreparedStatement.php +++ b/lib/public/DB/IPreparedStatement.php @@ -3,25 +3,8 @@ declare(strict_types=1); /** - * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\DB; diff --git a/lib/public/DB/IResult.php b/lib/public/DB/IResult.php index 10a60cd5ff4..347919ab336 100644 --- a/lib/public/DB/IResult.php +++ b/lib/public/DB/IResult.php @@ -3,26 +3,8 @@ declare(strict_types=1); /** - * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Arthur Schiwon <blizzz@arthur-schiwon.de> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\DB; diff --git a/lib/public/DB/ISchemaWrapper.php b/lib/public/DB/ISchemaWrapper.php index 06827203f74..dcf22b52d3d 100644 --- a/lib/public/DB/ISchemaWrapper.php +++ b/lib/public/DB/ISchemaWrapper.php @@ -1,24 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> - * - * @author Joas Schilling <coding@schilljs.com> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\DB; diff --git a/lib/public/DB/QueryBuilder/ICompositeExpression.php b/lib/public/DB/QueryBuilder/ICompositeExpression.php index 56716c628b0..12f321d9e54 100644 --- a/lib/public/DB/QueryBuilder/ICompositeExpression.php +++ b/lib/public/DB/QueryBuilder/ICompositeExpression.php @@ -1,24 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Joas Schilling <coding@schilljs.com> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\DB\QueryBuilder; diff --git a/lib/public/DB/QueryBuilder/IExpressionBuilder.php b/lib/public/DB/QueryBuilder/IExpressionBuilder.php index 53dc1fa5a7f..12e30a45071 100644 --- a/lib/public/DB/QueryBuilder/IExpressionBuilder.php +++ b/lib/public/DB/QueryBuilder/IExpressionBuilder.php @@ -1,28 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author Joas Schilling <coding@schilljs.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\DB\QueryBuilder; @@ -70,10 +51,11 @@ interface IExpressionBuilder { * $expr->andX('u.type = ?', 'u.role = ?')); * * @param mixed ...$x Optional clause. Defaults = null, but requires - * at least one defined when converting to string. + * at least one defined when converting to string. * * @return \OCP\DB\QueryBuilder\ICompositeExpression * @since 8.2.0 + * @since 30.0.0 Calling the method without any arguments is deprecated and will throw with the next Doctrine/DBAL update * * @psalm-taint-sink sql $x */ @@ -89,10 +71,11 @@ interface IExpressionBuilder { * $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?')); * * @param mixed ...$x Optional clause. Defaults = null, but requires - * at least one defined when converting to string. + * at least one defined when converting to string. * * @return \OCP\DB\QueryBuilder\ICompositeExpression * @since 8.2.0 + * @since 30.0.0 Calling the method without any arguments is deprecated and will throw with the next Doctrine/DBAL update * * @psalm-taint-sink sql $x */ @@ -105,7 +88,7 @@ interface IExpressionBuilder { * @param string $operator One of the IExpressionBuilder::* constants. * @param mixed $y The right expression. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -130,7 +113,7 @@ interface IExpressionBuilder { * @param mixed $x The left expression. * @param mixed $y The right expression. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -153,7 +136,7 @@ interface IExpressionBuilder { * @param mixed $x The left expression. * @param mixed $y The right expression. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -176,7 +159,7 @@ interface IExpressionBuilder { * @param mixed $x The left expression. * @param mixed $y The right expression. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -199,7 +182,7 @@ interface IExpressionBuilder { * @param mixed $x The left expression. * @param mixed $y The right expression. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -222,7 +205,7 @@ interface IExpressionBuilder { * @param mixed $x The left expression. * @param mixed $y The right expression. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -245,7 +228,7 @@ interface IExpressionBuilder { * @param mixed $x The left expression. * @param mixed $y The right expression. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -286,7 +269,7 @@ interface IExpressionBuilder { * @param ILiteral|IParameter|IQueryFunction|string $x Field in string format to be inspected by LIKE() comparison. * @param mixed $y Argument to be used in LIKE() comparison. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -303,7 +286,7 @@ interface IExpressionBuilder { * @param ILiteral|IParameter|IQueryFunction|string $x Field in string format to be inspected by NOT LIKE() comparison. * @param mixed $y Argument to be used in NOT LIKE() comparison. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -320,7 +303,7 @@ interface IExpressionBuilder { * @param string $x Field in string format to be inspected by ILIKE() comparison. * @param mixed $y Argument to be used in ILIKE() comparison. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 9.0.0 @@ -337,7 +320,7 @@ interface IExpressionBuilder { * @param ILiteral|IParameter|IQueryFunction|string $x The field in string format to be inspected by IN() comparison. * @param ILiteral|IParameter|IQueryFunction|string|array $y The placeholder or the array of values to be used by IN() comparison. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 @@ -354,7 +337,7 @@ interface IExpressionBuilder { * @param ILiteral|IParameter|IQueryFunction|string $x The field in string format to be inspected by NOT IN() comparison. * @param ILiteral|IParameter|IQueryFunction|string|array $y The placeholder or the array of values to be used by NOT IN() comparison. * @param mixed|null $type one of the IQueryBuilder::PARAM_* constants - * required when comparing text fields for oci compatibility + * required when comparing text fields for oci compatibility * * @return string * @since 8.2.0 - Parameter $type was added in 9.0.0 diff --git a/lib/public/DB/QueryBuilder/IFunctionBuilder.php b/lib/public/DB/QueryBuilder/IFunctionBuilder.php index d4edc8ea9f8..480ec1cb1ac 100644 --- a/lib/public/DB/QueryBuilder/IFunctionBuilder.php +++ b/lib/public/DB/QueryBuilder/IFunctionBuilder.php @@ -1,26 +1,8 @@ <?php + /** - * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl> - * - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\DB\QueryBuilder; diff --git a/lib/public/DB/QueryBuilder/ILiteral.php b/lib/public/DB/QueryBuilder/ILiteral.php index fbd175470ac..574eb0894eb 100644 --- a/lib/public/DB/QueryBuilder/ILiteral.php +++ b/lib/public/DB/QueryBuilder/ILiteral.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\DB\QueryBuilder; diff --git a/lib/public/DB/QueryBuilder/IParameter.php b/lib/public/DB/QueryBuilder/IParameter.php index 3344a9c56ce..86ea9437e9c 100644 --- a/lib/public/DB/QueryBuilder/IParameter.php +++ b/lib/public/DB/QueryBuilder/IParameter.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\DB\QueryBuilder; diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php index d677ee214f8..4794e7e8877 100644 --- a/lib/public/DB/QueryBuilder/IQueryBuilder.php +++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php @@ -1,35 +1,19 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Daniel Kesselberg <mail@danielkesselberg.de> - * @author J0WI <J0WI@users.noreply.github.com> - * @author Joas Schilling <coding@schilljs.com> - * @author Lukas Reschke <lukas@statuscode.ch> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\DB\QueryBuilder; +use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\ParameterType; +use Doctrine\DBAL\Types\Types; use OCP\DB\Exception; use OCP\DB\IResult; +use OCP\IDBConnection; /** * This class provides a wrapper around Doctrine's QueryBuilder @@ -41,27 +25,77 @@ interface IQueryBuilder { /** * @since 9.0.0 */ - public const PARAM_NULL = \PDO::PARAM_NULL; + public const PARAM_NULL = ParameterType::NULL; /** * @since 9.0.0 */ - public const PARAM_BOOL = \PDO::PARAM_BOOL; + public const PARAM_BOOL = Types::BOOLEAN; /** * @since 9.0.0 */ - public const PARAM_INT = \PDO::PARAM_INT; + public const PARAM_INT = ParameterType::INTEGER; /** * @since 9.0.0 */ - public const PARAM_STR = \PDO::PARAM_STR; + public const PARAM_STR = ParameterType::STRING; /** * @since 9.0.0 */ - public const PARAM_LOB = \PDO::PARAM_LOB; + public const PARAM_LOB = ParameterType::LARGE_OBJECT; + /** * @since 9.0.0 + * @deprecated 31.0.0 - use PARAM_DATETIME_MUTABLE instead + */ + public const PARAM_DATE = Types::DATETIME_MUTABLE; + + /** + * For passing a \DateTime instance when only interested in the time part (without timezone support) + * @since 31.0.0 + */ + public const PARAM_TIME_MUTABLE = Types::TIME_MUTABLE; + + /** + * For passing a \DateTime instance when only interested in the date part (without timezone support) + * @since 31.0.0 + */ + public const PARAM_DATE_MUTABLE = Types::DATE_MUTABLE; + + /** + * For passing a \DateTime instance (without timezone support) + * @since 31.0.0 + */ + public const PARAM_DATETIME_MUTABLE = Types::DATETIME_MUTABLE; + + /** + * For passing a \DateTime instance with timezone support + * @since 31.0.0 + */ + public const PARAM_DATETIME_TZ_MUTABLE = Types::DATETIMETZ_MUTABLE; + + /** + * For passing a \DateTimeImmutable instance when only interested in the time part (without timezone support) + * @since 31.0.0 + */ + public const PARAM_TIME_IMMUTABLE = Types::TIME_MUTABLE; + + /** + * For passing a \DateTime instance when only interested in the date part (without timezone support) + * @since 9.0.0 + */ + public const PARAM_DATE_IMMUTABLE = Types::DATE_IMMUTABLE; + + /** + * For passing a \DateTime instance (without timezone support) + * @since 31.0.0 + */ + public const PARAM_DATETIME_IMMUTABLE = Types::DATETIME_IMMUTABLE; + + /** + * For passing a \DateTime instance with timezone support + * @since 31.0.0 */ - public const PARAM_DATE = 'datetime'; + public const PARAM_DATETIME_TZ_IMMUTABLE = Types::DATETIMETZ_IMMUTABLE; /** * @since 24.0.0 @@ -71,11 +105,11 @@ interface IQueryBuilder { /** * @since 9.0.0 */ - public const PARAM_INT_ARRAY = Connection::PARAM_INT_ARRAY; + public const PARAM_INT_ARRAY = ArrayParameterType::INTEGER; /** * @since 9.0.0 */ - public const PARAM_STR_ARRAY = Connection::PARAM_STR_ARRAY; + public const PARAM_STR_ARRAY = ArrayParameterType::STRING; /** * @since 24.0.0 Indicates how many rows can be deleted at once with MySQL @@ -87,7 +121,7 @@ interface IQueryBuilder { * Enable/disable automatic prefixing of table names with the oc_ prefix * * @param bool $enabled If set to true table names will be prefixed with the - * owncloud database prefix automatically. + * owncloud database prefix automatically. * @since 8.2.0 */ public function automaticTablePrefix($enabled); @@ -151,6 +185,8 @@ interface IQueryBuilder { * * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN. * @since 8.2.0 + * @deprecated 30.0.0 This function is going to be removed with the next Doctrine/DBAL update + * and we can not fix this in our wrapper. */ public function getState(); @@ -164,34 +200,37 @@ interface IQueryBuilder { * that interface changed in a breaking way the adapter \OCP\DB\QueryBuilder\IStatement is returned * to bridge old code to the new API * + * @param ?IDBConnection $connection (optional) the connection to run the query against. since 30.0 * @return IResult|int * @throws Exception since 21.0.0 * @since 8.2.0 * @deprecated 22.0.0 Use executeQuery or executeStatement */ - public function execute(); + public function execute(?IDBConnection $connection = null); /** * Execute for select statements * + * @param ?IDBConnection $connection (optional) the connection to run the query against. since 30.0 * @return IResult * @since 22.0.0 * * @throws Exception * @throws \RuntimeException in case of usage with non select query */ - public function executeQuery(): IResult; + public function executeQuery(?IDBConnection $connection = null): IResult; /** * Execute insert, update and delete statements * + * @param ?IDBConnection $connection (optional) the connection to run the query against. since 30.0 * @return int the number of affected rows * @since 22.0.0 * * @throws Exception * @throws \RuntimeException in case of usage with select query */ - public function executeStatement(): int; + public function executeStatement(?IDBConnection $connection = null): int; /** * Gets the complete SQL string formed by the current specifications of this QueryBuilder. @@ -409,8 +448,8 @@ interface IQueryBuilder { * * <code> * $qb = $conn->getQueryBuilder() - * ->delete('users', 'u') - * ->where('u.id = :user_id'); + * ->delete('users') + * ->where('id = :user_id'); * ->setParameter(':user_id', 1); * </code> * @@ -419,6 +458,7 @@ interface IQueryBuilder { * * @return $this This QueryBuilder instance. * @since 8.2.0 + * @since 30.0.0 Alias is deprecated and will no longer be used with the next Doctrine/DBAL update * * @psalm-taint-sink sql $delete */ @@ -430,9 +470,10 @@ interface IQueryBuilder { * * <code> * $qb = $conn->getQueryBuilder() - * ->update('users', 'u') - * ->set('u.password', md5('password')) - * ->where('u.id = ?'); + * ->update('users') + * ->set('email', ':email') + * ->where('id = :user_id'); + * ->setParameter(':user_id', 1); * </code> * * @param string $update The table whose rows are subject to the update. @@ -440,6 +481,7 @@ interface IQueryBuilder { * * @return $this This QueryBuilder instance. * @since 8.2.0 + * @since 30.0.0 Alias is deprecated and will no longer be used with the next Doctrine/DBAL update * * @psalm-taint-sink sql $update */ @@ -550,12 +592,13 @@ interface IQueryBuilder { * </code> * * @param string $fromAlias The alias that points to a from clause. - * @param string $join The table name to join. + * @param string|IQueryFunction $join The table name to join. * @param string $alias The alias of the join table. * @param string|ICompositeExpression|null $condition The condition for the join. * * @return $this This QueryBuilder instance. * @since 8.2.0 + * @since 30.0.0 Allow passing IQueryFunction as parameter for `$join` to allow join with a sub-query. * * @psalm-taint-sink sql $fromAlias * @psalm-taint-sink sql $join @@ -620,12 +663,13 @@ interface IQueryBuilder { * ->from('users', 'u') * ->where('u.id = ?'); * - * // You can optionally programatically build and/or expressions + * // You can optionally programmatically build and/or expressions * $qb = $conn->getQueryBuilder(); * - * $or = $qb->expr()->orx(); - * $or->add($qb->expr()->eq('u.id', 1)); - * $or->add($qb->expr()->eq('u.id', 2)); + * $or = $qb->expr()->orx( + * $qb->expr()->eq('u.id', 1), + * $qb->expr()->eq('u.id', 2), + * ); * * $qb->update('users', 'u') * ->set('u.password', md5('password')) @@ -851,6 +895,8 @@ interface IQueryBuilder { * * @return mixed * @since 8.2.0 + * @deprecated 30.0.0 This function is going to be removed with the next Doctrine/DBAL update + * and we can not fix this in our wrapper. Please track the details you need, outside the object. */ public function getQueryPart($queryPartName); @@ -859,6 +905,8 @@ interface IQueryBuilder { * * @return array * @since 8.2.0 + * @deprecated 30.0.0 This function is going to be removed with the next Doctrine/DBAL update + * and we can not fix this in our wrapper. Please track the details you need, outside the object. */ public function getQueryParts(); @@ -869,6 +917,8 @@ interface IQueryBuilder { * * @return $this This QueryBuilder instance. * @since 8.2.0 + * @deprecated 30.0.0 This function is going to be removed with the next Doctrine/DBAL update + * and we can not fix this in our wrapper. Please create a new IQueryBuilder instead. */ public function resetQueryParts($queryPartNames = null); @@ -879,6 +929,8 @@ interface IQueryBuilder { * * @return $this This QueryBuilder instance. * @since 8.2.0 + * @deprecated 30.0.0 This function is going to be removed with the next Doctrine/DBAL update + * and we can not fix this in our wrapper. Please create a new IQueryBuilder instead. */ public function resetQueryPart($queryPartName); @@ -906,7 +958,7 @@ interface IQueryBuilder { * @link http://www.zetacomponents.org * * @param mixed $value - * @param mixed $type + * @param self::PARAM_* $type * @param string $placeHolder The name to bind with. The string must start with a colon ':'. * * @return IParameter @@ -934,7 +986,7 @@ interface IQueryBuilder { * </code> * * @param mixed $value - * @param integer $type + * @param self::PARAM_* $type * * @return IParameter * @since 8.2.0 @@ -988,7 +1040,7 @@ interface IQueryBuilder { * @return IQueryFunction * @since 8.2.0 * - * @psalm-taint-sink sql + * @psalm-taint-sink sql $call */ public function createFunction($call); @@ -1001,15 +1053,27 @@ interface IQueryBuilder { public function getLastInsertId(): int; /** - * Returns the table name quoted and with database prefix as needed by the implementation + * Returns the table name quoted and with database prefix as needed by the implementation. + * If a query function is passed the function is casted to string, + * this allows passing functions as sub-queries for join expression. * * @param string|IQueryFunction $table * @return string * @since 9.0.0 + * @since 24.0.0 accepts IQueryFunction as parameter */ public function getTableName($table); /** + * Returns the table name with database prefix as needed by the implementation + * + * @param string $table + * @return string + * @since 30.0.0 + */ + public function prefixTableName(string $table): string; + + /** * Returns the column name quoted and with table alias prefix as needed by the implementation * * @param string $column @@ -1018,4 +1082,30 @@ interface IQueryBuilder { * @since 9.0.0 */ public function getColumnName($column, $tableAlias = ''); + + /** + * Provide a hint for the shard key for queries where this can't be detected otherwise + * + * @param string $column + * @param mixed $value + * @return $this + * @since 30.0.0 + */ + public function hintShardKey(string $column, mixed $value, bool $overwrite = false): self; + + /** + * Set the query to run across all shards if sharding is enabled. + * + * @return $this + * @since 30.0.0 + */ + public function runAcrossAllShards(): self; + + /** + * Get a list of column names that are expected in the query output + * + * @return array + * @since 30.0.0 + */ + public function getOutputColumns(): array; } diff --git a/lib/public/DB/QueryBuilder/IQueryFunction.php b/lib/public/DB/QueryBuilder/IQueryFunction.php index d76f964fafd..e19fc2959db 100644 --- a/lib/public/DB/QueryBuilder/IQueryFunction.php +++ b/lib/public/DB/QueryBuilder/IQueryFunction.php @@ -1,25 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCP\DB\QueryBuilder; diff --git a/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php b/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php new file mode 100644 index 00000000000..fa00fb68719 --- /dev/null +++ b/lib/public/DB/QueryBuilder/Sharded/IShardMapper.php @@ -0,0 +1,25 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Robin Appelman <robin@icewind.nl> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCP\DB\QueryBuilder\Sharded; + +/** + * Implementation of logic of mapping shard keys to shards. + * @since 30.0.0 + */ +interface IShardMapper { + /** + * Get the shard number for a given shard key and total shard count + * + * @param int $key + * @param int $count + * @return int + * @since 30.0.0 + */ + public function getShardForKey(int $key, int $count): int; +} diff --git a/lib/public/DB/Types.php b/lib/public/DB/Types.php index 31a474b03a0..969ec5e6611 100644 --- a/lib/public/DB/Types.php +++ b/lib/public/DB/Types.php @@ -3,25 +3,8 @@ declare(strict_types=1); /** - * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OCP\DB; @@ -58,18 +41,77 @@ final class Types { public const BOOLEAN = 'boolean'; /** + * A datetime instance with only the date set. + * This will be (de)serialized into a \DateTime instance, + * it is recommended to instead use the `DATE_IMMUTABLE` instead. + * + * Warning: When deserialized the timezone will be set to UTC. * @var string * @since 21.0.0 */ public const DATE = 'date'; /** + * An immutable datetime instance with only the date set. + * This will be (de)serialized into a \DateTimeImmutable instance, + * It is recommended to use this over the `DATE` type because + * out `Entity` class works detecting changes through the setter, + * changes on mutable objects can not be detected. + * + * Warning: When deserialized the timezone will be set to UTC. + * @var string + * @since 31.0.0 + */ + public const DATE_IMMUTABLE = 'date_immutable'; + + /** + * A datetime instance with date and time support. + * This will be (de)serialized into a \DateTime instance, + * it is recommended to instead use the `DATETIME_IMMUTABLE` instead. + * + * Warning: When deserialized the timezone will be set to UTC. * @var string * @since 21.0.0 */ public const DATETIME = 'datetime'; /** + * An immutable datetime instance with date and time set. + * This will be (de)serialized into a \DateTimeImmutable instance, + * It is recommended to use this over the `DATETIME` type because + * out `Entity` class works detecting changes through the setter, + * changes on mutable objects can not be detected. + * + * Warning: When deserialized the timezone will be set to UTC. + * @var string + * @since 31.0.0 + */ + public const DATETIME_IMMUTABLE = 'datetime_immutable'; + + + /** + * A datetime instance with timezone support + * This will be (de)serialized into a \DateTime instance, + * it is recommended to instead use the `DATETIME_TZ_IMMUTABLE` instead. + * + * @var string + * @since 31.0.0 + */ + public const DATETIME_TZ = 'datetimetz'; + + /** + * An immutable timezone aware datetime instance with date and time set. + * This will be (de)serialized into a \DateTimeImmutable instance, + * It is recommended to use this over the `DATETIME_TZ` type because + * out `Entity` class works detecting changes through the setter, + * changes on mutable objects can not be detected. + * + * @var string + * @since 31.0.0 + */ + public const DATETIME_TZ_IMMUTABLE = 'datetimetz_immutable'; + + /** * @var string * @since 21.0.0 */ @@ -106,12 +148,30 @@ final class Types { public const TEXT = 'text'; /** + * A datetime instance with only the time set. + * This will be (de)serialized into a \DateTime instance, + * it is recommended to instead use the `TIME_IMMUTABLE` instead. + * + * Warning: When deserialized the timezone will be set to UTC. * @var string * @since 21.0.0 */ public const TIME = 'time'; /** + * A datetime instance with only the time set. + * This will be (de)serialized into a \DateTime instance. + * + * It is recommended to use this over the `DATETIME_TZ` type because + * out `Entity` class works detecting changes through the setter, + * changes on mutable objects can not be detected. + * + * @var string + * @since 31.0.0 + */ + public const TIME_IMMUTABLE = 'time_immutable'; + + /** * @var string * @since 24.0.0 */ |