131 lines
4.7 KiB
PHP
131 lines
4.7 KiB
PHP
![]() |
<?php
|
||
|
namespace ProVM\Generator;
|
||
|
|
||
|
use DateTimeInterface;
|
||
|
use DateInterval;
|
||
|
use PDOException;
|
||
|
use Psr\Log\LoggerInterface;
|
||
|
use Symfony\Component\Console\Style\StyleInterface;
|
||
|
use ProVM\Concept;
|
||
|
use ProVM\Repository;
|
||
|
|
||
|
class Migration
|
||
|
{
|
||
|
public function __construct(
|
||
|
protected Concept\Database\Connection $connection, protected Concept\Database $database,
|
||
|
protected Concept\Database\Query\Builder $queryBuilder,
|
||
|
public Repository\Table $tableRepository, protected LoggerInterface $logger,
|
||
|
protected DateTimeInterface $startDate, protected string $databaseName,
|
||
|
protected string $migrationsPath, protected array $skips) {}
|
||
|
|
||
|
public function generate(StyleInterface $io, bool $dryRun = false): void
|
||
|
{
|
||
|
$this->log('Running generate migrations' . (($dryRun) ? ' [dry-run]' : ''), true, $io);
|
||
|
foreach ($this->tableRepository->getAll() as $tableName) {
|
||
|
if (in_array($tableName, $this->skips)) {
|
||
|
continue;
|
||
|
}
|
||
|
$this->log("Table: {$tableName}", true, $io);
|
||
|
$filename = $this->buildFilename($tableName);
|
||
|
$this->log("Filename: {$filename}", $dryRun, $io);
|
||
|
$content = $this->buildFile($tableName);
|
||
|
$this->log("Content: {$content}");
|
||
|
|
||
|
if ($dryRun) {
|
||
|
$status = file_put_contents($filename, $content);
|
||
|
$this->log("Saved: " . var_export($status, true));
|
||
|
try {
|
||
|
$this->registerMigration($tableName);
|
||
|
} catch (PDOException $exception) {
|
||
|
$this->logger->warning($exception);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
$this->log("Total tables migrated: " . count($this->tableRepository->getAll()), true, $io);
|
||
|
}
|
||
|
|
||
|
protected function buildFilename(string $table): string
|
||
|
{
|
||
|
$i = $this->tableRepository->getIndex($table);
|
||
|
$time = $this->startDate->add(new DateInterval("PT{$i}S"));
|
||
|
return implode(DIRECTORY_SEPARATOR, [
|
||
|
$this->migrationsPath,
|
||
|
"{$time->format('YmdHis')}_create_{$table}.php"
|
||
|
]);
|
||
|
}
|
||
|
protected function buildClassName(string $table): string
|
||
|
{
|
||
|
return 'Create' . str_replace(' ', '', ucwords(str_replace('_', ' ', $table)));
|
||
|
}
|
||
|
protected function buildHeader(): string
|
||
|
{
|
||
|
return "<?php
|
||
|
|
||
|
use Phinx\Db\Adapter\MysqlAdapter;
|
||
|
";
|
||
|
}
|
||
|
protected function buildClass(string $table): string
|
||
|
{
|
||
|
return "class {$this->buildClassName($table)} extends Phinx\Migration\AbstractMigration";
|
||
|
}
|
||
|
protected function buildFunction(string $table): string
|
||
|
{
|
||
|
$output = ["{", "\tpublic function change(): void", "\t{"];
|
||
|
$output []= $this->buildInitialSetup();
|
||
|
$this->tableRepository->getDefinition($table);
|
||
|
$output []= $this->tableRepository->parseDefinition($table);
|
||
|
$output []= $this->buildFinalSetup();
|
||
|
$output []= "\t}";
|
||
|
return implode(PHP_EOL, $output);
|
||
|
}
|
||
|
protected function buildInitialSetup(): string
|
||
|
{
|
||
|
return implode(PHP_EOL, [
|
||
|
"\t\t\$this->execute('SET unique_checks=0; SET foreign_key_checks=0;');",
|
||
|
"\t\t\$this->execute(\"ALTER DATABASE CHARACTER SET 'utf8mb4';\");",
|
||
|
"\t\t\$this->execute(\"ALTER DATABASE COLLATE='utf8mb4_general_ci';\");",
|
||
|
''
|
||
|
]);
|
||
|
}
|
||
|
protected function buildFinalSetup(): string
|
||
|
{
|
||
|
return "\t\t\$this->execute('SET unique_checks=1; SET foreign_key_checks=1;');";
|
||
|
}
|
||
|
protected function buildFile(string $table): string
|
||
|
{
|
||
|
return implode(PHP_EOL, [
|
||
|
$this->buildHeader(),
|
||
|
$this->buildClass($table),
|
||
|
$this->buildFunction($table),
|
||
|
'}',
|
||
|
''
|
||
|
]);
|
||
|
}
|
||
|
protected function registerMigration(string $table): void
|
||
|
{
|
||
|
$i = $this->tableRepository->getIndex($table);
|
||
|
$time = $this->startDate->add(new DateInterval("PT{$i}S"));
|
||
|
$this->logger->info("Registering migration: {$time->format('Y-m-d H:i:s')}");
|
||
|
$migrationName = $this->buildClassName($table);
|
||
|
|
||
|
$query = $this->queryBuilder
|
||
|
->insert()
|
||
|
->into('phinxlog')
|
||
|
->columns(['version', 'migration_name', 'start_time', 'end_time', 'breakpoint'])
|
||
|
->values(['?', '?', '?', '?', 0]);
|
||
|
|
||
|
$this->connection->execute($query, [
|
||
|
$time->format('YmdHis'),
|
||
|
$migrationName,
|
||
|
$time->format('Y-m-d H:i:s'),
|
||
|
$time->format('Y-m-d H:i:s')
|
||
|
]);
|
||
|
}
|
||
|
protected function log(string $message, bool $output = false, ?StyleInterface $io = null): void
|
||
|
{
|
||
|
$this->logger->info($message);
|
||
|
if ($output) {
|
||
|
$io->note($message);
|
||
|
}
|
||
|
}
|
||
|
}
|