From 05d9c5ddbb989d56d24b19bae5dcce4bf3f9844c Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Mon, 30 Oct 2023 15:14:12 +0200 Subject: [PATCH 1/4] Add TableSorter --- src/Atomizer/Atomizer.php | 38 +++++++----------- src/Atomizer/TableSorter.php | 33 ++++++++++++++++ tests/Migrations/MySQL/TableSorterTest.php | 10 +++++ tests/Migrations/Postgres/TableSorterTest.php | 10 +++++ .../Migrations/SQLServer/TableSorterTest.php | 10 +++++ tests/Migrations/SQLite/TableSorterTest.php | 10 +++++ tests/Migrations/TableSorterTest.php | 39 +++++++++++++++++++ 7 files changed, 126 insertions(+), 24 deletions(-) create mode 100644 src/Atomizer/TableSorter.php create mode 100644 tests/Migrations/MySQL/TableSorterTest.php create mode 100644 tests/Migrations/Postgres/TableSorterTest.php create mode 100644 tests/Migrations/SQLServer/TableSorterTest.php create mode 100644 tests/Migrations/SQLite/TableSorterTest.php create mode 100644 tests/Migrations/TableSorterTest.php diff --git a/src/Atomizer/Atomizer.php b/src/Atomizer/Atomizer.php index 66a7953..3ef0edc 100644 --- a/src/Atomizer/Atomizer.php +++ b/src/Atomizer/Atomizer.php @@ -5,7 +5,6 @@ namespace Cycle\Migrations\Atomizer; use Cycle\Database\Schema\AbstractTable; -use Cycle\Database\Schema\Reflector; use Spiral\Reactor\Partial\Method; /** @@ -18,7 +17,8 @@ final class Atomizer protected array $tables = []; public function __construct( - private readonly RendererInterface $renderer + private readonly RendererInterface $renderer, + private readonly TableSorter $tableSorter = new TableSorter() ) { } @@ -32,6 +32,16 @@ public function addTable(AbstractTable $table): self return $this; } + /** + * @param AbstractTable[] $tables + */ + public function setTables(array $tables): self + { + $this->tables = $tables; + + return $this; + } + /** * Get all atomizer tables. * @@ -47,7 +57,7 @@ public function getTables(): array */ public function declareChanges(Method $method): void { - foreach ($this->sortedTables() as $table) { + foreach ($this->tableSorter->sort($this->tables) as $table) { if (!$table->getComparator()->hasChanges()) { continue; } @@ -65,7 +75,7 @@ public function declareChanges(Method $method): void */ public function revertChanges(Method $method): void { - foreach ($this->sortedTables(true) as $table) { + foreach ($this->tableSorter->sort($this->tables, true) as $table) { if (!$table->getComparator()->hasChanges()) { continue; } @@ -77,24 +87,4 @@ public function revertChanges(Method $method): void } } } - - /** - * Tables sorted in order of their dependencies. - * - * @return AbstractTable[] - */ - protected function sortedTables($reverse = false): array - { - $reflector = new Reflector(); - foreach ($this->tables as $table) { - $reflector->addTable($table); - } - - $sorted = $reflector->sortedTables(); - if ($reverse) { - return \array_reverse($sorted); - } - - return $sorted; - } } diff --git a/src/Atomizer/TableSorter.php b/src/Atomizer/TableSorter.php new file mode 100644 index 0000000..7e1cc1a --- /dev/null +++ b/src/Atomizer/TableSorter.php @@ -0,0 +1,33 @@ +addTable($table); + } + + $sorted = $reflector->sortedTables(); + if ($reverse) { + return \array_reverse($sorted); + } + + return $sorted; + } +} diff --git a/tests/Migrations/MySQL/TableSorterTest.php b/tests/Migrations/MySQL/TableSorterTest.php new file mode 100644 index 0000000..78c9c4a --- /dev/null +++ b/tests/Migrations/MySQL/TableSorterTest.php @@ -0,0 +1,10 @@ +schema('table1'); + $table1->primary('id'); + $table1->integer('value'); + + $table2 = $this->schema('table2'); + $table2->primary('id'); + $table1->integer('value'); + + $this->assertSame([$table1, $table2], $sorter->sort([$table1, $table2])); + } + + public function testSortWithCorrectOrder(): void + { + $sorter = new TableSorter(); + $table1 = $this->schema('table1'); + $table1->primary('id'); + $table1->integer('value'); + + $table2 = $this->schema('table2'); + $table2->primary('id'); + $table2->integer('sample_id'); + $table2->foreignKey(['sample_id'])->references('table1', ['id']); + + $this->assertSame([$table1, $table2], $sorter->sort([$table1, $table2])); + } +} From 87ea50bee67b8d2b9f22850d3f3a3d73c9e6b693 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Mon, 30 Oct 2023 15:18:28 +0200 Subject: [PATCH 2/4] Add unit test --- tests/Migrations/TableSorterTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/Migrations/TableSorterTest.php b/tests/Migrations/TableSorterTest.php index 3ddcb64..823594e 100644 --- a/tests/Migrations/TableSorterTest.php +++ b/tests/Migrations/TableSorterTest.php @@ -36,4 +36,19 @@ public function testSortWithCorrectOrder(): void $this->assertSame([$table1, $table2], $sorter->sort([$table1, $table2])); } + + public function testSortWithIncorrectOrder(): void + { + $sorter = new TableSorter(); + $table1 = $this->schema('table1'); + $table1->primary('id'); + $table1->integer('sample_id'); + $table1->foreignKey(['sample_id'])->references('table2', ['id']); + + $table2 = $this->schema('table2'); + $table2->primary('id'); + $table2->integer('value'); + + $this->assertSame([$table2, $table1], $sorter->sort([$table1, $table2])); + } } From 2b15a202a7e7d43ac098662af90c42099b1d59bb Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Mon, 30 Oct 2023 15:22:51 +0200 Subject: [PATCH 3/4] Remove 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 d7aeea5..2512993 100644 --- a/.github/workflows/ci-mssql.yml +++ b/.github/workflows/ci-mssql.yml @@ -20,7 +20,7 @@ jobs: matrix: include: - 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 a7bc52a..7b947e3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,7 +27,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)" From 383cca330fb31c266a9c94f14e01cf7f0e0bf1d0 Mon Sep 17 00:00:00 2001 From: Maxim Smakouz Date: Mon, 30 Oct 2023 19:59:54 +0200 Subject: [PATCH 4/4] Add setTables test --- tests/Migrations/AtomizerTest.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/Migrations/AtomizerTest.php b/tests/Migrations/AtomizerTest.php index 128c3a7..438fdb3 100644 --- a/tests/Migrations/AtomizerTest.php +++ b/tests/Migrations/AtomizerTest.php @@ -12,6 +12,9 @@ namespace Cycle\Migrations\Tests; use Cycle\Database\Injection\Fragment; +use Cycle\Database\Schema\AbstractTable; +use Cycle\Migrations\Atomizer\Atomizer; +use Cycle\Migrations\Atomizer\Renderer; use Cycle\Migrations\Migration; use Cycle\Migrations\State; @@ -428,4 +431,19 @@ public function testChangeColumnScale(): void $this->migrator->rollback(); $this->assertFalse($this->db->hasTable('sample')); } + + public function testSetTables(): void + { + $atomizer = new Atomizer(new Renderer()); + + $table1 = $this->createMock(AbstractTable::class); + $table2 = $this->createMock(AbstractTable::class); + $table3 = $this->createMock(AbstractTable::class); + + $atomizer->addTable($table1); + $this->assertSame([$table1], $atomizer->getTables()); + + $atomizer->setTables([$table2, $table3]); + $this->assertSame([$table2, $table3], $atomizer->getTables()); + } }