diff options
Diffstat (limited to 'core/Migrations')
29 files changed, 758 insertions, 21 deletions
diff --git a/core/Migrations/Version13000Date20170705121758.php b/core/Migrations/Version13000Date20170705121758.php index 7233cc0302e..17262cf0743 100644 --- a/core/Migrations/Version13000Date20170705121758.php +++ b/core/Migrations/Version13000Date20170705121758.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/core/Migrations/Version13000Date20170718121200.php b/core/Migrations/Version13000Date20170718121200.php index c485e025c37..35c2d1730bc 100644 --- a/core/Migrations/Version13000Date20170718121200.php +++ b/core/Migrations/Version13000Date20170718121200.php @@ -1,11 +1,11 @@ <?php + /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OC\Core\Migrations; -use Doctrine\DBAL\Platforms\PostgreSQL94Platform; use OCP\DB\ISchemaWrapper; use OCP\DB\Types; use OCP\IDBConnection; @@ -124,10 +124,12 @@ class Version13000Date20170718121200 extends SimpleMigrationStep { $table->addIndex(['user_id', 'root_id', 'mount_point'], 'mounts_user_root_path_index', [], ['lengths' => [null, null, 128]]); } else { $table = $schema->getTable('mounts'); - $table->addColumn('mount_id', Types::BIGINT, [ - 'notnull' => false, - 'length' => 20, - ]); + if (!$table->hasColumn('mount_id')) { + $table->addColumn('mount_id', Types::BIGINT, [ + 'notnull' => false, + 'length' => 20, + ]); + } if (!$table->hasIndex('mounts_mount_id_index')) { $table->addIndex(['mount_id'], 'mounts_mount_id_index'); } @@ -238,7 +240,7 @@ class Version13000Date20170718121200 extends SimpleMigrationStep { $table->addIndex(['name'], 'fs_name_hash'); $table->addIndex(['mtime'], 'fs_mtime'); $table->addIndex(['size'], 'fs_size'); - if (!$schema->getDatabasePlatform() instanceof PostgreSQL94Platform) { + if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) { $table->addIndex(['storage', 'path'], 'fs_storage_path_prefix', [], ['lengths' => [null, 64]]); } } @@ -656,6 +658,7 @@ class Version13000Date20170718121200 extends SimpleMigrationStep { $table->addIndex(['uid'], 'uid_index'); $table->addIndex(['type'], 'type_index'); $table->addIndex(['category'], 'category_index'); + $table->addUniqueIndex(['uid', 'type', 'category'], 'unique_category_per_user'); } if (!$schema->hasTable('vcategory_to_object')) { @@ -729,6 +732,10 @@ class Version13000Date20170718121200 extends SimpleMigrationStep { $table->setPrimaryKey(['objecttype', 'objectid', 'systemtagid'], 'som_pk'); // $table->addUniqueIndex(['objecttype', 'objectid', 'systemtagid'], 'mapping'); $table->addIndex(['systemtagid', 'objecttype'], 'systag_by_tagid'); + // systag_by_objectid was added later and might be missing in older deployments + $table->addIndex(['objectid'], 'systag_by_objectid'); + // systag_objecttype was added later and might be missing in older deployments + $table->addIndex(['objecttype'], 'systag_objecttype'); } if (!$schema->hasTable('systemtag_group')) { @@ -1012,9 +1019,9 @@ class Version13000Date20170718121200 extends SimpleMigrationStep { $result = $query->execute(); while ($row = $result->fetch()) { preg_match('/(calendar)\/([A-z0-9-@_]+)\//', $row['propertypath'], $match); - $insert->setParameter('propertypath', (string) $row['propertypath']) - ->setParameter('propertyname', (string) $row['propertyname']) - ->setParameter('propertyvalue', (string) $row['propertyvalue']) + $insert->setParameter('propertypath', (string)$row['propertypath']) + ->setParameter('propertyname', (string)$row['propertyname']) + ->setParameter('propertyvalue', (string)$row['propertyvalue']) ->setParameter('userid', ($match[2] ?? '')); $insert->execute(); } diff --git a/core/Migrations/Version13000Date20170814074715.php b/core/Migrations/Version13000Date20170814074715.php index 73de1af0e0a..6e7ca19fc3c 100644 --- a/core/Migrations/Version13000Date20170814074715.php +++ b/core/Migrations/Version13000Date20170814074715.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/core/Migrations/Version13000Date20170919121250.php b/core/Migrations/Version13000Date20170919121250.php index ae6eff99bcd..b3e9541d605 100644 --- a/core/Migrations/Version13000Date20170919121250.php +++ b/core/Migrations/Version13000Date20170919121250.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/core/Migrations/Version13000Date20170926101637.php b/core/Migrations/Version13000Date20170926101637.php index 4a270c5e1cb..aca772de313 100644 --- a/core/Migrations/Version13000Date20170926101637.php +++ b/core/Migrations/Version13000Date20170926101637.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -13,7 +14,7 @@ use OCP\Migration\BigIntMigration; class Version13000Date20170926101637 extends BigIntMigration { /** * @return array Returns an array with the following structure - * ['table1' => ['column1', 'column2'], ...] + * ['table1' => ['column1', 'column2'], ...] * @since 13.0.0 */ protected function getColumnsByTable() { diff --git a/core/Migrations/Version14000Date20180129121024.php b/core/Migrations/Version14000Date20180129121024.php index 6da5f2602e8..c16d95ed71b 100644 --- a/core/Migrations/Version14000Date20180129121024.php +++ b/core/Migrations/Version14000Date20180129121024.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/core/Migrations/Version14000Date20180516101403.php b/core/Migrations/Version14000Date20180516101403.php index c024b1b93ab..a71673a9674 100644 --- a/core/Migrations/Version14000Date20180516101403.php +++ b/core/Migrations/Version14000Date20180516101403.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/core/Migrations/Version14000Date20180626223656.php b/core/Migrations/Version14000Date20180626223656.php index 8c3e81303bc..7d4dea585f6 100644 --- a/core/Migrations/Version14000Date20180626223656.php +++ b/core/Migrations/Version14000Date20180626223656.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -6,10 +7,11 @@ namespace OC\Core\Migrations; use OCP\DB\ISchemaWrapper; +use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; class Version14000Date20180626223656 extends SimpleMigrationStep { - public function changeSchema(\OCP\Migration\IOutput $output, \Closure $schemaClosure, array $options) { + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); if (!$schema->hasTable('whats_new')) { diff --git a/core/Migrations/Version14000Date20180712153140.php b/core/Migrations/Version14000Date20180712153140.php index d719b0f803c..b1a295ea2f6 100644 --- a/core/Migrations/Version14000Date20180712153140.php +++ b/core/Migrations/Version14000Date20180712153140.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -6,6 +7,7 @@ namespace OC\Core\Migrations; use OCP\DB\ISchemaWrapper; +use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; /** @@ -14,7 +16,7 @@ use OCP\Migration\SimpleMigrationStep; * Class Version14000Date20180712153140 */ class Version14000Date20180712153140 extends SimpleMigrationStep { - public function changeSchema(\OCP\Migration\IOutput $output, \Closure $schemaClosure, array $options) { + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); diff --git a/core/Migrations/Version19000Date20200211083441.php b/core/Migrations/Version19000Date20200211083441.php index 4b361149b30..2f8b46ad772 100644 --- a/core/Migrations/Version19000Date20200211083441.php +++ b/core/Migrations/Version19000Date20200211083441.php @@ -35,7 +35,7 @@ class Version19000Date20200211083441 extends SimpleMigrationStep { ]); $table->addColumn('public_key_credential_id', 'string', [ 'notnull' => true, - 'length' => 255 + 'length' => 512 ]); $table->addColumn('data', 'text', [ 'notnull' => true, diff --git a/core/Migrations/Version20000Date20201109081918.php b/core/Migrations/Version20000Date20201109081918.php index 5f0051c4690..a24b1ab82b4 100644 --- a/core/Migrations/Version20000Date20201109081918.php +++ b/core/Migrations/Version20000Date20201109081918.php @@ -79,9 +79,9 @@ class Version20000Date20201109081918 extends SimpleMigrationStep { $result = $query->execute(); while ($row = $result->fetch()) { - $insert->setParameter('user', (string) $row['user']) - ->setParameter('identifier', (string) $row['identifier']) - ->setParameter('credentials', (string) $row['credentials']); + $insert->setParameter('user', (string)$row['user']) + ->setParameter('identifier', (string)$row['identifier']) + ->setParameter('credentials', (string)$row['credentials']); $insert->execute(); } $result->closeCursor(); diff --git a/core/Migrations/Version23000Date20210721100600.php b/core/Migrations/Version23000Date20210721100600.php index 72437337326..a611c0c4b36 100644 --- a/core/Migrations/Version23000Date20210721100600.php +++ b/core/Migrations/Version23000Date20210721100600.php @@ -36,7 +36,7 @@ class Version23000Date20210721100600 extends SimpleMigrationStep { 'notnull' => true, 'length' => 200, ]); - + $table->setPrimaryKey(['id']); $table->addIndex(['group_id'], 'admindel_groupid_idx'); return $schema; diff --git a/core/Migrations/Version23000Date20211213203940.php b/core/Migrations/Version23000Date20211213203940.php index 69f6257e812..f31f13a14d7 100644 --- a/core/Migrations/Version23000Date20211213203940.php +++ b/core/Migrations/Version23000Date20211213203940.php @@ -14,7 +14,7 @@ use OCP\Migration\BigIntMigration; class Version23000Date20211213203940 extends BigIntMigration { /** * @return array Returns an array with the following structure - * ['table1' => ['column1', 'column2'], ...] + * ['table1' => ['column1', 'column2'], ...] */ protected function getColumnsByTable() { return [ diff --git a/core/Migrations/Version25000Date20220515204012.php b/core/Migrations/Version25000Date20220515204012.php index 2ec96bc5175..7f7c6b6cee2 100644 --- a/core/Migrations/Version25000Date20220515204012.php +++ b/core/Migrations/Version25000Date20220515204012.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2019 ownCloud GmbH * SPDX-License-Identifier: AGPL-3.0-only diff --git a/core/Migrations/Version27000Date20220613163520.php b/core/Migrations/Version27000Date20220613163520.php index f3f6e374572..4a5601b6cd5 100644 --- a/core/Migrations/Version27000Date20220613163520.php +++ b/core/Migrations/Version27000Date20220613163520.php @@ -16,7 +16,7 @@ use OCP\Migration\SimpleMigrationStep; class Version27000Date20220613163520 extends SimpleMigrationStep { public function name(): string { - return "Add mountpoint path to mounts table unique index"; + return 'Add mountpoint path to mounts table unique index'; } public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { diff --git a/core/Migrations/Version28000Date20240828142927.php b/core/Migrations/Version28000Date20240828142927.php new file mode 100644 index 00000000000..e36c27add1c --- /dev/null +++ b/core/Migrations/Version28000Date20240828142927.php @@ -0,0 +1,83 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\Migration\Attributes\ColumnType; +use OCP\Migration\Attributes\ModifyColumn; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * Migrate the argument_hash column of oc_jobs to use sha256 instead of md5. + */ +#[ModifyColumn(table: 'jobs', name: 'argument_hash', type: ColumnType::STRING, description: 'Increase the column size from 32 to 64')] +#[ModifyColumn(table: 'jobs', name: 'argument_hash', type: ColumnType::STRING, description: 'Rehash the argument_hash column using sha256')] +class Version28000Date20240828142927 extends SimpleMigrationStep { + public function __construct( + protected IDBConnection $connection, + ) { + } + + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + // Increase the column size from 32 to 64 + $table = $schema->getTable('jobs'); + $table->modifyColumn('argument_hash', [ + 'notnull' => false, + 'length' => 64, + ]); + + return $schema; + } + + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + $chunkSize = 1000; + $offset = 0; + $nullHash = hash('sha256', 'null'); + + $selectQuery = $this->connection->getQueryBuilder() + ->select('*') + ->from('jobs') + ->setMaxResults($chunkSize); + + $insertQuery = $this->connection->getQueryBuilder(); + $insertQuery->update('jobs') + ->set('argument_hash', $insertQuery->createParameter('argument_hash')) + ->where($insertQuery->expr()->eq('id', $insertQuery->createParameter('id'))); + + do { + $result = $selectQuery + ->setFirstResult($offset) + ->executeQuery(); + + $jobs = $result->fetchAll(); + $count = count($jobs); + + foreach ($jobs as $jobRow) { + if ($jobRow['argument'] === 'null') { + $hash = $nullHash; + } else { + $hash = hash('sha256', $jobRow['argument']); + } + $insertQuery->setParameter('id', (string)$jobRow['id'], IQueryBuilder::PARAM_INT); + $insertQuery->setParameter('argument_hash', $hash); + $insertQuery->executeStatement(); + } + + $offset += $chunkSize; + } while ($count === $chunkSize); + } +} diff --git a/core/Migrations/Version29000Date20240131122720.php b/core/Migrations/Version29000Date20240131122720.php index 14f02331587..abd5e73165a 100644 --- a/core/Migrations/Version29000Date20240131122720.php +++ b/core/Migrations/Version29000Date20240131122720.php @@ -29,8 +29,8 @@ class Version29000Date20240131122720 extends SimpleMigrationStep { $tableProperties = $schema->getTable('properties'); - if ($tableProperties->hasIndex('property_index') && - $tableProperties->hasIndex('properties_path_index')) { + if ($tableProperties->hasIndex('property_index') + && $tableProperties->hasIndex('properties_path_index')) { $tableProperties->dropIndex('property_index'); } diff --git a/core/Migrations/Version30000Date20240429122720.php b/core/Migrations/Version30000Date20240429122720.php index 281ea1cfbd5..eeefc8dd10c 100644 --- a/core/Migrations/Version30000Date20240429122720.php +++ b/core/Migrations/Version30000Date20240429122720.php @@ -11,12 +11,20 @@ namespace OC\Core\Migrations; use Closure; use OCP\DB\ISchemaWrapper; use OCP\DB\Types; +use OCP\Migration\Attributes\AddIndex; +use OCP\Migration\Attributes\CreateTable; +use OCP\Migration\Attributes\IndexType; use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; /** * */ +#[CreateTable(table: 'taskprocessing_tasks')] +#[AddIndex(table: 'taskprocessing_tasks', type: IndexType::PRIMARY)] +#[AddIndex(table: 'taskprocessing_tasks', type: IndexType::INDEX)] +#[AddIndex(table: 'taskprocessing_tasks', type: IndexType::INDEX)] +#[AddIndex(table: 'taskprocessing_tasks', type: IndexType::INDEX)] class Version30000Date20240429122720 extends SimpleMigrationStep { /** diff --git a/core/Migrations/Version30000Date20240708160048.php b/core/Migrations/Version30000Date20240708160048.php new file mode 100644 index 00000000000..83edd84e56a --- /dev/null +++ b/core/Migrations/Version30000Date20240708160048.php @@ -0,0 +1,67 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\Types; +use OCP\Migration\Attributes\AddColumn; +use OCP\Migration\Attributes\ColumnType; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * + */ +#[AddColumn(table: 'taskprocessing_tasks', name: 'scheduled_at', type: ColumnType::INTEGER)] +#[AddColumn(table: 'taskprocessing_tasks', name: 'started_at', type: ColumnType::INTEGER)] +#[AddColumn(table: 'taskprocessing_tasks', name: 'ended_at', type: ColumnType::INTEGER)] +class Version30000Date20240708160048 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('taskprocessing_tasks')) { + $table = $schema->getTable('taskprocessing_tasks'); + + if (!$table->hasColumn('scheduled_at')) { + $table->addColumn('scheduled_at', Types::INTEGER, [ + 'notnull' => false, + 'default' => null, + 'unsigned' => true, + ]); + } + if (!$table->hasColumn('started_at')) { + $table->addColumn('started_at', Types::INTEGER, [ + 'notnull' => false, + 'default' => null, + 'unsigned' => true, + ]); + } + if (!$table->hasColumn('ended_at')) { + $table->addColumn('ended_at', Types::INTEGER, [ + 'notnull' => false, + 'default' => null, + 'unsigned' => true, + ]); + } + + return $schema; + } + + return null; + } +} diff --git a/core/Migrations/Version30000Date20240717111406.php b/core/Migrations/Version30000Date20240717111406.php new file mode 100644 index 00000000000..558ac432387 --- /dev/null +++ b/core/Migrations/Version30000Date20240717111406.php @@ -0,0 +1,55 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\Types; +use OCP\Migration\Attributes\AddColumn; +use OCP\Migration\Attributes\ColumnType; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * + */ +#[AddColumn(table: 'taskprocessing_tasks', name: 'webhook_uri', type: ColumnType::STRING)] +#[AddColumn(table: 'taskprocessing_tasks', name: 'webhook_method', type: ColumnType::STRING)] +class Version30000Date20240717111406 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('taskprocessing_tasks')) { + $table = $schema->getTable('taskprocessing_tasks'); + + $table->addColumn('webhook_uri', Types::STRING, [ + 'notnull' => false, + 'default' => null, + 'length' => 4000, + ]); + $table->addColumn('webhook_method', Types::STRING, [ + 'notnull' => false, + 'default' => null, + 'length' => 64, + ]); + + return $schema; + } + + return null; + } +} diff --git a/core/Migrations/Version30000Date20240814180800.php b/core/Migrations/Version30000Date20240814180800.php new file mode 100644 index 00000000000..199af8cc0aa --- /dev/null +++ b/core/Migrations/Version30000Date20240814180800.php @@ -0,0 +1,37 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +class Version30000Date20240814180800 extends SimpleMigrationStep { + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->getTable('webauthn'); + $column = $table->getColumn('public_key_credential_id'); + + /** + * There is no maximum length defined in the standard, + * most common the length is between 128 and 200 characters, + * but as we store it not in plain data but base64 encoded the length can grow about 1/3. + * We had a regression with 'Nitrokey 3' which created IDs with 196 byte length -> 262 bytes encoded base64. + * So to be save we increase the size to 512 bytes. + */ + if ($column->getLength() < 512) { + $column->setLength(512); + } + + return $schema; + } +} diff --git a/core/Migrations/Version30000Date20240815080800.php b/core/Migrations/Version30000Date20240815080800.php new file mode 100644 index 00000000000..5212467ece0 --- /dev/null +++ b/core/Migrations/Version30000Date20240815080800.php @@ -0,0 +1,30 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 S1m <git@sgougeon.fr> + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\Types; +use OCP\Migration\Attributes\AddColumn; +use OCP\Migration\Attributes\ColumnType; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +#[AddColumn(table: 'webauthn', name: 'user_verification', type: ColumnType::BOOLEAN)] +class Version30000Date20240815080800 extends SimpleMigrationStep { + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->getTable('webauthn'); + $table->addColumn('user_verification', Types::BOOLEAN, ['notnull' => false, 'default' => false]); + return $schema; + } +} diff --git a/core/Migrations/Version30000Date20240906095113.php b/core/Migrations/Version30000Date20240906095113.php new file mode 100644 index 00000000000..7c3efe41bc3 --- /dev/null +++ b/core/Migrations/Version30000Date20240906095113.php @@ -0,0 +1,42 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\Attributes\ModifyColumn; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +#[ModifyColumn(table: 'taskprocessing_tasks', name: 'error_message', description: 'Increase column length to 4000 bytes to support longer error messages')] +class Version30000Date20240906095113 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('taskprocessing_tasks')) { + $table = $schema->getTable('taskprocessing_tasks'); + $column = $table->getColumn('error_message'); + + if ($column->getLength() < 4000) { + $column->setLength(4000); + } + } + + return $schema; + } +} diff --git a/core/Migrations/Version31000Date20240101084401.php b/core/Migrations/Version31000Date20240101084401.php new file mode 100644 index 00000000000..60792dcac21 --- /dev/null +++ b/core/Migrations/Version31000Date20240101084401.php @@ -0,0 +1,135 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\Types; +use OCP\Migration\Attributes\AddIndex; +use OCP\Migration\Attributes\CreateTable; +use OCP\Migration\Attributes\IndexType; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * @since 31.0.0 + */ +#[CreateTable( + table: 'sec_signatory', + columns: ['id', 'key_id_sum', 'key_id', 'host', 'provider_id', 'account', 'public_key', 'metadata', 'type', 'status', 'creation', 'last_updated'], + description: 'new table to store remove public/private key pairs' +)] +#[AddIndex( + table: 'sec_signatory', + type: IndexType::PRIMARY +)] +#[AddIndex( + table: 'sec_signatory', + type: IndexType::UNIQUE, + description: 'confirm uniqueness per host, provider and account' +)] +#[AddIndex( + table: 'sec_signatory', + type: IndexType::INDEX, + description: 'to search on key and provider' +)] +class Version31000Date20240101084401 extends SimpleMigrationStep { + public function description(): string { + return "creating new table 'sec_signatory' to store remote signatories"; + } + + public function name(): string { + return 'create sec_signatory'; + } + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if (!$schema->hasTable('sec_signatory')) { + $table = $schema->createTable('sec_signatory'); + $table->addColumn('id', Types::BIGINT, [ + 'notnull' => true, + 'length' => 64, + 'autoincrement' => true, + 'unsigned' => true, + ]); + // key_id_sum will store a hash version of the key_id, more appropriate for search/index + $table->addColumn('key_id_sum', Types::STRING, [ + 'notnull' => true, + 'length' => 127, + ]); + $table->addColumn('key_id', Types::STRING, [ + 'notnull' => true, + 'length' => 512 + ]); + // host/provider_id/account will help generate a unique entry, not based on key_id + // this way, a spoofed instance cannot publish a new key_id for same host+provider_id + // account will be used only to stored multiple keys for the same provider_id/host + $table->addColumn('host', Types::STRING, [ + 'notnull' => true, + 'length' => 512 + ]); + $table->addColumn('provider_id', Types::STRING, [ + 'notnull' => true, + 'length' => 31, + ]); + $table->addColumn('account', Types::STRING, [ + 'notnull' => false, + 'length' => 127, + 'default' => '' + ]); + $table->addColumn('public_key', Types::TEXT, [ + 'notnull' => true, + 'default' => '' + ]); + $table->addColumn('metadata', Types::TEXT, [ + 'notnull' => true, + 'default' => '[]' + ]); + // type+status are informative about the trustability of remote instance and status of the signatory + $table->addColumn('type', Types::SMALLINT, [ + 'notnull' => true, + 'length' => 2, + 'default' => 9 + ]); + $table->addColumn('status', Types::SMALLINT, [ + 'notnull' => true, + 'length' => 2, + 'default' => 0, + ]); + $table->addColumn('creation', Types::INTEGER, [ + 'notnull' => false, + 'length' => 4, + 'default' => 0, + 'unsigned' => true, + ]); + $table->addColumn('last_updated', Types::INTEGER, [ + 'notnull' => false, + 'length' => 4, + 'default' => 0, + 'unsigned' => true, + ]); + + $table->setPrimaryKey(['id'], 'sec_sig_id'); + $table->addUniqueIndex(['provider_id', 'host', 'account'], 'sec_sig_unic'); + $table->addIndex(['key_id_sum', 'provider_id'], 'sec_sig_key'); + + return $schema; + } + + return null; + } +} diff --git a/core/Migrations/Version31000Date20240814184402.php b/core/Migrations/Version31000Date20240814184402.php new file mode 100644 index 00000000000..14b32a704be --- /dev/null +++ b/core/Migrations/Version31000Date20240814184402.php @@ -0,0 +1,54 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\Types; +use OCP\Migration\Attributes\AddColumn; +use OCP\Migration\Attributes\AddIndex; +use OCP\Migration\Attributes\ColumnType; +use OCP\Migration\Attributes\DropIndex; +use OCP\Migration\Attributes\IndexType; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * Create new column and index for lazy loading in preferences for the new IUserPreferences API. + */ +#[AddColumn(table: 'preferences', name: 'lazy', type: ColumnType::SMALLINT, description: 'lazy loading to user preferences')] +#[AddColumn(table: 'preferences', name: 'type', type: ColumnType::SMALLINT, description: 'typed values to user preferences')] +#[AddColumn(table: 'preferences', name: 'flag', type: ColumnType::INTEGER, description: 'bitflag about the value')] +#[AddColumn(table: 'preferences', name: 'indexed', type: ColumnType::INTEGER, description: 'non-array value can be set as indexed')] +#[DropIndex(table: 'preferences', type: IndexType::INDEX, description: 'remove previous app/key index', notes: ['will be re-created to include \'indexed\' field'])] +#[AddIndex(table: 'preferences', type: IndexType::INDEX, description: 'new index including user+lazy')] +#[AddIndex(table: 'preferences', type: IndexType::INDEX, description: 'new index including app/key and indexed')] +class Version31000Date20240814184402 extends SimpleMigrationStep { + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->getTable('preferences'); + $table->addColumn('lazy', Types::SMALLINT, ['notnull' => true, 'default' => 0, 'length' => 1, 'unsigned' => true]); + $table->addColumn('type', Types::SMALLINT, ['notnull' => true, 'default' => 0, 'unsigned' => true]); + $table->addColumn('flags', Types::INTEGER, ['notnull' => true, 'default' => 0, 'unsigned' => true]); + $table->addColumn('indexed', Types::STRING, ['notnull' => false, 'default' => '', 'length' => 64]); + + // removing this index from Version13000Date20170718121200 + // $table->addIndex(['appid', 'configkey'], 'preferences_app_key'); + if ($table->hasIndex('preferences_app_key')) { + $table->dropIndex('preferences_app_key'); + } + + $table->addIndex(['userid', 'lazy'], 'prefs_uid_lazy_i'); + $table->addIndex(['appid', 'configkey', 'indexed', 'flags'], 'prefs_app_key_ind_fl_i'); + + return $schema; + } +} diff --git a/core/Migrations/Version31000Date20250213102442.php b/core/Migrations/Version31000Date20250213102442.php new file mode 100644 index 00000000000..d267e867129 --- /dev/null +++ b/core/Migrations/Version31000Date20250213102442.php @@ -0,0 +1,37 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\Attributes\DropIndex; +use OCP\Migration\Attributes\IndexType; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * Drop index fs_id_storage_size + * + * Added in https://github.com/nextcloud/server/pull/29118 + * Matching request changed in https://github.com/nextcloud/server/pull/50781 + */ +#[DropIndex(table: 'filecache', type: IndexType::INDEX, description: 'remove index fs_id_storage_size (concurrent with PRIMARY KEY)')] +class Version31000Date20250213102442 extends SimpleMigrationStep { + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->getTable('filecache'); + + // Index added in Version13000Date20170718121200 + if ($table->hasIndex('fs_id_storage_size')) { + $table->dropIndex('fs_id_storage_size'); + } + + return $schema; + } +} diff --git a/core/Migrations/Version32000Date20250620081925.php b/core/Migrations/Version32000Date20250620081925.php new file mode 100644 index 00000000000..13e1ac0f87d --- /dev/null +++ b/core/Migrations/Version32000Date20250620081925.php @@ -0,0 +1,16 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\Core\Migrations; + +/** + * Run the old migration Version24000Date20211210141942 again. + */ +class Version32000Date20250620081925 extends Version24000Date20211210141942 { +} diff --git a/core/Migrations/Version32000Date20250731062008.php b/core/Migrations/Version32000Date20250731062008.php new file mode 100644 index 00000000000..bf15e4a0b22 --- /dev/null +++ b/core/Migrations/Version32000Date20250731062008.php @@ -0,0 +1,106 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; +use Override; + +/** + * Make sure vcategory entries are unique per user and type + * This migration will clean up existing duplicates + * and add a unique constraint to prevent future duplicates. + */ +class Version32000Date20250731062008 extends SimpleMigrationStep { + public function __construct( + private IDBConnection $connection, + ) { + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + #[Override] + public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + // Clean up duplicate categories before adding unique constraint + $this->cleanupDuplicateCategories($output); + } + + /** + * Clean up duplicate categories + */ + private function cleanupDuplicateCategories(IOutput $output) { + $output->info('Starting cleanup of duplicate vcategory records...'); + + // Find all categories, ordered to identify duplicates + $qb = $this->connection->getQueryBuilder(); + $qb->select('id', 'uid', 'type', 'category') + ->from('vcategory') + ->orderBy('uid') + ->addOrderBy('type') + ->addOrderBy('category') + ->addOrderBy('id'); + + $result = $qb->executeQuery(); + + $seen = []; + $duplicateCount = 0; + + while ($category = $result->fetch()) { + $key = $category['uid'] . '|' . $category['type'] . '|' . $category['category']; + $categoryId = (int)$category['id']; + + if (!isset($seen[$key])) { + // First occurrence - keep this one + $seen[$key] = $categoryId; + continue; + } + + // Duplicate found + $keepId = $seen[$key]; + $duplicateCount++; + + $output->info("Found duplicate: keeping ID $keepId, removing ID $categoryId"); + + // Update object references + $updateQb = $this->connection->getQueryBuilder(); + $updateQb->update('vcategory_to_object') + ->set('categoryid', $updateQb->createNamedParameter($keepId)) + ->where($updateQb->expr()->eq('categoryid', $updateQb->createNamedParameter($categoryId))); + + $affectedRows = $updateQb->executeStatement(); + if ($affectedRows > 0) { + $output->info(" - Updated $affectedRows object references from category $categoryId to $keepId"); + } + + // Remove duplicate category record + $deleteQb = $this->connection->getQueryBuilder(); + $deleteQb->delete('vcategory') + ->where($deleteQb->expr()->eq('id', $deleteQb->createNamedParameter($categoryId))); + + $deleteQb->executeStatement(); + $output->info(" - Deleted duplicate category record ID $categoryId"); + + } + + $result->closeCursor(); + + if ($duplicateCount === 0) { + $output->info('No duplicate categories found'); + } else { + $output->info("Duplicate cleanup completed - processed $duplicateCount duplicates"); + } + } +} diff --git a/core/Migrations/Version32000Date20250806110519.php b/core/Migrations/Version32000Date20250806110519.php new file mode 100644 index 00000000000..c498a1cc820 --- /dev/null +++ b/core/Migrations/Version32000Date20250806110519.php @@ -0,0 +1,49 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OC\Core\Migrations; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\Types; +use OCP\Migration\Attributes\AddColumn; +use OCP\Migration\Attributes\ColumnType; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +/** + * + */ +#[AddColumn(table: 'taskprocessing_tasks', name: 'allow_cleanup', type: ColumnType::SMALLINT)] +class Version32000Date20250806110519 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('taskprocessing_tasks')) { + $table = $schema->getTable('taskprocessing_tasks'); + if (!$table->hasColumn('allow_cleanup')) { + $table->addColumn('allow_cleanup', Types::SMALLINT, [ + 'notnull' => true, + 'default' => 1, + 'unsigned' => true, + ]); + return $schema; + } + } + + return null; + } +} |