paneric/migrations

v1.0.5 2022-08-15 17:45 UTC

This package is auto-updated.

Last update: 2024-04-15 21:16:25 UTC


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.