Skip to content

Commit 10fd8bf

Browse files
authored
5.x Add first pass at migration table storage abstraction (#951)
Extract the existing logic into another object. We could define an interface or extend this class for the new table storage. The Adapter layer can pick one table or the other based on config, and we can have both available at the same time for the upgrade process.
1 parent 93089cc commit 10fd8bf

File tree

3 files changed

+245
-92
lines changed

3 files changed

+245
-92
lines changed

src/Db/Adapter/AbstractAdapter.php

Lines changed: 20 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use Cake\Database\Schema\SchemaDialect;
2020
use Cake\I18n\Date;
2121
use Cake\I18n\DateTime;
22-
use Exception;
2322
use InvalidArgumentException;
2423
use Migrations\Config\Config;
2524
use Migrations\Db\Action\AddColumn;
@@ -37,7 +36,6 @@
3736
use Migrations\Db\AlterInstructions;
3837
use Migrations\Db\InsertMode;
3938
use Migrations\Db\Literal;
40-
use Migrations\Db\Table;
4139
use Migrations\Db\Table\CheckConstraint;
4240
use Migrations\Db\Table\Column;
4341
use Migrations\Db\Table\ForeignKey;
@@ -129,21 +127,7 @@ public function setConnection(Connection $connection): AdapterInterface
129127
if (!$this->hasTable($this->getSchemaTableName())) {
130128
$this->createSchemaTable();
131129
} else {
132-
$table = new Table($this->getSchemaTableName(), [], $this);
133-
if (!$table->hasColumn('migration_name')) {
134-
$table
135-
->addColumn(
136-
'migration_name',
137-
'string',
138-
['limit' => 100, 'after' => 'version', 'default' => null, 'null' => true],
139-
)
140-
->save();
141-
}
142-
if (!$table->hasColumn('breakpoint')) {
143-
$table
144-
->addColumn('breakpoint', 'boolean', ['default' => false, 'null' => false])
145-
->save();
146-
}
130+
$this->migrationsTable()->upgradeTable();
147131
}
148132

149133
return $this;
@@ -357,26 +341,7 @@ public function hasColumn(string $tableName, string $columnName): bool
357341
*/
358342
public function createSchemaTable(): void
359343
{
360-
try {
361-
$options = [
362-
'id' => false,
363-
'primary_key' => 'version',
364-
];
365-
366-
$table = new Table($this->getSchemaTableName(), $options, $this);
367-
$table->addColumn('version', 'biginteger', ['null' => false])
368-
->addColumn('migration_name', 'string', ['limit' => 100, 'default' => null, 'null' => true])
369-
->addColumn('start_time', 'timestamp', ['default' => null, 'null' => true])
370-
->addColumn('end_time', 'timestamp', ['default' => null, 'null' => true])
371-
->addColumn('breakpoint', 'boolean', ['default' => false, 'null' => false])
372-
->save();
373-
} catch (Exception $exception) {
374-
throw new InvalidArgumentException(
375-
'There was a problem creating the schema table: ' . $exception->getMessage(),
376-
(int)$exception->getCode(),
377-
$exception,
378-
);
379-
}
344+
$this->migrationsTable()->createTable();
380345
}
381346

382347
/**
@@ -815,6 +780,18 @@ public function getVersions(): array
815780
return array_keys($rows);
816781
}
817782

783+
/**
784+
* Get the migrations table storage implementation.
785+
*
786+
* @return \Migrations\Db\Adapter\MigrationsTableStorage
787+
* @internal
788+
*/
789+
protected function migrationsTable(): MigrationsTableStorage
790+
{
791+
// TODO Use configure/auto-detect which implmentation to use.
792+
return new MigrationsTableStorage($this, $this->getSchemaTableName());
793+
}
794+
818795
/**
819796
* {@inheritDoc}
820797
*
@@ -832,10 +809,7 @@ public function getVersionLog(): array
832809
default:
833810
throw new RuntimeException('Invalid version_order configuration option');
834811
}
835-
$query = $this->getSelectBuilder();
836-
$query->select('*')
837-
->from($this->getSchemaTableName())
838-
->orderBy($orderBy);
812+
$query = $this->migrationsTable()->getVersions($orderBy);
839813

840814
// This will throw an exception if doing a --dry-run without any migrations as phinxlog
841815
// does not exist, so in that case, we can just expect to trivially return empty set
@@ -862,24 +836,10 @@ public function getVersionLog(): array
862836
public function migrated(MigrationInterface $migration, string $direction, string $startTime, string $endTime): AdapterInterface
863837
{
864838
if (strcasecmp($direction, MigrationInterface::UP) === 0) {
865-
$query = $this->getInsertBuilder();
866-
$query->insert(['version', 'migration_name', 'start_time', 'end_time', 'breakpoint'])
867-
->into($this->getSchemaTableName())
868-
->values([
869-
'version' => (string)$migration->getVersion(),
870-
'migration_name' => substr($migration->getName(), 0, 100),
871-
'start_time' => $startTime,
872-
'end_time' => $endTime,
873-
'breakpoint' => 0,
874-
]);
875-
$this->executeQuery($query);
839+
$this->migrationsTable()->recordUp($migration, $startTime, $endTime);
876840
} else {
877841
// down
878-
$query = $this->getDeleteBuilder();
879-
$query->delete()
880-
->from($this->getSchemaTableName())
881-
->where(['version' => $migration->getVersion()]);
882-
$this->executeQuery($query);
842+
$this->migrationsTable()->recordDown($migration);
883843
}
884844

885845
return $this;
@@ -890,19 +850,7 @@ public function migrated(MigrationInterface $migration, string $direction, strin
890850
*/
891851
public function toggleBreakpoint(MigrationInterface $migration): AdapterInterface
892852
{
893-
$params = [
894-
$migration->getVersion(),
895-
];
896-
$this->query(
897-
sprintf(
898-
'UPDATE %1$s SET %2$s = CASE %2$s WHEN true THEN false ELSE true END, %4$s = %4$s WHERE %3$s = ?;',
899-
$this->quoteTableName($this->getSchemaTableName()),
900-
$this->quoteColumnName('breakpoint'),
901-
$this->quoteColumnName('version'),
902-
$this->quoteColumnName('start_time'),
903-
),
904-
$params,
905-
);
853+
$this->migrationsTable()->toggleBreakpoint($migration);
906854

907855
return $this;
908856
}
@@ -912,17 +860,7 @@ public function toggleBreakpoint(MigrationInterface $migration): AdapterInterfac
912860
*/
913861
public function resetAllBreakpoints(): int
914862
{
915-
$query = $this->getUpdateBuilder();
916-
$query->update($this->getSchemaTableName())
917-
->set([
918-
'breakpoint' => 0,
919-
'start_time' => $query->identifier('start_time'),
920-
])
921-
->where([
922-
'breakpoint !=' => 0,
923-
]);
924-
925-
return $this->executeQuery($query);
863+
return $this->migrationsTable()->resetAllBreakpoints();
926864
}
927865

928866
/**
@@ -954,16 +892,7 @@ public function unsetBreakpoint(MigrationInterface $migration): AdapterInterface
954892
*/
955893
protected function markBreakpoint(MigrationInterface $migration, bool $state): AdapterInterface
956894
{
957-
$query = $this->getUpdateBuilder();
958-
$query->update($this->getSchemaTableName())
959-
->set([
960-
'breakpoint' => (int)$state,
961-
'start_time' => $query->identifier('start_time'),
962-
])
963-
->where([
964-
'version' => $migration->getVersion(),
965-
]);
966-
$this->executeQuery($query);
895+
$this->migrationsTable()->markBreakpoint($migration, $state);
967896

968897
return $this;
969898
}

0 commit comments

Comments
 (0)