paneric / migrations
Requires
- monolog/monolog: ^3.2
- php-di/php-di: ^6.4
- psr/container: ^1.0
- symfony/console: ^6.1
- vlucas/phpdotenv: ^5.4
Requires (Dev)
- phpmd/phpmd: ^2.12
- phpstan/phpstan: ^1.8
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^3.7
- symfony/var-dumper: ^6.1
README
Simple framework and dbal agnostic migrations' library created exclusively for sql queries execution.
Requirements
- PHP 8.1
Installation
Composer
$ composer require paneric/migrations
Console command script
Copy: vendor/paneric/migrations/bin/paneric-migrations
into: bin/paneric-migrations
Custom DBAL adapter
Regardless of your personal dbal choice it is required to implement the interface:
<?php
declare(strict_types=1);
namespace Paneric\Migrations;
interface MigrationRepositoryInterface
{
public function createTable(): void;
public function findOneByRef(string $ref): mixed;
/**
* @throws Exception
*/
public function execute(string $multiSql, array $migration);
}
public function createTable(): void;
- this method is required to create eventually missing migration table.
public function findOneByRef(string $ref): mixed;
- this method is required to find a migration entry in table migration by ref field.
- $ref value as a single migration reference represents migration class namespace
public function execute(string $multiSql, array $migration);
- this method is required to execute migration
Bear in mind that some database drivers (e.g. PDO MySQL driver) might not consume multi query sql strings by definition. You have to take this into account and hook this issue when creating this method (e.q. by explode and loop).
- $multiSql : string content of multi query .sql file
- $migration : array of attributes to be inserted into migration table:
<?php
$migration = [
'ref' => MyMigrationClass::class,
'description' => 'My migration description',
];
Container
Configuration
<?php
declare(strict_types=1);
return [
'migrations' => [
'folder_paths' => [
'relative/Folder/Path/' => 'Some\\Namespace',
...
],
],
];
- folder_paths is an array of references for chosen migration classes location
- array key indicates migration folder path
- array key value indicates migration class namespace
Objects
<?php
declare(strict_types=1);
use Paneric\Migrations\Command\Config;
use MigrationRepositoryAdapter;
use Paneric\Migrations\MigrationRepositoryInterface;
use Psr\Container\ContainerInterface;
return [
Config::class => static function (ContainerInterface $container): Config {
return new Config(
$container->get('migrations'),
);
},
MigrationRepositoryInterface::class => static function (
ContainerInterface $container
): CustomMigrationRepositoryAdapter {
$adapter = new CustomMigrationRepositoryAdapter();
$adapter->createTable();
return $adapter;
},
];
- Config::class - migrations configuration class Paneric\Migrations\Command\Config
- MigrationRepositoryInterface::clas - custom MigrationRepository adapter
Commands
Generate
$ php bin/paneric-migrations generate relative/Folder/Path/
Generates migration Some\Namespace\Migration20220815113334 in relative/Folder/Path/.
$ php bin/paneric-migrations generate relative/Folder/Path/ -s User
Generates migration Some\Namespace\Migration20220815113334User with suffix User in relative/Folder/Path/.
Migrate
$ php bin/paneric-migrations migrate
Executes all migrations from within all folders indicated in configuration.
$ php bin/paneric-migrations migrate -f relative/Folder/Path/
Executes all migrations from within single folder as long as it is indicated in configuration.
$ php bin/paneric-migrations migrate -f Migration20220815113334
Executes single migration.
Migration class
<?php
declare(strict_types=1);
namespace Paneric\Auth\Migrations;
use Exception;
use Paneric\Migrations\AbstractMigration;
final class Migration20220815113334Action extends AbstractMigration
{
private const SQL_PATH = '';
public function getDescription(): string
{
return '';
}
/**
* @throws Exception
*/
public function execute(): void
{
$this->executeQuery(file_get_contents(self::SQL_PATH));
}
}
- private const SQL_PATH contains a path of sql file to execute by migration.
- getDescription() returns custom info/comment/description for migration entry that is inserted into database table migration.
Database table "migration"
As a starting point, you can use sql below:
CREATE TABLE IF NOT EXISTS `migration` (
`id` int(11) UNSIGNED NOT NULL,
`ref` varchar(255) COLLATE utf8_unicode_ci,
`description` varchar(255) COLLATE utf8_unicode_ci,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `migration`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `ref` (`ref`),
ADD KEY `created_at` (`created_at`),
ADD KEY `updated_at` (`updated_at`),
MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
Bear in mind that $attributes array is delivered into your execute() method of CustomMigrationRepositoryAdapter in a strictly defined form.
If you decide to customize your migration table, you will need some slight mapping within your execute() method, for example:
<?php
...
/**
* @throws Exception
*/
public function execute(string $multiSql, array $migration): void
{
$migration = [
'namespace' => $migration['ref'],
'information' => $migration['description'],
];
...
}
...
where $migration['description'] stands for value returned by the method getDescription() of generated migration.