diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 2ef77c40..7b8f4c30 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,16 @@ + + + + + + + + + + + @@ -9,6 +20,23 @@ + + + addOption('--environment', '-e', InputArgument::OPTIONAL)]]> + addOption('--environment', '-e', InputArgument::OPTIONAL)]]> + addOption('--environment', '-e', InputArgument::OPTIONAL)]]> + addOption('--environment', '-e', InputArgument::OPTIONAL)]]> + addOption('--environment', '-e', InputArgument::OPTIONAL)]]> + addOption('--environment', '-e', InputArgument::OPTIONAL)]]> + setManager(new CakeManager($this->getConfig(), $input, $output))]]> + setManager(new CakeManager($this->getConfig(), $input, $output))]]> + setManager(new CakeManager($this->getConfig(), $input, $output))]]> + setManager(new CakeManager($this->getConfig(), $input, $output))]]> + setManager(new CakeManager($this->getConfig(), $input, $output))]]> + setManager(new CakeManager($this->getConfig(), $input, $output))]]> + setManager(new CakeManager($this->getConfig(), $input, $output))]]> + + @@ -142,6 +170,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/Command/Phinx/Create.php b/src/Command/Phinx/Create.php index c619a25f..c434fb73 100644 --- a/src/Command/Phinx/Create.php +++ b/src/Command/Phinx/Create.php @@ -22,6 +22,9 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +/** + * @deprecated 4.5.0 This command is deprecated alongside phinx compatibility. + */ class Create extends CreateCommand { use CommandTrait { diff --git a/src/Command/Phinx/Dump.php b/src/Command/Phinx/Dump.php index 78208837..b4eca9f3 100644 --- a/src/Command/Phinx/Dump.php +++ b/src/Command/Phinx/Dump.php @@ -26,6 +26,8 @@ * Dump command class. * A "dump" is a snapshot of a database at a given point in time. It is stored in a * .lock file in the same folder as migrations files. + * + * @deprecated 4.5.0 This command is deprecated alongside phinx compatibility. */ class Dump extends AbstractCommand { diff --git a/src/Command/Phinx/MarkMigrated.php b/src/Command/Phinx/MarkMigrated.php index 3bd0ab5e..1170cbb0 100644 --- a/src/Command/Phinx/MarkMigrated.php +++ b/src/Command/Phinx/MarkMigrated.php @@ -23,6 +23,7 @@ /** * @method \Migrations\CakeManager getManager() + * @deprecated 4.5.0 This command is deprecated alongside phinx compatibility. */ class MarkMigrated extends AbstractCommand { diff --git a/src/Command/Phinx/Migrate.php b/src/Command/Phinx/Migrate.php index 01b14057..8c49e7a2 100644 --- a/src/Command/Phinx/Migrate.php +++ b/src/Command/Phinx/Migrate.php @@ -20,6 +20,9 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +/** + * @deprecated 4.5.0 This command is deprecated alongside phinx compatibility. + */ class Migrate extends MigrateCommand { use CommandTrait { diff --git a/src/Command/Phinx/Rollback.php b/src/Command/Phinx/Rollback.php index 5d779973..c025a2c5 100644 --- a/src/Command/Phinx/Rollback.php +++ b/src/Command/Phinx/Rollback.php @@ -20,6 +20,9 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +/** + * @deprecated 4.5.0 This command is deprecated alongside phinx compatibility. + */ class Rollback extends RollbackCommand { use CommandTrait { diff --git a/src/Command/Phinx/Seed.php b/src/Command/Phinx/Seed.php index 652585e4..37d886df 100644 --- a/src/Command/Phinx/Seed.php +++ b/src/Command/Phinx/Seed.php @@ -20,6 +20,9 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +/** + * @deprecated 4.5.0 This command is deprecated alongside phinx compatibility. + */ class Seed extends SeedRun { use CommandTrait { diff --git a/src/Command/Phinx/Status.php b/src/Command/Phinx/Status.php index bb406a7f..9375a216 100644 --- a/src/Command/Phinx/Status.php +++ b/src/Command/Phinx/Status.php @@ -21,6 +21,7 @@ /** * @method \Migrations\CakeManager getManager() + * @deprecated 4.5.0 This command is deprecated alongside phinx compatibility. */ class Status extends StatusCommand { diff --git a/src/Db/Adapter/PdoAdapter.php b/src/Db/Adapter/PdoAdapter.php index 1c30f755..33a29482 100644 --- a/src/Db/Adapter/PdoAdapter.php +++ b/src/Db/Adapter/PdoAdapter.php @@ -17,6 +17,7 @@ use Cake\Database\Query\SelectQuery; use Cake\Database\Query\UpdateQuery; use InvalidArgumentException; +use Migrations\Config\Config; use Migrations\Db\Action\AddColumn; use Migrations\Db\Action\AddForeignKey; use Migrations\Db\Action\AddIndex; @@ -39,7 +40,6 @@ use Migrations\MigrationInterface; use PDO; use PDOException; -use Phinx\Config\Config; use Phinx\Util\Literal as PhinxLiteral; use ReflectionMethod; use RuntimeException; diff --git a/src/Db/Table/Column.php b/src/Db/Table/Column.php index d740e0d0..22bdf851 100644 --- a/src/Db/Table/Column.php +++ b/src/Db/Table/Column.php @@ -9,9 +9,9 @@ namespace Migrations\Db\Table; use Cake\Core\Configure; +use Migrations\Db\Adapter\AdapterInterface; +use Migrations\Db\Adapter\PostgresAdapter; use Migrations\Db\Literal; -use Phinx\Db\Adapter\AdapterInterface; -use Phinx\Db\Adapter\PostgresAdapter; use RuntimeException; /** diff --git a/src/Migration/BackendInterface.php b/src/Migration/BackendInterface.php new file mode 100644 index 00000000..7719494d --- /dev/null +++ b/src/Migration/BackendInterface.php @@ -0,0 +1,81 @@ + $options Options to pass to the command + * Available options are : + * + * - `format` Format to output the response. Can be 'json' + * - `connection` The datasource connection to use + * - `source` The folder where migrations are in + * - `plugin` The plugin containing the migrations + * @return array The migrations list and their statuses + */ + public function status(array $options = []): array; + + /** + * Migrates available migrations + * + * @param array $options Options to pass to the command + * Available options are : + * + * - `target` The version number to migrate to. If not provided, will migrate + * everything it can + * - `connection` The datasource connection to use + * - `source` The folder where migrations are in + * - `plugin` The plugin containing the migrations + * - `date` The date to migrate to + * @return bool Success + */ + public function migrate(array $options = []): bool; + + /** + * Rollbacks migrations + * + * @param array $options Options to pass to the command + * Available options are : + * + * - `target` The version number to migrate to. If not provided, will only migrate + * the last migrations registered in the phinx log + * - `connection` The datasource connection to use + * - `source` The folder where migrations are in + * - `plugin` The plugin containing the migrations + * - `date` The date to rollback to + * @return bool Success + */ + public function rollback(array $options = []): bool; + + /** + * Marks a migration as migrated + * + * @param int|string|null $version The version number of the migration to mark as migrated + * @param array $options Options to pass to the command + * Available options are : + * + * - `connection` The datasource connection to use + * - `source` The folder where migrations are in + * - `plugin` The plugin containing the migrations + * @return bool Success + */ + public function markMigrated(int|string|null $version = null, array $options = []): bool; + + /** + * Seed the database using a seed file + * + * @param array $options Options to pass to the command + * Available options are : + * + * - `connection` The datasource connection to use + * - `source` The folder where migrations are in + * - `plugin` The plugin containing the migrations + * - `seed` The seed file to use + * @return bool Success + */ + public function seed(array $options = []): bool; +} diff --git a/src/Migration/BuiltinBackend.php b/src/Migration/BuiltinBackend.php index 2b806d0e..ee70978c 100644 --- a/src/Migration/BuiltinBackend.php +++ b/src/Migration/BuiltinBackend.php @@ -20,9 +20,6 @@ use DateTime; use InvalidArgumentException; use Migrations\Config\ConfigInterface; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Output\NullOutput; -use Symfony\Component\Console\Output\OutputInterface; /** * The Migrations class is responsible for handling migrations command @@ -30,16 +27,8 @@ * * @internal */ -class BuiltinBackend +class BuiltinBackend implements BackendInterface { - /** - * The OutputInterface. - * Should be a \Symfony\Component\Console\Output\NullOutput instance - * - * @var \Symfony\Component\Console\Output\OutputInterface - */ - protected OutputInterface $output; - /** * Manager instance * @@ -63,14 +52,6 @@ class BuiltinBackend */ protected string $command; - /** - * Stub input to feed the manager class since we might not have an input ready when we get the Manager using - * the `getManager()` method - * - * @var \Symfony\Component\Console\Input\ArrayInput - */ - protected ArrayInput $stubInput; - /** * Constructor * @@ -82,25 +63,13 @@ class BuiltinBackend */ public function __construct(array $default = []) { - $this->output = new NullOutput(); - $this->stubInput = new ArrayInput([]); - if ($default) { $this->default = $default; } } /** - * Returns the status of each migrations based on the options passed - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `format` Format to output the response. Can be 'json' - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * @return array The migrations list and their statuses + * {@inheritDoc} */ public function status(array $options = []): array { @@ -110,18 +79,7 @@ public function status(array $options = []): array } /** - * Migrates available migrations - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `target` The version number to migrate to. If not provided, will migrate - * everything it can - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * - `date` The date to migrate to - * @return bool Success + * {@inheritDoc} */ public function migrate(array $options = []): bool { @@ -141,18 +99,7 @@ public function migrate(array $options = []): bool } /** - * Rollbacks migrations - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `target` The version number to migrate to. If not provided, will only migrate - * the last migrations registered in the phinx log - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * - `date` The date to rollback to - * @return bool Success + * {@inheritDoc} */ public function rollback(array $options = []): bool { @@ -172,16 +119,7 @@ public function rollback(array $options = []): bool } /** - * Marks a migration as migrated - * - * @param int|string|null $version The version number of the migration to mark as migrated - * @param array $options Options to pass to the command - * Available options are : - * - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * @return bool Success + * {@inheritDoc} */ public function markMigrated(int|string|null $version = null, array $options = []): bool { @@ -206,16 +144,7 @@ public function markMigrated(int|string|null $version = null, array $options = [ } /** - * Seed the database using a seed file - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * - `seed` The seed file to use - * @return bool Success + * {@inheritDoc} */ public function seed(array $options = []): bool { diff --git a/src/Migration/PhinxBackend.php b/src/Migration/PhinxBackend.php index 8b81a511..14ad28a7 100644 --- a/src/Migration/PhinxBackend.php +++ b/src/Migration/PhinxBackend.php @@ -35,7 +35,7 @@ * * @internal */ -class PhinxBackend +class PhinxBackend implements BackendInterface { use ConfigurationTrait; @@ -133,16 +133,7 @@ public function getCommand(): string } /** - * Returns the status of each migrations based on the options passed - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `format` Format to output the response. Can be 'json' - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * @return array The migrations list and their statuses + * {@inheritDoc} */ public function status(array $options = []): array { @@ -153,18 +144,7 @@ public function status(array $options = []): array } /** - * Migrates available migrations - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `target` The version number to migrate to. If not provided, will migrate - * everything it can - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * - `date` The date to migrate to - * @return bool Success + * {@inheritDoc} */ public function migrate(array $options = []): bool { @@ -184,18 +164,7 @@ public function migrate(array $options = []): bool } /** - * Rollbacks migrations - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `target` The version number to migrate to. If not provided, will only migrate - * the last migrations registered in the phinx log - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * - `date` The date to rollback to - * @return bool Success + * {@inheritDoc} */ public function rollback(array $options = []): bool { @@ -215,16 +184,7 @@ public function rollback(array $options = []): bool } /** - * Marks a migration as migrated - * - * @param int|string|null $version The version number of the migration to mark as migrated - * @param array $options Options to pass to the command - * Available options are : - * - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * @return bool Success + * {@inheritDoc} */ public function markMigrated(int|string|null $version = null, array $options = []): bool { @@ -257,16 +217,7 @@ public function markMigrated(int|string|null $version = null, array $options = [ } /** - * Seed the database using a seed file - * - * @param array $options Options to pass to the command - * Available options are : - * - * - `connection` The datasource connection to use - * - `source` The folder where migrations are in - * - `plugin` The plugin containing the migrations - * - `seed` The seed file to use - * @return bool Success + * {@inheritDoc} */ public function seed(array $options = []): bool { @@ -285,13 +236,7 @@ public function seed(array $options = []): bool } /** - * Runs the method needed to execute and return - * - * @param string $method Manager method to call - * @param array $params Manager params to pass - * @param \Symfony\Component\Console\Input\InputInterface $input InputInterface needed for the - * Manager to properly run - * @return mixed The result of the CakeManager::$method() call + * {@inheritDoc} */ protected function run(string $method, array $params, InputInterface $input): mixed { diff --git a/src/MigrationInterface.php b/src/MigrationInterface.php index 7b6153f9..28046a39 100644 --- a/src/MigrationInterface.php +++ b/src/MigrationInterface.php @@ -120,6 +120,16 @@ public function getVersion(): int; */ public function setMigratingUp(bool $isMigratingUp); + /** + * Hook method to decide if this migration should use transactions + * + * By default if your driver supports transactions, a transaction will be opened + * before the migration begins, and commit when the migration completes. + * + * @return bool + */ + public function useTransactions(): bool; + /** * Gets whether this migration is being applied or reverted. * True means that the migration is being applied. diff --git a/src/Migrations.php b/src/Migrations.php index 7354436a..71859f89 100644 --- a/src/Migrations.php +++ b/src/Migrations.php @@ -16,6 +16,7 @@ use Cake\Core\Configure; use Cake\Datasource\ConnectionManager; use InvalidArgumentException; +use Migrations\Migration\BackendInterface; use Migrations\Migration\BuiltinBackend; use Migrations\Migration\PhinxBackend; use Phinx\Config\ConfigInterface; @@ -27,7 +28,7 @@ /** * The Migrations class is responsible for handling migrations command - * within an none-shell application. + * within an non-shell application. */ class Migrations { @@ -129,9 +130,9 @@ public function getCommand(): string /** * Get the Migrations interface backend based on configuration data. * - * @return \Migrations\Migration\BuiltinBackend|\Migrations\Migration\PhinxBackend + * @return \Migrations\Migration\BackendInterface */ - protected function getBackend(): BuiltinBackend|PhinxBackend + protected function getBackend(): BackendInterface { $backend = (string)(Configure::read('Migrations.backend') ?? 'builtin'); if ($backend === 'builtin') { diff --git a/src/Shim/MigrationAdapter.php b/src/Shim/MigrationAdapter.php index 6cc13236..ba80f2de 100644 --- a/src/Shim/MigrationAdapter.php +++ b/src/Shim/MigrationAdapter.php @@ -204,9 +204,7 @@ public function setConfig(ConfigInterface $config) } /** - * Gets the name. - * - * @return string + * {@inheritDoc} */ public function getName(): string { @@ -214,10 +212,7 @@ public function getName(): string } /** - * Sets the migration version number. - * - * @param int $version Version - * @return $this + * {@inheritDoc} */ public function setVersion(int $version) { @@ -227,9 +222,7 @@ public function setVersion(int $version) } /** - * Gets the migration version number. - * - * @return int + * {@inheritDoc} */ public function getVersion(): int { @@ -237,10 +230,19 @@ public function getVersion(): int } /** - * Sets whether this migration is being applied or reverted - * - * @param bool $isMigratingUp True if the migration is being applied - * @return $this + * {@inheritDoc} + */ + public function useTransactions(): bool + { + if (method_exists($this->migration, 'useTransactions')) { + return $this->migration->useTransactions(); + } + + return $this->migration->getAdapter()->hasTransactions(); + } + + /** + * {@inheritDoc} */ public function setMigratingUp(bool $isMigratingUp) { @@ -250,10 +252,7 @@ public function setMigratingUp(bool $isMigratingUp) } /** - * Gets whether this migration is being applied or reverted. - * True means that the migration is being applied. - * - * @return bool + * {@inheritDoc} */ public function isMigratingUp(): bool { @@ -261,11 +260,7 @@ public function isMigratingUp(): bool } /** - * Executes a SQL statement and returns the number of affected rows. - * - * @param string $sql SQL - * @param array $params parameters to use for prepared query - * @return int + * {@inheritDoc} */ public function execute(string $sql, array $params = []): int { @@ -273,16 +268,7 @@ public function execute(string $sql, array $params = []): int } /** - * Executes a SQL statement. - * - * The return type depends on the underlying adapter being used. To improve - * IDE auto-completion possibility, you can overwrite the query method - * phpDoc in your (typically custom abstract parent) migration class, where - * you can set the return type by the adapter in your current use. - * - * @param string $sql SQL - * @param array $params parameters to use for prepared query - * @return mixed + * {@inheritDoc} */ public function query(string $sql, array $params = []): mixed { @@ -290,15 +276,7 @@ public function query(string $sql, array $params = []): mixed } /** - * Returns a new Query object that can be used to build complex SELECT, UPDATE, INSERT or DELETE - * queries and execute them against the current database. - * - * Queries executed through the query builder are always sent to the database, regardless of the - * the dry-run settings. - * - * @see https://api.cakephp.org/3.6/class-Cake.Database.Query.html - * @param string $type Query - * @return \Cake\Database\Query + * {@inheritDoc} */ public function getQueryBuilder(string $type): Query { @@ -306,13 +284,7 @@ public function getQueryBuilder(string $type): Query } /** - * Returns a new SelectQuery object that can be used to build complex - * SELECT queries and execute them against the current database. - * - * Queries executed through the query builder are always sent to the database, regardless of the - * the dry-run settings. - * - * @return \Cake\Database\Query\SelectQuery + * {@inheritDoc} */ public function getSelectBuilder(): SelectQuery { @@ -320,13 +292,7 @@ public function getSelectBuilder(): SelectQuery } /** - * Returns a new InsertQuery object that can be used to build complex - * INSERT queries and execute them against the current database. - * - * Queries executed through the query builder are always sent to the database, regardless of the - * the dry-run settings. - * - * @return \Cake\Database\Query\InsertQuery + * {@inheritDoc} */ public function getInsertBuilder(): InsertQuery { @@ -334,13 +300,7 @@ public function getInsertBuilder(): InsertQuery } /** - * Returns a new UpdateQuery object that can be used to build complex - * UPDATE queries and execute them against the current database. - * - * Queries executed through the query builder are always sent to the database, regardless of the - * the dry-run settings. - * - * @return \Cake\Database\Query\UpdateQuery + * {@inheritDoc} */ public function getUpdateBuilder(): UpdateQuery { @@ -348,13 +308,7 @@ public function getUpdateBuilder(): UpdateQuery } /** - * Returns a new DeleteQuery object that can be used to build complex - * DELETE queries and execute them against the current database. - * - * Queries executed through the query builder are always sent to the database, regardless of the - * the dry-run settings. - * - * @return \Cake\Database\Query\DeleteQuery + * {@inheritDoc} */ public function getDeleteBuilder(): DeleteQuery { @@ -362,10 +316,7 @@ public function getDeleteBuilder(): DeleteQuery } /** - * Executes a query and returns only one row as an array. - * - * @param string $sql SQL - * @return array|false + * {@inheritDoc} */ public function fetchRow(string $sql): array|false { @@ -373,10 +324,7 @@ public function fetchRow(string $sql): array|false } /** - * Executes a query and returns an array of rows. - * - * @param string $sql SQL - * @return array + * {@inheritDoc} */ public function fetchAll(string $sql): array { @@ -384,11 +332,7 @@ public function fetchAll(string $sql): array } /** - * Create a new database. - * - * @param string $name Database Name - * @param array $options Options - * @return void + * {@inheritDoc} */ public function createDatabase(string $name, array $options): void { @@ -396,10 +340,7 @@ public function createDatabase(string $name, array $options): void } /** - * Drop a database. - * - * @param string $name Database Name - * @return void + * {@inheritDoc} */ public function dropDatabase(string $name): void { diff --git a/src/Util/ColumnParser.php b/src/Util/ColumnParser.php index 6b98ad97..9c6c7d83 100644 --- a/src/Util/ColumnParser.php +++ b/src/Util/ColumnParser.php @@ -5,7 +5,7 @@ use Cake\Collection\Collection; use Cake\Utility\Hash; -use Phinx\Db\Adapter\AdapterInterface; +use Migrations\Db\Adapter\AdapterInterface; use ReflectionClass; /** diff --git a/tests/TestCase/Migration/EnvironmentTest.php b/tests/TestCase/Migration/EnvironmentTest.php index 990bc577..7e79a780 100644 --- a/tests/TestCase/Migration/EnvironmentTest.php +++ b/tests/TestCase/Migration/EnvironmentTest.php @@ -174,7 +174,7 @@ public function testExecutingAMigrationWithTransactions() $adapterStub->expects($this->once()) ->method('commitTransaction'); - $adapterStub->expects($this->exactly(1)) + $adapterStub->expects($this->atLeastOnce()) ->method('hasTransactions') ->willReturn(true); @@ -206,7 +206,7 @@ public function testExecutingAMigrationWithUseTransactions() $adapterStub->expects($this->never()) ->method('commitTransaction'); - $adapterStub->expects($this->exactly(1)) + $adapterStub->expects($this->atLeastOnce()) ->method('hasTransactions') ->willReturn(true); @@ -227,7 +227,8 @@ public function up(): void } }; - $this->environment->executeMigration($migration, MigrationInterface::UP); + $migrationWrapper = new MigrationAdapter($migration, $migration->getVersion()); + $this->environment->executeMigration($migrationWrapper, MigrationInterface::UP); $this->assertTrue($migration->executed); }