diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 53dd1d7..bb3ad38 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -1,5 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]]>
+
+
@@ -25,26 +46,4 @@
database]]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- getName()]]>
- getName()]]>
- getName()]]>
-
-
diff --git a/psalm.xml b/psalm.xml
index 755ad51..286a1ec 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -5,6 +5,7 @@
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="psalm-baseline.xml"
errorLevel="1"
+ findUnusedBaselineEntry="true"
>
diff --git a/src/Changes/ChangeType.php b/src/Changes/ChangeType.php
new file mode 100644
index 0000000..296404a
--- /dev/null
+++ b/src/Changes/ChangeType.php
@@ -0,0 +1,25 @@
+
+ */
+ public function collect(Atomizer $atomizer): array
+ {
+ $result = [];
+
+ foreach ($atomizer->getTables() as $table) {
+ if ($table->getStatus() === AbstractTable::STATUS_NEW) {
+ $result[] = [ChangeType::CreateTable, $table->getName()];
+ continue;
+ }
+
+ if ($table->getStatus() === AbstractTable::STATUS_DECLARED_DROPPED) {
+ $result[] = [ChangeType::DropTable, $table->getName()];
+ continue;
+ }
+
+ if ($table->getComparator()->isRenamed()) {
+ $result[] = [ChangeType::RenameTable, $table->getInitialName()];
+ continue;
+ }
+
+ $result[] = [ChangeType::ChangeTable, $table->getName()];
+
+ $comparator = $table->getComparator();
+
+ foreach ($comparator->addedColumns() as $column) {
+ $result[] = [ChangeType::AddColumn, $column->getName()];
+ }
+
+ foreach ($comparator->droppedColumns() as $column) {
+ $result[] = [ChangeType::DropColumn, $column->getName()];
+ }
+
+ foreach ($comparator->alteredColumns() as $column) {
+ $result[] = [ChangeType::AlterColumn, $column[0]->getName()];
+ }
+
+ foreach ($comparator->addedIndexes() as $index) {
+ $result[] = [ChangeType::AddIndex, $index->getName()];
+ }
+
+ foreach ($comparator->droppedIndexes() as $index) {
+ $result[] = [ChangeType::DropIndex, $index->getName()];
+ }
+
+ foreach ($comparator->alteredIndexes() as $index) {
+ $result[] = [ChangeType::AlterIndex, $index[0]->getName()];
+ }
+
+ foreach ($comparator->addedForeignKeys() as $fk) {
+ $result[] = [ChangeType::AddFk, $fk->getName()];
+ }
+
+ foreach ($comparator->droppedForeignKeys() as $fk) {
+ $result[] = [ChangeType::DropFk, $fk->getName()];
+ }
+
+ foreach ($comparator->alteredForeignKeys() as $fk) {
+ $result[] = [ChangeType::AlterFk, $fk[0]->getName()];
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/src/ChangesCountNameGenerator.php b/src/ChangesCountNameGenerator.php
new file mode 100644
index 0000000..86c4162
--- /dev/null
+++ b/src/ChangesCountNameGenerator.php
@@ -0,0 +1,62 @@
+collect($atomizer) as $pair) {
+ $key = $this->changeToString($pair[0]);
+ $map[$key] ??= 0;
+ $map[$key]++;
+ }
+
+ $result = [];
+ foreach ($map as $key => $cnt) {
+ $result[] = "{$key}{$cnt}";
+ }
+
+ return \implode('_', $result);
+ }
+
+ private function changeToString(ChangeType $change): string
+ {
+ return match ($change) {
+ ChangeType::CreateTable => 'ct',
+ ChangeType::DropTable => 'dt',
+ ChangeType::RenameTable,
+ ChangeType::ChangeTable => 't',
+ ChangeType::AddColumn,
+ ChangeType::DropColumn,
+ ChangeType::AlterColumn => 'c',
+ ChangeType::AddIndex,
+ ChangeType::DropIndex,
+ ChangeType::AlterIndex => 'i',
+ ChangeType::AddFk,
+ ChangeType::DropFk,
+ ChangeType::AlterFk => 'fk',
+ };
+ }
+}
diff --git a/src/NameBasedOnChangesGenerator.php b/src/NameBasedOnChangesGenerator.php
index b851ce4..4c0f120 100644
--- a/src/NameBasedOnChangesGenerator.php
+++ b/src/NameBasedOnChangesGenerator.php
@@ -4,72 +4,44 @@
namespace Cycle\Schema\Generator\Migrations;
-use Cycle\Database\Schema\AbstractTable;
use Cycle\Migrations\Atomizer\Atomizer;
+use Cycle\Schema\Generator\Migrations\Changes\ChangeType;
+use Cycle\Schema\Generator\Migrations\Changes\Collector;
final class NameBasedOnChangesGenerator implements NameGeneratorInterface
{
public function generate(Atomizer $atomizer): string
{
- $name = [];
-
- foreach ($atomizer->getTables() as $table) {
- if ($table->getStatus() === AbstractTable::STATUS_NEW) {
- $name[] = 'create_' . $table->getName();
- continue;
- }
-
- if ($table->getStatus() === AbstractTable::STATUS_DECLARED_DROPPED) {
- $name[] = 'drop_' . $table->getName();
- continue;
- }
-
- if ($table->getComparator()->isRenamed()) {
- $name[] = 'rename_' . $table->getInitialName();
- continue;
- }
-
- $name[] = 'change_' . $table->getName();
-
- $comparator = $table->getComparator();
-
- foreach ($comparator->addedColumns() as $column) {
- $name[] = 'add_' . $column->getName();
- }
-
- foreach ($comparator->droppedColumns() as $column) {
- $name[] = 'rm_' . $column->getName();
- }
-
- foreach ($comparator->alteredColumns() as $column) {
- $name[] = 'alter_' . $column[0]->getName();
- }
-
- foreach ($comparator->addedIndexes() as $index) {
- $name[] = 'add_index_' . $index->getName();
- }
-
- foreach ($comparator->droppedIndexes() as $index) {
- $name[] = 'rm_index_' . $index->getName();
- }
-
- foreach ($comparator->alteredIndexes() as $index) {
- $name[] = 'alter_index_' . $index[0]->getName();
- }
-
- foreach ($comparator->addedForeignKeys() as $fk) {
- $name[] = 'add_fk_' . $fk->getName();
- }
-
- foreach ($comparator->droppedForeignKeys() as $fk) {
- $name[] = 'rm_fk_' . $fk->getName();
- }
-
- foreach ($comparator->alteredForeignKeys() as $fk) {
- $name[] = 'alter_fk_' . $fk[0]->getName();
- }
- }
+ $collector = new Collector();
+ return \implode(
+ '_',
+ \array_map(
+ fn(array $pair): string => $this->changeToString($pair[0], $pair[1]),
+ $collector->collect($atomizer),
+ ),
+ );
+ }
- return \implode('_', $name);
+ private function changeToString(ChangeType $change, string $name): string
+ {
+ return sprintf(
+ '%s_%s',
+ match ($change) {
+ ChangeType::CreateTable => 'create',
+ ChangeType::DropTable => 'drop',
+ ChangeType::RenameTable => 'rename',
+ ChangeType::ChangeTable => 'change',
+ ChangeType::AddColumn => 'add',
+ ChangeType::DropColumn => 'rm',
+ ChangeType::AlterColumn => 'alter',
+ ChangeType::AddIndex => 'add_index',
+ ChangeType::DropIndex => 'rm_index',
+ ChangeType::AlterIndex => 'alter_index',
+ ChangeType::AddFk => 'add_fk',
+ ChangeType::DropFk => 'rm_fk',
+ ChangeType::AlterFk => 'alter_fk',
+ },
+ $name,
+ );
}
}
diff --git a/tests/Migrations/Unit/ChangesCountTest.php b/tests/Migrations/Unit/ChangesCountTest.php
new file mode 100644
index 0000000..5500c67
--- /dev/null
+++ b/tests/Migrations/Unit/ChangesCountTest.php
@@ -0,0 +1,107 @@
+createMock(RendererInterface::class),
+ );
+
+ $create = $this->createMock(AbstractTable::class);
+ $create->method('getName')->willReturn('creates');
+ $create->method('getStatus')->willReturn(AbstractTable::STATUS_NEW);
+
+ $drops = $this->createMock(AbstractTable::class);
+ $drops->method('getName')->willReturn('drops');
+ $drops->method('getStatus')->willReturn(AbstractTable::STATUS_DECLARED_DROPPED);
+
+ $renamesCmp = $this->createMock(ComparatorInterface::class);
+ $renamesCmp->method('isRenamed')->willReturn(true);
+ $renames = $this->createMock(AbstractTable::class);
+ $renames->method('getName')->willReturn('renames');
+ $renames->method('getStatus')->willReturn(AbstractTable::STATUS_EXISTS);
+ $renames->method('getComparator')->willReturn($renamesCmp);
+ $renames->method('getInitialName')->willReturn('old_name');
+
+ // Comparator
+ $changeCmp = $this->createMock(ComparatorInterface::class);
+ $changeCmp->method('isRenamed')->willReturn(false);
+ //// Column
+ $columnAdd = $this->createMock(AbstractColumn::class);
+ $columnAdd->method('getName')->willReturn('c1');
+ $columnDrop = $this->createMock(AbstractColumn::class);
+ $columnDrop->method('getName')->willReturn('c2');
+ $columnAlter = $this->createMock(AbstractColumn::class);
+ $columnAlter->method('getName')->willReturn('c3');
+ $changeCmp->method('addedColumns')->willReturn([$columnAdd]);
+ $changeCmp->method('droppedColumns')->willReturn([$columnDrop]);
+ $changeCmp->method('alteredColumns')
+ ->willReturn([
+ [$columnAlter, $this->createMock(AbstractColumn::class)],
+ ]);
+ //// Index
+ $indexAdd = $this->createMock(AbstractIndex::class);
+ $indexAdd->method('getName')->willReturn('i1');
+ $indexDrop = $this->createMock(AbstractIndex::class);
+ $indexDrop->method('getName')->willReturn('i2');
+ $indexAlter = $this->createMock(AbstractIndex::class);
+ $indexAlter->method('getName')->willReturn('i3');
+ $changeCmp->method('addedIndexes')->willReturn([$indexAdd]);
+ $changeCmp->method('droppedIndexes')->willReturn([$indexDrop]);
+ $changeCmp->method('alteredIndexes')
+ ->willReturn([
+ [$indexAlter, $this->createMock(AbstractIndex::class)],
+ ]);
+ //// FK
+ $fkAdd = $this->createMock(AbstractForeignKey::class);
+ $fkAdd->method('getName')->willReturn('fk1');
+ $fkDrop = $this->createMock(AbstractForeignKey::class);
+ $fkDrop->method('getName')->willReturn('fk2');
+ $fkAlter = $this->createMock(AbstractForeignKey::class);
+ $fkAlter->method('getName')->willReturn('fk3');
+ $changeCmp->method('addedForeignKeys')->willReturn([$fkAdd]);
+ $changeCmp->method('droppedForeignKeys')->willReturn([$fkDrop]);
+ $changeCmp->method('alteredForeignKeys')
+ ->willReturn([
+ [$fkAlter, $this->createMock(AbstractForeignKey::class)],
+ ]);
+
+ // Table
+ $change = $this->createMock(AbstractTable::class);
+ $change->method('getStatus')->willReturn(AbstractTable::STATUS_EXISTS);
+ $renames->method('getName')->willReturn('changes');
+ $change->method('getComparator')->willReturn($changeCmp);
+
+ $atomizer
+ ->addTable($create)
+ ->addTable($drops)
+ ->addTable($renames)
+ ->addTable($change);
+ $generator = new ChangesCountNameGenerator();
+ self::assertSame(
+ 'ct1_dt1_t2_c3_i3_fk3',
+ $generator->generate($atomizer),
+ );
+ }
+}
diff --git a/tests/Migrations/Unit/NameBasedOnChangesGeneratorTest.php b/tests/Migrations/Unit/NameBasedOnChangesGeneratorTest.php
new file mode 100644
index 0000000..67ecd57
--- /dev/null
+++ b/tests/Migrations/Unit/NameBasedOnChangesGeneratorTest.php
@@ -0,0 +1,54 @@
+createMock(RendererInterface::class),
+ );
+
+ $create = $this->createMock(AbstractTable::class);
+ $create->method('getName')->willReturn('creates');
+ $create->method('getStatus')->willReturn(AbstractTable::STATUS_NEW);
+
+ $drops = $this->createMock(AbstractTable::class);
+ $drops->method('getName')->willReturn('drops');
+ $drops->method('getStatus')->willReturn(AbstractTable::STATUS_DECLARED_DROPPED);
+
+ $renamesCmp = $this->createMock(ComparatorInterface::class);
+ $renamesCmp->method('isRenamed')->willReturn(true);
+ $renames = $this->createMock(AbstractTable::class);
+ $renames->method('getName')->willReturn('renames');
+ $renames->method('getStatus')->willReturn(AbstractTable::STATUS_EXISTS);
+ $renames->method('getComparator')->willReturn($renamesCmp);
+ $renames->method('getInitialName')->willReturn('old_name');
+
+ $atomizer
+ ->addTable($create)
+ ->addTable($drops)
+ ->addTable($renames);
+ $generator = new NameBasedOnChangesGenerator();
+ self::assertSame(
+ 'create_creates_drop_drops_rename_old_name',
+ $generator->generate($atomizer),
+ );
+ }
+}