From a1f967b50823313eb0fce944c153b6b65dd65443 Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Fri, 7 Jan 2022 19:16:01 +0800 Subject: [PATCH 01/13] Custom builder for migrations --- src/V2/Column.php | 62 ++++++++++ src/V2/ColumnParser.php | 63 ++++++++++ src/V2/ColumnTrait.php | 79 +++++++++++++ src/V2/ColumnType.php | 31 +++++ src/V2/FKAction.php | 51 ++++++++ src/V2/ForeignKey.php | 46 ++++++++ src/V2/ForeignKeyParser.php | 68 +++++++++++ src/V2/Index.php | 33 ++++++ src/V2/IndexParser.php | 42 +++++++ src/V2/Migration.php | 86 ++++++++++++++ src/V2/TableBlueprint.php | 227 ++++++++++++++++++++++++++++++++++++ src/V2/TypeBuilder.php | 46 ++++++++ 12 files changed, 834 insertions(+) create mode 100644 src/V2/Column.php create mode 100644 src/V2/ColumnParser.php create mode 100644 src/V2/ColumnTrait.php create mode 100644 src/V2/ColumnType.php create mode 100644 src/V2/FKAction.php create mode 100644 src/V2/ForeignKey.php create mode 100644 src/V2/ForeignKeyParser.php create mode 100644 src/V2/Index.php create mode 100644 src/V2/IndexParser.php create mode 100644 src/V2/Migration.php create mode 100644 src/V2/TableBlueprint.php create mode 100644 src/V2/TypeBuilder.php diff --git a/src/V2/Column.php b/src/V2/Column.php new file mode 100644 index 0000000..36ef085 --- /dev/null +++ b/src/V2/Column.php @@ -0,0 +1,62 @@ +type = $type; + $this->length = $length; + } + + public function notNull(): self + { + $this->isNotNull = true; + return $this; + } + + public function null(): self + { + $this->isNotNull = false; + return $this; + } + + public function unique(): self + { + $this->isUnique = true; + return $this; + } + + public function check($check): self + { + $this->check = $check; + return $this; + } + + public function defaultValue(?string $default): self + { + if ($default === null) { + $this->null(); + } + + $this->default = $default; + return $this; + } + + public function comment(?string $comment): self + { + $this->comment = $comment; + return $this; + } +} diff --git a/src/V2/ColumnParser.php b/src/V2/ColumnParser.php new file mode 100644 index 0000000..fdaaf89 --- /dev/null +++ b/src/V2/ColumnParser.php @@ -0,0 +1,63 @@ +column = $column; + } + + public function getType(): string + { + return $this->column->type; + } + + public function getLength(): ?int + { + return $this->column->length; + } + + public function isUnique(): bool + { + return $this->column->isUnique; + } + + public function getDefault(): ?string + { + return $this->column->default; + } + + public function isNotNull(): bool + { + return $this->column->isNotNull; + } + + public function getCheck(): ?string + { + return $this->column->check; + } + + public function getComment(): ?string + { + return $this->column->comment; + } + + public function getOptions(): array + { + $options = []; + $options['unique'] = $this->isUnique(); + $options['nullable'] = !$this->isNotNull(); + + if ($this->getDefault() !== null) { + $options['default'] = $this->getDefault(); + } + + return $options; + } +} diff --git a/src/V2/ColumnTrait.php b/src/V2/ColumnTrait.php new file mode 100644 index 0000000..dd9423f --- /dev/null +++ b/src/V2/ColumnTrait.php @@ -0,0 +1,79 @@ +notNull(); + + return $column; + } + + protected function bigPrimaryKey($length = null): Column + { + $column = new Column(ColumnType::TYPE_BIGPK, $length); + $column->notNull(); + + return $column; + } + + protected function string($length = null): Column + { + return new Column(ColumnType::TYPE_STRING, $length); + } + + protected function text(): Column + { + return new Column(ColumnType::TYPE_TEXT); + } + + protected function integer($length = null): Column + { + return new Column(ColumnType::TYPE_INTEGER, $length); + } + + protected function bigInteger($length = null): Column + { + return new Column(ColumnType::TYPE_BIGINT, $length); + } + + protected function numeric($precision = null): Column + { + return new Column(ColumnType::TYPE_NUMERIC, $precision); + } + + protected function dateTime(): Column + { + return new Column(ColumnType::TYPE_DATETIME); + } + + protected function boolean(): Column + { + return new Column(ColumnType::TYPE_BOOLEAN); + } + + protected function money(): Column + { + return new Column(ColumnType::TYPE_MONEY); + } + + protected function json(): Column + { + return new Column(ColumnType::TYPE_JSON); + } + + protected function point(): Column + { + return new Column(ColumnType::TYPE_POINT); + } + + protected function customType(string $type): Column + { + return new Column($type); + } +} diff --git a/src/V2/ColumnType.php b/src/V2/ColumnType.php new file mode 100644 index 0000000..fc70e9f --- /dev/null +++ b/src/V2/ColumnType.php @@ -0,0 +1,31 @@ +value = $value; + } + + public static function Cascade(): self + { + return new self(self::CASCADE); + } + + public static function SetNull(): self + { + return new self(self::SET_NULL); + } + + public static function SetDefault(): self + { + return new self(self::SET_DEFAULT); + } + + public static function Restrict(): self + { + return new self(self::RESTRICT); + } + + public static function NoAction(): self + { + return new self(self::NO_ACTION); + } + + public function value(): string + { + return $this->value; + } +} diff --git a/src/V2/ForeignKey.php b/src/V2/ForeignKey.php new file mode 100644 index 0000000..4bef0b4 --- /dev/null +++ b/src/V2/ForeignKey.php @@ -0,0 +1,46 @@ +innerKeys = $innerKey; + $this->outerTable = $table; + $this->outerKeys = $outerKey; + + $this->onDelete = FKAction::Cascade(); + $this->onUpdate = FKAction::Cascade(); + } + + public function name(?string $name): self + { + $this->name = $name; + + return $this; + } + + public function onDelete(FKAction $action): self + { + $this->onDelete = $action; + + return $this; + } + + public function onUpdate(FKAction $action): self + { + $this->onUpdate = $action; + + return $this; + } +} diff --git a/src/V2/ForeignKeyParser.php b/src/V2/ForeignKeyParser.php new file mode 100644 index 0000000..7ce3452 --- /dev/null +++ b/src/V2/ForeignKeyParser.php @@ -0,0 +1,68 @@ +foreignKey = $foreignKey; + $this->tableName = $tableName; + } + + public function getName(): string + { + return $this->index->name ?? sprintf( + '%s_%s_%s_%s_fk', + $this->getInnerTable(), + $this->getInnerKeys()[0], + $this->getOuterTable(), + $this->getOuterKeys()[0] + ); + } + + public function getInnerTable(): string + { + return $this->tableName; + } + + public function getInnerKeys(): array + { + return $this->foreignKey->innerKeys; + } + + public function getOuterTable(): string + { + return $this->foreignKey->outerTable; + } + + public function getOuterKeys(): array + { + return $this->foreignKey->outerKeys; + } + + public function getOnDelete(): string + { + return $this->foreignKey->onDelete->value(); + } + + public function getOnUpdate(): string + { + return $this->foreignKey->onUpdate->value(); + } + + public function getOptions(): array + { + return [ + 'name' => $this->getName(), + 'delete' => $this->getOnDelete(), + 'update' => $this->getOnUpdate(), + ]; + } +} diff --git a/src/V2/Index.php b/src/V2/Index.php new file mode 100644 index 0000000..43e54fe --- /dev/null +++ b/src/V2/Index.php @@ -0,0 +1,33 @@ +fields = $fields; + $this->name = $name; + } + + public function unique(): self + { + $this->unique = true; + + return $this; + } + + public function notUnique(): self + { + $this->unique = false; + + return $this; + } +} diff --git a/src/V2/IndexParser.php b/src/V2/IndexParser.php new file mode 100644 index 0000000..8c1e025 --- /dev/null +++ b/src/V2/IndexParser.php @@ -0,0 +1,42 @@ +index = $index; + $this->tableName = $tableName; + } + + public function getField(): array + { + return $this->index->fields; + } + + public function getName(): string + { + return $this->index->name + ?? sprintf('%s_%s_index', $this->tableName, implode('_', $this->getField())); + } + + public function isUnique(): bool + { + return $this->index->unique; + } + + public function getOptions(): array + { + return [ + 'name' => $this->getName(), + 'unique' => $this->isUnique(), + ]; + } +} diff --git a/src/V2/Migration.php b/src/V2/Migration.php new file mode 100644 index 0000000..d62f630 --- /dev/null +++ b/src/V2/Migration.php @@ -0,0 +1,86 @@ +capsule = $capsule; + + return $migration; + } + + public function withState(State $state): MigrationInterface + { + $migration = clone $this; + $migration->state = $state; + + return $migration; + } + + public function getState(): State + { + if (empty($this->state)) { + throw new MigrationException('Unable to get migration state, no state are set'); + } + + return $this->state; + } + + protected function database(): DatabaseInterface + { + if (empty($this->capsule)) { + throw new MigrationException('Unable to get database, no capsule are set'); + } + + return $this->capsule->getDatabase(); + } + + protected function table(string $tableName): TableBlueprint + { + return new TableBlueprint($tableName, $this->capsule); + } + + protected function index(array $fields, ?string $name = null): Index + { + return new Index($fields, $name); + } + + protected function foreignKey(array $fields, string $table, array $outerKeys): ForeignKey + { + return new ForeignKey($fields, $table, $outerKeys); + } + + protected function enum(string $name, array $values): TypeBuilder + { + return new TypeBuilder( + $name, + $values, + TypeBuilder::ENUM, + $this->database() + ); + } +} diff --git a/src/V2/TableBlueprint.php b/src/V2/TableBlueprint.php new file mode 100644 index 0000000..4b66706 --- /dev/null +++ b/src/V2/TableBlueprint.php @@ -0,0 +1,227 @@ +tableName = $tableName; + $this->capsule = $capsule; + } + + public function getSchema(): AbstractTable + { + return $this->capsule->getSchema($this->tableName); + } + + public function addColumns(array $columns): self + { + foreach ($columns as $name => $column) { + $columnParser = new ColumnParser($column); + $this->addOperation( + new Operation\Column\Add( + $this->tableName, + $name, + $columnParser->getType(), + $columnParser->getOptions() + ) + ); + } + + return $this; + } + + public function alterColumns(array $columns): self + { + foreach ($columns as $name => $column) { + $columnParser = new ColumnParser($column); + $this->addOperation( + new Operation\Column\Alter( + $this->tableName, + $name, + $columnParser->getType(), + $columnParser->getOptions() + ) + ); + } + + return $this; + } + + public function renameColumn(string $name, string $newName): self + { + return $this->addOperation( + new Operation\Column\Rename($this->tableName, $name, $newName) + ); + } + + public function dropColumns(array $columnsName = []): self + { + foreach ($columnsName as $columnName) { + $this->addOperation( + new Operation\Column\Drop($this->tableName, $columnName) + ); + } + + return $this; + } + + public function addIndexes(array $indexes): self + { + foreach ($indexes as $index) { + $indexParser = new IndexParser($index, $this->tableName); + + $this->addOperation( + new Operation\Index\Add( + $this->tableName, + $indexParser->getField(), + $indexParser->getOptions() + ) + ); + } + + return $this; + } + + public function alterIndexes(array $indexes): self + { + foreach ($indexes as $index) { + $indexParser = new IndexParser($index, $this->tableName); + + $this->addOperation( + new Operation\Index\Alter( + $this->tableName, + $indexParser->getField(), + $indexParser->getOptions() + ) + ); + } + + return $this; + } + + /** + * @example [['email'], ['phone', 'created_at']] - drop two indexes + * @param array $indexes + * @return $this + */ + public function dropIndexesByColumns(array $indexes): self + { + foreach ($indexes as $columns) { + $this->addOperation( + new Operation\Index\Drop($this->tableName, $columns) + ); + } + + return $this; + } + + public function addForeignKeys(array $foreignKeys): self + { + foreach ($foreignKeys as $foreignKey) { + $fkParser = new ForeignKeyParser($foreignKey, $this->tableName); + + $this->addOperation( + new Operation\ForeignKey\Add( + $this->tableName, + $fkParser->getInnerKeys(), + $fkParser->getOuterTable(), + $fkParser->getOuterKeys(), + $fkParser->getOptions() + ) + ); + } + + return $this; + } + + /** + * @example [['email'], ['phone', 'created_at']] - drop two foreignKeys + * @param array $foreignKeys + * @return $this + */ + public function dropForeignKeysByColumns(array $foreignKeys): self + { + foreach ($foreignKeys as $columns) { + $this->addOperation( + new Operation\ForeignKey\Drop($this->tableName, $columns) + ); + } + + return $this; + } + + public function setPrimaryKeys(array $keys): self + { + return $this->addOperation( + new Operation\Table\PrimaryKeys($this->tableName, $keys) + ); + } + + public function create(): void + { + $this->addOperation( + new Operation\Table\Create($this->tableName) + ); + + $this->execute(); + } + + public function update(): void + { + $this->addOperation( + new Operation\Table\Update($this->tableName) + ); + + $this->execute(); + } + + public function rename(string $newName): void + { + $this->addOperation( + new Operation\Table\Rename($this->tableName, $newName) + ); + + $this->execute(); + } + + public function drop(): void + { + $this->addOperation( + new Operation\Table\Drop($this->tableName) + ); + + $this->execute(); + } + + public function addOperation(OperationInterface $operation): self + { + $this->operations[] = $operation; + + return $this; + } + + private function execute(): void + { + if ($this->executed) { + throw new BlueprintException('Only one create/update/rename/drop is allowed per blueprint.'); + } + + $this->capsule->execute($this->operations); + $this->executed = true; + } +} diff --git a/src/V2/TypeBuilder.php b/src/V2/TypeBuilder.php new file mode 100644 index 0000000..18d3861 --- /dev/null +++ b/src/V2/TypeBuilder.php @@ -0,0 +1,46 @@ +db = $db; + $this->name = $name; + $this->values = $values; + $this->type = $type; + } + + public function create(): void + { + $values = implode(',', array_map(static fn($v) => "'{$v}'", $this->values)); + + $query = sprintf( + 'CREATE TYPE %s AS %s (%s);', + $this->name, + $this->type, + $values + ); + + $this->db->execute($query); + $this->db->commit(); + } +} From 3361195e4d182915228011742d399e6c9bd001fd Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Thu, 4 Aug 2022 23:46:16 +0400 Subject: [PATCH 02/13] Added truncate operation --- src/Operation/Table/Truncate.php | 27 +++++++++++++++++++++++++++ src/V2/TableBlueprint.php | 9 +++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/Operation/Table/Truncate.php diff --git a/src/Operation/Table/Truncate.php b/src/Operation/Table/Truncate.php new file mode 100644 index 0000000..3afa118 --- /dev/null +++ b/src/Operation/Table/Truncate.php @@ -0,0 +1,27 @@ +getSchema($this->getTable()); + $database = $this->database ?? '[default]'; + + if (!$schema->exists()) { + throw new TableException( + "Unable to truncate table '{$database}'.'{$this->getTable()}', table does not exists" + ); + } + + $capsule->getDatabase()->execute(sprintf('TRUNCATE `%s`', $this->getTable())); + } +} diff --git a/src/V2/TableBlueprint.php b/src/V2/TableBlueprint.php index 4b66706..7ce5de8 100644 --- a/src/V2/TableBlueprint.php +++ b/src/V2/TableBlueprint.php @@ -208,6 +208,15 @@ public function drop(): void $this->execute(); } + public function truncate(): void + { + $this->addOperation( + new Operation\Table\Truncate($this->tableName) + ); + + $this->execute(); + } + public function addOperation(OperationInterface $operation): self { $this->operations[] = $operation; From 3025a9b1dcd91dfc031866fd5baeba986a719c61 Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Fri, 5 Aug 2022 03:12:11 +0400 Subject: [PATCH 03/13] Added truncate operation --- src/Operation/Table/Truncate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Operation/Table/Truncate.php b/src/Operation/Table/Truncate.php index 3afa118..1edd039 100644 --- a/src/Operation/Table/Truncate.php +++ b/src/Operation/Table/Truncate.php @@ -22,6 +22,6 @@ public function execute(CapsuleInterface $capsule): void ); } - $capsule->getDatabase()->execute(sprintf('TRUNCATE `%s`', $this->getTable())); + $capsule->getDatabase()->execute(sprintf('TRUNCATE "%s"', $this->getTable())); } } From ce0e4b372e600236c7bd26813e4e0915d1de21f9 Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Fri, 5 Aug 2022 03:16:45 +0400 Subject: [PATCH 04/13] Added truncate operation --- src/Operation/Table/Truncate.php | 7 ++++++- src/V2/TableBlueprint.php | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Operation/Table/Truncate.php b/src/Operation/Table/Truncate.php index 1edd039..f3758cb 100644 --- a/src/Operation/Table/Truncate.php +++ b/src/Operation/Table/Truncate.php @@ -8,6 +8,11 @@ final class Truncate extends AbstractOperation { + public function __construct(string $table, private string $strategy) + { + parent::__construct($table); + } + /** * {@inheritdoc} */ @@ -22,6 +27,6 @@ public function execute(CapsuleInterface $capsule): void ); } - $capsule->getDatabase()->execute(sprintf('TRUNCATE "%s"', $this->getTable())); + $capsule->getDatabase()->execute(sprintf('TRUNCATE "%s" %s', $this->getTable(), $this->strategy)); } } diff --git a/src/V2/TableBlueprint.php b/src/V2/TableBlueprint.php index 7ce5de8..7f419a1 100644 --- a/src/V2/TableBlueprint.php +++ b/src/V2/TableBlueprint.php @@ -208,10 +208,10 @@ public function drop(): void $this->execute(); } - public function truncate(): void + public function truncate(string $strategy = ''): void { $this->addOperation( - new Operation\Table\Truncate($this->tableName) + new Operation\Table\Truncate($this->tableName, $strategy) ); $this->execute(); From d3b57c05d225ecae950b0ca9c703da414339c7a8 Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Fri, 26 Aug 2022 13:52:25 +0400 Subject: [PATCH 05/13] Fix code style --- src/V2/FKAction.php | 10 +++++----- src/V2/ForeignKey.php | 4 ++-- src/V2/TypeBuilder.php | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/V2/FKAction.php b/src/V2/FKAction.php index dfd5138..3b343f4 100644 --- a/src/V2/FKAction.php +++ b/src/V2/FKAction.php @@ -19,27 +19,27 @@ private function __construct(string $value) $this->value = $value; } - public static function Cascade(): self + public static function cascade(): self { return new self(self::CASCADE); } - public static function SetNull(): self + public static function setNull(): self { return new self(self::SET_NULL); } - public static function SetDefault(): self + public static function setDefault(): self { return new self(self::SET_DEFAULT); } - public static function Restrict(): self + public static function restrict(): self { return new self(self::RESTRICT); } - public static function NoAction(): self + public static function noAction(): self { return new self(self::NO_ACTION); } diff --git a/src/V2/ForeignKey.php b/src/V2/ForeignKey.php index 4bef0b4..a12791f 100644 --- a/src/V2/ForeignKey.php +++ b/src/V2/ForeignKey.php @@ -19,8 +19,8 @@ public function __construct(array $innerKey, string $table, array $outerKey) $this->outerTable = $table; $this->outerKeys = $outerKey; - $this->onDelete = FKAction::Cascade(); - $this->onUpdate = FKAction::Cascade(); + $this->onDelete = FKAction::cascade(); + $this->onUpdate = FKAction::cascade(); } public function name(?string $name): self diff --git a/src/V2/TypeBuilder.php b/src/V2/TypeBuilder.php index 18d3861..333f715 100644 --- a/src/V2/TypeBuilder.php +++ b/src/V2/TypeBuilder.php @@ -1,6 +1,5 @@ Date: Sun, 30 Oct 2022 14:31:15 +0800 Subject: [PATCH 06/13] Fix code style --- src/V2/TypeBuilder.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/V2/TypeBuilder.php b/src/V2/TypeBuilder.php index 333f715..5982cbb 100644 --- a/src/V2/TypeBuilder.php +++ b/src/V2/TypeBuilder.php @@ -42,4 +42,12 @@ public function create(): void $this->db->execute($query); $this->db->commit(); } + + public function drop(): void + { + $query = sprintf('DROP TYPE %s;', $this->name); + $this->db->execute($query); + $this->db->commit(); + + } } From a9bdef312e9f15426dcf7b3fd687e6973f8fe3d3 Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Sun, 30 Oct 2022 14:39:24 +0800 Subject: [PATCH 07/13] Added drop operation for enum --- src/V2/Migration.php | 3 +-- src/V2/TypeBuilder.php | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/V2/Migration.php b/src/V2/Migration.php index d62f630..fb63249 100644 --- a/src/V2/Migration.php +++ b/src/V2/Migration.php @@ -74,11 +74,10 @@ protected function foreignKey(array $fields, string $table, array $outerKeys): F return new ForeignKey($fields, $table, $outerKeys); } - protected function enum(string $name, array $values): TypeBuilder + protected function enum(string $name): TypeBuilder { return new TypeBuilder( $name, - $values, TypeBuilder::ENUM, $this->database() ); diff --git a/src/V2/TypeBuilder.php b/src/V2/TypeBuilder.php index 5982cbb..1b215cc 100644 --- a/src/V2/TypeBuilder.php +++ b/src/V2/TypeBuilder.php @@ -5,6 +5,7 @@ namespace Cycle\Migrations\V2; use Cycle\Database\DatabaseInterface; +use Cycle\Migrations\Exception\OperationException; class TypeBuilder { @@ -18,18 +19,20 @@ class TypeBuilder public function __construct( string $name, - array $values, string $type, DatabaseInterface $db ) { $this->db = $db; $this->name = $name; - $this->values = $values; $this->type = $type; } public function create(): void { + if (empty($this->values)) { + throw new OperationException('Values can\'t be empty'); + } + $values = implode(',', array_map(static fn($v) => "'{$v}'", $this->values)); $query = sprintf( @@ -50,4 +53,11 @@ public function drop(): void $this->db->commit(); } + + public function addValues(array $values): self + { + $this->values = $values; + + return $this; + } } From ad0a80cdb0e5c56eb72e2d893e717846f743c7ba Mon Sep 17 00:00:00 2001 From: Pavel Buchnev Date: Tue, 3 Jan 2023 18:02:11 +0400 Subject: [PATCH 08/13] Fixes the problem with variadic arguments in column type methods (#45) Co-authored-by: Aleksei Gagarin # Conflicts: # composer.json --- composer.json | 2 +- src/Operation/Column/Column.php | 14 ++++++++++---- tests/Migrations/AtomizerTest.php | 7 +++++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 1477dcd..9586f75 100644 --- a/composer.json +++ b/composer.json @@ -5,7 +5,7 @@ "license": "MIT", "require": { "php": ">=8.0", - "cycle/database": "^2.0", + "cycle/database": "^2.3", "spiral/core": "^2.7", "spiral/files": "^2.7", "spiral/tokenizer": "^2.7", diff --git a/src/Operation/Column/Column.php b/src/Operation/Column/Column.php index c5045da..dd9dd6f 100644 --- a/src/Operation/Column/Column.php +++ b/src/Operation/Column/Column.php @@ -43,21 +43,27 @@ protected function declareColumn(AbstractTable $schema): AbstractColumn //Type configuring if (method_exists($column, $this->type)) { $arguments = []; + $variadic = false; $method = new \ReflectionMethod($column, $this->type); foreach ($method->getParameters() as $parameter) { if ($this->hasOption($parameter->getName())) { - $arguments[] = $this->getOption($parameter->getName()); + $arguments[$parameter->getName()] = $this->getOption($parameter->getName()); } elseif (!$parameter->isOptional()) { throw new ColumnException( "Option '{$parameter->getName()}' are required to define column with type '{$this->type}'" ); - } else { - $arguments[] = $parameter->getDefaultValue(); + } elseif ($parameter->isDefaultValueAvailable()) { + $arguments[$parameter->getName()] = $parameter->getDefaultValue(); + } elseif ($parameter->isVariadic()) { + $variadic = true; } } - call_user_func_array([$column, $this->type], $arguments); + \call_user_func_array( + [$column, $this->type], + $variadic ? $arguments + $this->options + $column->getAttributes() : $arguments, + ); } else { $column->type($this->type); } diff --git a/tests/Migrations/AtomizerTest.php b/tests/Migrations/AtomizerTest.php index f6d41e4..128c3a7 100644 --- a/tests/Migrations/AtomizerTest.php +++ b/tests/Migrations/AtomizerTest.php @@ -310,7 +310,7 @@ public function testCreateDatetimeNowColumn(): void $this->migrator->configure(); $schema = $this->schema('sample'); - $column = $schema->datetime('value'); + $column = $schema->datetime('value', size: 2, foo: 'bar'); $column->defaultValue(new Fragment($column::DATETIME_NOW)); $this->atomize('migration1', [$schema]); @@ -318,7 +318,10 @@ public function testCreateDatetimeNowColumn(): void $this->migrator->run(); $this->assertTrue($this->db->hasTable('sample')); - $this->assertSame((string)$column->getDefaultValue(), (string)$this->schema('sample')->column('value')->getDefaultValue()); + $this->assertSame( + (string)$column->getDefaultValue(), + (string)$this->schema('sample')->column('value')->getDefaultValue() + ); $this->migrator->rollback(); $this->assertFalse($this->db->hasTable('sample')); From 2f358a2da0362aa9f538339eb78f08d376161e46 Mon Sep 17 00:00:00 2001 From: AnrDaemon Date: Sat, 21 Jan 2023 15:55:36 +0300 Subject: [PATCH 09/13] Removed unnecessary string operations (#43) Co-authored-by: roxblnfk --- src/FileRepository.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/FileRepository.php b/src/FileRepository.php index 7a47fff..b64175d 100644 --- a/src/FileRepository.php +++ b/src/FileRepository.php @@ -136,7 +136,7 @@ private function getFiles(string $directory): \Generator { foreach ($this->files->getFiles($directory, '*.php') as $filename) { $reflection = new ReflectionFile($filename); - $definition = \explode('_', \basename($filename)); + $definition = \explode('_', \basename($filename, '.php'), 3); if (\count($definition) < 3) { throw new RepositoryException("Invalid migration filename '{$filename}'"); @@ -152,11 +152,7 @@ private function getFiles(string $directory): \Generator 'class' => $reflection->getClasses()[0], 'created' => $created, 'chunk' => $definition[1], - 'name' => \str_replace( - '.php', - '', - \implode('_', \array_slice($definition, 2)) - ), + 'name' => $definition[2], ]; } } From cb9b241c3f9a1757d9d82782ce46c49b4af2be5c Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Mon, 23 Jan 2023 23:43:49 +0800 Subject: [PATCH 10/13] Fix options for cycle/database 2.3.0 --- src/V2/ColumnParser.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/V2/ColumnParser.php b/src/V2/ColumnParser.php index fdaaf89..d6275c7 100644 --- a/src/V2/ColumnParser.php +++ b/src/V2/ColumnParser.php @@ -58,6 +58,10 @@ public function getOptions(): array $options['default'] = $this->getDefault(); } + if ($this->getType() === ColumnType::TYPE_DATETIME) { + $options['attributes'] = []; + } + return $options; } } From 0c7e8371113cb260be704b981e912dd87c9ef0ba Mon Sep 17 00:00:00 2001 From: Sergei Iamskoi Date: Mon, 23 Jan 2023 23:50:58 +0800 Subject: [PATCH 11/13] Rollback options and update fork --- src/V2/ColumnParser.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/V2/ColumnParser.php b/src/V2/ColumnParser.php index d6275c7..fdaaf89 100644 --- a/src/V2/ColumnParser.php +++ b/src/V2/ColumnParser.php @@ -58,10 +58,6 @@ public function getOptions(): array $options['default'] = $this->getDefault(); } - if ($this->getType() === ColumnType::TYPE_DATETIME) { - $options['attributes'] = []; - } - return $options; } } From 5c9a731b6cd146162ee8cf6edf46b9e5d4323f3f Mon Sep 17 00:00:00 2001 From: AnrDaemon Date: Mon, 13 Nov 2023 23:04:29 +0300 Subject: [PATCH 12/13] Fixed array_multisort parameters error --- src/FileRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FileRepository.php b/src/FileRepository.php index 7a47fff..ef3f424 100644 --- a/src/FileRepository.php +++ b/src/FileRepository.php @@ -66,7 +66,7 @@ public function getMigrations(): array $migrations[] = $migration->withState(new State($f['name'], $f['created'])); } - \array_multisort($timestamps, $chunks, SORT_ASC | SORT_NATURAL, $migrations); + \array_multisort($timestamps, $chunks, SORT_NATURAL, $migrations); return $migrations; } From 11581aff286d21d99878a41c2e38093b2f097a41 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Mon, 20 Nov 2023 19:19:52 +0200 Subject: [PATCH 13/13] Change pdo_sqlsrv extension version --- .github/workflows/ci-mssql.yml | 2 +- .github/workflows/main.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-mssql.yml b/.github/workflows/ci-mssql.yml index d5eafbb..b68c197 100644 --- a/.github/workflows/ci-mssql.yml +++ b/.github/workflows/ci-mssql.yml @@ -24,7 +24,7 @@ jobs: extensions: pdo, pdo_sqlsrv mssql: 'server:2019-latest' - php: '8.1' - extensions: pdo, pdo_sqlsrv-5.10.0beta2 + extensions: pdo, pdo_sqlsrv mssql: 'server:2019-latest' services: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 38fce4e..6bfcb60 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ jobs: php-version: ${{ matrix.php-versions }} coverage: pcov tools: pecl - extensions: mbstring, pdo, pdo_sqlite, pdo_pgsql, pdo_sqlsrv-5.10.0beta2, pdo_mysql + extensions: mbstring, pdo, pdo_sqlite, pdo_pgsql, pdo_sqlsrv, pdo_mysql - name: Get Composer Cache Directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)"