aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMaxence Lange <maxence@artificial-owl.com>2024-07-17 10:49:11 -0100
committerMaxence Lange <maxence@artificial-owl.com>2024-07-29 12:44:52 -0100
commit88cfab4f329c7ee1f360be1ad7d90cf767da3720 (patch)
treead460429a5d58ef5ac67450cabc24e54bb9b1d9e /lib
parent10821643645f1e9ab5d6d768bd52b37468722d3f (diff)
downloadnextcloud-server-88cfab4f329c7ee1f360be1ad7d90cf767da3720.tar.gz
nextcloud-server-88cfab4f329c7ee1f360be1ad7d90cf767da3720.zip
feat(upgrade): migration attributes
Signed-off-by: Maxence Lange <maxence@artificial-owl.com> d Signed-off-by: Maxence Lange <maxence@artificial-owl.com> f Signed-off-by: Maxence Lange <maxence@artificial-owl.com> d Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php20
-rw-r--r--lib/composer/composer/autoload_static.php20
-rw-r--r--lib/public/Migration/Attributes/AddColumn.php22
-rw-r--r--lib/public/Migration/Attributes/AddIndex.php20
-rw-r--r--lib/public/Migration/Attributes/ColumnMigrationAttribute.php58
-rw-r--r--lib/public/Migration/Attributes/ColumnType.php46
-rw-r--r--lib/public/Migration/Attributes/CreateTable.php20
-rw-r--r--lib/public/Migration/Attributes/DeleteTable.php18
-rw-r--r--lib/public/Migration/Attributes/DropColumn.php21
-rw-r--r--lib/public/Migration/Attributes/DropIndex.php20
-rw-r--r--lib/public/Migration/Attributes/GenericMigrationAttribute.php31
-rw-r--r--lib/public/Migration/Attributes/IndexMigrationAttribute.php46
-rw-r--r--lib/public/Migration/Attributes/IndexType.php21
-rw-r--r--lib/public/Migration/Attributes/MigrationAttribute.php66
-rw-r--r--lib/public/Migration/Attributes/ModifyColumn.php22
-rw-r--r--lib/public/Migration/Attributes/TableMigrationAttribute.php46
-rw-r--r--lib/public/Migration/Exceptions/AttributeException.php17
17 files changed, 514 insertions, 0 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index dc0c8f0e6c6..a167eba878f 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -572,6 +572,7 @@ return array(
'OCP\\Mail\\IEMailTemplate' => $baseDir . '/lib/public/Mail/IEMailTemplate.php',
'OCP\\Mail\\IMailer' => $baseDir . '/lib/public/Mail/IMailer.php',
'OCP\\Mail\\IMessage' => $baseDir . '/lib/public/Mail/IMessage.php',
+<<<<<<< HEAD
'OCP\\Mail\\Provider\\Address' => $baseDir . '/lib/public/Mail/Provider/Address.php',
'OCP\\Mail\\Provider\\Attachment' => $baseDir . '/lib/public/Mail/Provider/Attachment.php',
'OCP\\Mail\\Provider\\Exception\\Exception' => $baseDir . '/lib/public/Mail/Provider/Exception/Exception.php',
@@ -584,7 +585,24 @@ return array(
'OCP\\Mail\\Provider\\IProvider' => $baseDir . '/lib/public/Mail/Provider/IProvider.php',
'OCP\\Mail\\Provider\\IService' => $baseDir . '/lib/public/Mail/Provider/IService.php',
'OCP\\Mail\\Provider\\Message' => $baseDir . '/lib/public/Mail/Provider/Message.php',
+=======
+ 'OCP\\Migration\\Attributes\\AddColumn' => $baseDir . '/lib/public/Migration/Attributes/AddColumn.php',
+ 'OCP\\Migration\\Attributes\\AddIndex' => $baseDir . '/lib/public/Migration/Attributes/AddIndex.php',
+ 'OCP\\Migration\\Attributes\\ColumnMigrationAttribute' => $baseDir . '/lib/public/Migration/Attributes/ColumnMigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\ColumnType' => $baseDir . '/lib/public/Migration/Attributes/ColumnType.php',
+ 'OCP\\Migration\\Attributes\\CreateTable' => $baseDir . '/lib/public/Migration/Attributes/CreateTable.php',
+ 'OCP\\Migration\\Attributes\\DeleteTable' => $baseDir . '/lib/public/Migration/Attributes/DeleteTable.php',
+ 'OCP\\Migration\\Attributes\\DropColumn' => $baseDir . '/lib/public/Migration/Attributes/DropColumn.php',
+ 'OCP\\Migration\\Attributes\\DropIndex' => $baseDir . '/lib/public/Migration/Attributes/DropIndex.php',
+ 'OCP\\Migration\\Attributes\\GenericMigrationAttribute' => $baseDir . '/lib/public/Migration/Attributes/GenericMigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\IndexMigrationAttribute' => $baseDir . '/lib/public/Migration/Attributes/IndexMigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\IndexType' => $baseDir . '/lib/public/Migration/Attributes/IndexType.php',
+ 'OCP\\Migration\\Attributes\\MigrationAttribute' => $baseDir . '/lib/public/Migration/Attributes/MigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\ModifyColumn' => $baseDir . '/lib/public/Migration/Attributes/ModifyColumn.php',
+ 'OCP\\Migration\\Attributes\\TableMigrationAttribute' => $baseDir . '/lib/public/Migration/Attributes/TableMigrationAttribute.php',
+>>>>>>> 2f771df35a9 (feat(upgrade): migration attributes)
'OCP\\Migration\\BigIntMigration' => $baseDir . '/lib/public/Migration/BigIntMigration.php',
+ 'OCP\\Migration\\Exceptions\\AttributeException' => $baseDir . '/lib/public/Migration/Exceptions/AttributeException.php',
'OCP\\Migration\\IMigrationStep' => $baseDir . '/lib/public/Migration/IMigrationStep.php',
'OCP\\Migration\\IOutput' => $baseDir . '/lib/public/Migration/IOutput.php',
'OCP\\Migration\\IRepairStep' => $baseDir . '/lib/public/Migration/IRepairStep.php',
@@ -1143,7 +1161,9 @@ return array(
'OC\\Core\\Command\\Db\\ExportSchema' => $baseDir . '/core/Command/Db/ExportSchema.php',
'OC\\Core\\Command\\Db\\Migrations\\ExecuteCommand' => $baseDir . '/core/Command/Db/Migrations/ExecuteCommand.php',
'OC\\Core\\Command\\Db\\Migrations\\GenerateCommand' => $baseDir . '/core/Command/Db/Migrations/GenerateCommand.php',
+ 'OC\\Core\\Command\\Db\\Migrations\\GenerateMetadataCommand' => $baseDir . '/core/Command/Db/Migrations/GenerateMetadataCommand.php',
'OC\\Core\\Command\\Db\\Migrations\\MigrateCommand' => $baseDir . '/core/Command/Db/Migrations/MigrateCommand.php',
+ 'OC\\Core\\Command\\Db\\Migrations\\PreviewCommand' => $baseDir . '/core/Command/Db/Migrations/PreviewCommand.php',
'OC\\Core\\Command\\Db\\Migrations\\StatusCommand' => $baseDir . '/core/Command/Db/Migrations/StatusCommand.php',
'OC\\Core\\Command\\Db\\SchemaEncoder' => $baseDir . '/core/Command/Db/SchemaEncoder.php',
'OC\\Core\\Command\\Encryption\\ChangeKeyStorageRoot' => $baseDir . '/core/Command/Encryption/ChangeKeyStorageRoot.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 635854db4c6..b328d6ff5c9 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -605,6 +605,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Mail\\IEMailTemplate' => __DIR__ . '/../../..' . '/lib/public/Mail/IEMailTemplate.php',
'OCP\\Mail\\IMailer' => __DIR__ . '/../../..' . '/lib/public/Mail/IMailer.php',
'OCP\\Mail\\IMessage' => __DIR__ . '/../../..' . '/lib/public/Mail/IMessage.php',
+<<<<<<< HEAD
'OCP\\Mail\\Provider\\Address' => __DIR__ . '/../../..' . '/lib/public/Mail/Provider/Address.php',
'OCP\\Mail\\Provider\\Attachment' => __DIR__ . '/../../..' . '/lib/public/Mail/Provider/Attachment.php',
'OCP\\Mail\\Provider\\Exception\\Exception' => __DIR__ . '/../../..' . '/lib/public/Mail/Provider/Exception/Exception.php',
@@ -617,7 +618,24 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Mail\\Provider\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Mail/Provider/IProvider.php',
'OCP\\Mail\\Provider\\IService' => __DIR__ . '/../../..' . '/lib/public/Mail/Provider/IService.php',
'OCP\\Mail\\Provider\\Message' => __DIR__ . '/../../..' . '/lib/public/Mail/Provider/Message.php',
+=======
+ 'OCP\\Migration\\Attributes\\AddColumn' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/AddColumn.php',
+ 'OCP\\Migration\\Attributes\\AddIndex' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/AddIndex.php',
+ 'OCP\\Migration\\Attributes\\ColumnMigrationAttribute' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/ColumnMigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\ColumnType' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/ColumnType.php',
+ 'OCP\\Migration\\Attributes\\CreateTable' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/CreateTable.php',
+ 'OCP\\Migration\\Attributes\\DeleteTable' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/DeleteTable.php',
+ 'OCP\\Migration\\Attributes\\DropColumn' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/DropColumn.php',
+ 'OCP\\Migration\\Attributes\\DropIndex' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/DropIndex.php',
+ 'OCP\\Migration\\Attributes\\GenericMigrationAttribute' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/GenericMigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\IndexMigrationAttribute' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/IndexMigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\IndexType' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/IndexType.php',
+ 'OCP\\Migration\\Attributes\\MigrationAttribute' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/MigrationAttribute.php',
+ 'OCP\\Migration\\Attributes\\ModifyColumn' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/ModifyColumn.php',
+ 'OCP\\Migration\\Attributes\\TableMigrationAttribute' => __DIR__ . '/../../..' . '/lib/public/Migration/Attributes/TableMigrationAttribute.php',
+>>>>>>> 2f771df35a9 (feat(upgrade): migration attributes)
'OCP\\Migration\\BigIntMigration' => __DIR__ . '/../../..' . '/lib/public/Migration/BigIntMigration.php',
+ 'OCP\\Migration\\Exceptions\\AttributeException' => __DIR__ . '/../../..' . '/lib/public/Migration/Exceptions/AttributeException.php',
'OCP\\Migration\\IMigrationStep' => __DIR__ . '/../../..' . '/lib/public/Migration/IMigrationStep.php',
'OCP\\Migration\\IOutput' => __DIR__ . '/../../..' . '/lib/public/Migration/IOutput.php',
'OCP\\Migration\\IRepairStep' => __DIR__ . '/../../..' . '/lib/public/Migration/IRepairStep.php',
@@ -1176,7 +1194,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\Db\\ExportSchema' => __DIR__ . '/../../..' . '/core/Command/Db/ExportSchema.php',
'OC\\Core\\Command\\Db\\Migrations\\ExecuteCommand' => __DIR__ . '/../../..' . '/core/Command/Db/Migrations/ExecuteCommand.php',
'OC\\Core\\Command\\Db\\Migrations\\GenerateCommand' => __DIR__ . '/../../..' . '/core/Command/Db/Migrations/GenerateCommand.php',
+ 'OC\\Core\\Command\\Db\\Migrations\\GenerateMetadataCommand' => __DIR__ . '/../../..' . '/core/Command/Db/Migrations/GenerateMetadataCommand.php',
'OC\\Core\\Command\\Db\\Migrations\\MigrateCommand' => __DIR__ . '/../../..' . '/core/Command/Db/Migrations/MigrateCommand.php',
+ 'OC\\Core\\Command\\Db\\Migrations\\PreviewCommand' => __DIR__ . '/../../..' . '/core/Command/Db/Migrations/PreviewCommand.php',
'OC\\Core\\Command\\Db\\Migrations\\StatusCommand' => __DIR__ . '/../../..' . '/core/Command/Db/Migrations/StatusCommand.php',
'OC\\Core\\Command\\Db\\SchemaEncoder' => __DIR__ . '/../../..' . '/core/Command/Db/SchemaEncoder.php',
'OC\\Core\\Command\\Encryption\\ChangeKeyStorageRoot' => __DIR__ . '/../../..' . '/core/Command/Encryption/ChangeKeyStorageRoot.php',
diff --git a/lib/public/Migration/Attributes/AddColumn.php b/lib/public/Migration/Attributes/AddColumn.php
new file mode 100644
index 00000000000..aadf3263b31
--- /dev/null
+++ b/lib/public/Migration/Attributes/AddColumn.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use Attribute;
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_CLASS)]
+class AddColumn extends ColumnMigrationAttribute {
+ public function definition(): string {
+ $type = is_null($this->getType()) ? '' : ' (' . $this->getType()->value . ')';
+ $table = empty($this->getTable()) ? '' : ' to table \'' . $this->getTable() . '\'';
+ return empty($this->getName()) ?
+ 'Addition of a new column' . $type . $table
+ : 'Addition of column \'' . $this->getName() . '\'' . $type . $table;
+ }
+}
diff --git a/lib/public/Migration/Attributes/AddIndex.php b/lib/public/Migration/Attributes/AddIndex.php
new file mode 100644
index 00000000000..9c96cd49a12
--- /dev/null
+++ b/lib/public/Migration/Attributes/AddIndex.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use Attribute;
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_CLASS)]
+class AddIndex extends IndexMigrationAttribute {
+ public function definition(): string {
+ $type = is_null($this->getType()) ? '' : ' (' . $this->getType()->value . ')';
+ $table = empty($this->getTable()) ? '' : ' to table \'' . $this->getTable() . '\'';
+ return 'Addition of a new index' . $type . $table;
+ }
+}
diff --git a/lib/public/Migration/Attributes/ColumnMigrationAttribute.php b/lib/public/Migration/Attributes/ColumnMigrationAttribute.php
new file mode 100644
index 00000000000..6862f73e11d
--- /dev/null
+++ b/lib/public/Migration/Attributes/ColumnMigrationAttribute.php
@@ -0,0 +1,58 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use JsonSerializable;
+
+class ColumnMigrationAttribute extends MigrationAttribute implements JsonSerializable {
+ public function __construct(
+ string $table = '',
+ private string $name = '',
+ private ?ColumnType $type = null,
+ string $description = '',
+ array $notes = [],
+ ) {
+ parent::__construct($table, $description, $notes);
+ }
+
+ public function setName(string $name): self {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function getName(): string {
+ return $this->name;
+ }
+
+ public function setType(?ColumnType $type): self {
+ $this->type = $type;
+ return $this;
+ }
+
+ public function getType(): ?ColumnType {
+ return $this->type;
+ }
+
+ public function import(array $data): self {
+ parent::import($data);
+ $this->setName($data['name'] ?? '');
+ $this->setType(ColumnType::tryFrom($data['type'] ?? ''));
+ return $this;
+ }
+
+ public function jsonSerialize(): array {
+ return array_merge(
+ parent::jsonSerialize(),
+ [
+ 'name' => $this->getName(),
+ 'type' => $this->getType() ?? '',
+ ]
+ );
+ }
+}
diff --git a/lib/public/Migration/Attributes/ColumnType.php b/lib/public/Migration/Attributes/ColumnType.php
new file mode 100644
index 00000000000..058b74f6516
--- /dev/null
+++ b/lib/public/Migration/Attributes/ColumnType.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+/**
+ * enum FieldType based on OCP\DB\Types
+ *
+ * @see \OCP\DB\Types
+ * @since 30.0.0
+ */
+enum ColumnType : string {
+ /** @since 30.0.0 */
+ case BIGINT = 'bigint';
+ /** @since 30.0.0 */
+ case BINARY = 'binary';
+ /** @since 30.0.0 */
+ case BLOB = 'blob';
+ /** @since 30.0.0 */
+ case BOOLEAN = 'boolean';
+ /** @since 30.0.0 */
+ case DATE = 'date';
+ /** @since 30.0.0 */
+ case DATETIME = 'datetime';
+ /** @since 30.0.0 */
+ case DECIMAL = 'decimal';
+ /** @since 30.0.0 */
+ case FLOAT = 'float';
+ /** @since 30.0.0 */
+ case INTEGER = 'integer';
+ /** @since 30.0.0 */
+ case SMALLINT = 'smallint';
+ /** @since 30.0.0 */
+ case STRING = 'string';
+ /** @since 30.0.0 */
+ case TEXT = 'text';
+ /** @since 30.0.0 */
+ case TIME = 'time';
+ /** @since 30.0.0 */
+ case JSON = 'json';
+}
diff --git a/lib/public/Migration/Attributes/CreateTable.php b/lib/public/Migration/Attributes/CreateTable.php
new file mode 100644
index 00000000000..600d9bf4b9f
--- /dev/null
+++ b/lib/public/Migration/Attributes/CreateTable.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use Attribute;
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_CLASS)]
+class CreateTable extends TableMigrationAttribute {
+ public function definition(): string {
+ $definition = empty($this->getTable()) ? 'Creation of a new table' : 'Creation of new table \'' . $this->getTable() . '\'';
+ $definition .= empty($this->getColumns()) ? '' : ' with columns ' . implode(', ', $this->getColumns());
+ return $definition;
+ }
+}
diff --git a/lib/public/Migration/Attributes/DeleteTable.php b/lib/public/Migration/Attributes/DeleteTable.php
new file mode 100644
index 00000000000..97bd36e385e
--- /dev/null
+++ b/lib/public/Migration/Attributes/DeleteTable.php
@@ -0,0 +1,18 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use Attribute;
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_CLASS)]
+class DeleteTable extends MigrationAttribute {
+ public function definition(): string {
+ return empty($this->getTable()) ? 'Deletion of a table' : 'Deletion of table \'' . $this->getTable() . '\'';
+ }
+}
diff --git a/lib/public/Migration/Attributes/DropColumn.php b/lib/public/Migration/Attributes/DropColumn.php
new file mode 100644
index 00000000000..dfa1e81b315
--- /dev/null
+++ b/lib/public/Migration/Attributes/DropColumn.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use Attribute;
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_CLASS)]
+class DropColumn extends ColumnMigrationAttribute {
+ public function definition(): string {
+ $table = empty($this->getTable()) ? '' : ' from table \'' . $this->getTable() . '\'';
+ return empty($this->getName()) ?
+ 'Deletion of a column' . $table
+ : 'Deletion of column \'' . $this->getName() . '\'' . $table;
+ }
+}
diff --git a/lib/public/Migration/Attributes/DropIndex.php b/lib/public/Migration/Attributes/DropIndex.php
new file mode 100644
index 00000000000..cbeea4f5997
--- /dev/null
+++ b/lib/public/Migration/Attributes/DropIndex.php
@@ -0,0 +1,20 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use Attribute;
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_CLASS)]
+class DropIndex extends IndexMigrationAttribute {
+ public function definition(): string {
+ return empty($this->getTable()) ?
+ 'Deletion of an index'
+ : 'Deletion of an index from table \'' . $this->getTable() . '\'';
+ }
+}
diff --git a/lib/public/Migration/Attributes/GenericMigrationAttribute.php b/lib/public/Migration/Attributes/GenericMigrationAttribute.php
new file mode 100644
index 00000000000..f0e3af97615
--- /dev/null
+++ b/lib/public/Migration/Attributes/GenericMigrationAttribute.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use JsonSerializable;
+
+class GenericMigrationAttribute extends MigrationAttribute implements JsonSerializable {
+ public function __construct(
+ private readonly array $details = []
+ ) {
+ parent::__construct(
+ $details['table'] ?? '',
+ $details['description'] ?? '',
+ $details['notes'] ?? []
+ );
+ }
+
+ public function definition(): string {
+ return json_encode($this->jsonSerialize(), JSON_UNESCAPED_SLASHES);
+ }
+
+ public function jsonSerialize(): array {
+ return $this->details;
+ }
+}
diff --git a/lib/public/Migration/Attributes/IndexMigrationAttribute.php b/lib/public/Migration/Attributes/IndexMigrationAttribute.php
new file mode 100644
index 00000000000..fbe636bd6b0
--- /dev/null
+++ b/lib/public/Migration/Attributes/IndexMigrationAttribute.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use JsonSerializable;
+
+class IndexMigrationAttribute extends MigrationAttribute implements JsonSerializable {
+ public function __construct(
+ string $table = '',
+ private ?IndexType $type = null,
+ string $description = '',
+ array $notes = [],
+ ) {
+ parent::__construct($table, $description, $notes);
+ }
+
+ public function setType(?IndexType $type): self {
+ $this->type = $type;
+ return $this;
+ }
+
+ public function getType(): ?IndexType {
+ return $this->type;
+ }
+
+ public function import(array $data): self {
+ parent::import($data);
+ $this->setType(IndexType::tryFrom($data['type'] ?? ''));
+ return $this;
+ }
+
+ public function jsonSerialize(): array {
+ return array_merge(
+ parent::jsonSerialize(),
+ [
+ 'type' => $this->getType() ?? '',
+ ]
+ );
+ }
+}
diff --git a/lib/public/Migration/Attributes/IndexType.php b/lib/public/Migration/Attributes/IndexType.php
new file mode 100644
index 00000000000..842f135e700
--- /dev/null
+++ b/lib/public/Migration/Attributes/IndexType.php
@@ -0,0 +1,21 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+/**
+ * @since 30.0.0
+ */
+enum IndexType : string {
+ /** @since 30.0.0 */
+ case PRIMARY = 'primary'; // migration is estimated to require few minutes
+ /** @since 30.0.0 */
+ case INDEX = 'index'; // depends on setup, migration might require some time
+ /** @since 30.0.0 */
+ case UNIQUE = 'unique'; // migration should be light and quick
+}
diff --git a/lib/public/Migration/Attributes/MigrationAttribute.php b/lib/public/Migration/Attributes/MigrationAttribute.php
new file mode 100644
index 00000000000..9f88614e37d
--- /dev/null
+++ b/lib/public/Migration/Attributes/MigrationAttribute.php
@@ -0,0 +1,66 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use JsonSerializable;
+
+class MigrationAttribute implements JsonSerializable {
+ public function __construct(
+ private string $table = '',
+ private string $description = '',
+ private array $notes = [],
+ ) {
+ }
+
+ public function setTable(string $table): self {
+ $this->table = $table;
+ return $this;
+ }
+
+ public function getTable(): string {
+ return $this->table;
+ }
+
+ public function setDescription(string $description): self {
+ $this->description = $description;
+ return $this;
+ }
+
+ public function getDescription(): string {
+ return $this->description;
+ }
+
+ public function setNotes(array $notes): self {
+ $this->notes = $notes;
+ return $this;
+ }
+
+ public function getNotes(): array {
+ return $this->notes;
+ }
+
+ public function definition(): string {
+ return json_encode($this->jsonSerialize(), JSON_UNESCAPED_SLASHES);
+ }
+
+ public function import(array $data): self {
+ return $this->setTable($data['table'] ?? '')
+ ->setDescription($data['description'] ?? '')
+ ->setNotes($data['notes'] ?? []);
+ }
+
+ public function jsonSerialize(): array {
+ return [
+ 'class' => get_class($this),
+ 'table' => $this->getTable(),
+ 'description' => $this->getDescription(),
+ 'notes' => $this->getNotes(),
+ ];
+ }
+}
diff --git a/lib/public/Migration/Attributes/ModifyColumn.php b/lib/public/Migration/Attributes/ModifyColumn.php
new file mode 100644
index 00000000000..e73b10478f7
--- /dev/null
+++ b/lib/public/Migration/Attributes/ModifyColumn.php
@@ -0,0 +1,22 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use Attribute;
+
+#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_CLASS)]
+class ModifyColumn extends ColumnMigrationAttribute {
+ public function definition(): string {
+ $type = is_null($this->getType()) ? '' : ' to ' . $this->getType()->value;
+ $table = empty($this->getTable()) ? '' : ' from table \'' . $this->getTable() . '\'';
+ return empty($this->getName()) ?
+ 'Modification of a column' . $table . $type
+ : 'Modification of column \'' . $this->getName() . '\'' . $table . $type;
+ }
+}
diff --git a/lib/public/Migration/Attributes/TableMigrationAttribute.php b/lib/public/Migration/Attributes/TableMigrationAttribute.php
new file mode 100644
index 00000000000..1c3f90c6acf
--- /dev/null
+++ b/lib/public/Migration/Attributes/TableMigrationAttribute.php
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Attributes;
+
+use JsonSerializable;
+
+class TableMigrationAttribute extends MigrationAttribute implements JsonSerializable {
+ public function __construct(
+ string $table = '',
+ private array $columns = [],
+ string $description = '',
+ array $notes = [],
+ ) {
+ parent::__construct($table, $description, $notes);
+ }
+
+ public function setColumns(array $columns): self {
+ $this->columns = $columns;
+ return $this;
+ }
+
+ public function getColumns(): array {
+ return $this->columns;
+ }
+
+ public function import(array $data): self {
+ parent::import($data);
+ $this->setColumns($data['columns'] ?? []);
+ return $this;
+ }
+
+ public function jsonSerialize(): array {
+ return array_merge(
+ parent::jsonSerialize(),
+ [
+ 'columns' => $this->getColumns(),
+ ]
+ );
+ }
+}
diff --git a/lib/public/Migration/Exceptions/AttributeException.php b/lib/public/Migration/Exceptions/AttributeException.php
new file mode 100644
index 00000000000..92de70f3e96
--- /dev/null
+++ b/lib/public/Migration/Exceptions/AttributeException.php
@@ -0,0 +1,17 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Migration\Exceptions;
+
+use Exception;
+
+/**
+ * @since 30.0.0
+ */
+class AttributeException extends Exception {
+}