132 lines
4.6 KiB
PHP
132 lines
4.6 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\Enforce;
|
|
use ProVM\Repository;
|
|
|
|
class Migration extends Enforce\Generator
|
|
{
|
|
public function __construct(
|
|
protected Concept\Database $database,
|
|
protected Concept\Database\Connection $connection,
|
|
protected Concept\Database\Query\Builder $queryBuilder,
|
|
public Repository\Table $tableRepository,
|
|
LoggerInterface $logger,
|
|
protected DateTimeInterface $startDate,
|
|
protected string $databaseName,
|
|
protected string $migrationsPath,
|
|
protected array $skips)
|
|
{
|
|
parent::__construct($logger);
|
|
}
|
|
|
|
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')
|
|
]);
|
|
}
|
|
} |