Skip to content

Instantly share code, notes, and snippets.

@vudaltsov
Last active May 18, 2025 18:35
Show Gist options
  • Save vudaltsov/63f6f0011c146e7d197e0ce034cf4039 to your computer and use it in GitHub Desktop.
Save vudaltsov/63f6f0011c146e7d197e0ce034cf4039 to your computer and use it in GitHub Desktop.
Simplest PHP migrator in the world
<?php
declare(strict_types=1);
namespace PHPyh\Server\ItOps\Migrations;
use Amp\Postgres\PostgresLink;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;
final readonly class Migrator
{
/**
* @param non-empty-string $directory
*/
public function __construct(
private PostgresLink $postgres,
private string $directory,
) {}
public function migrate(): void
{
$this->postgres->query(
<<<'SQL'
create table if not exists migration (
file text not null primary key,
migrated_at timestamptz not null
)
SQL,
);
$files = Finder::create()
->in($this->directory)
->path('Migration')
->name('*.sql')
->sortByName(useNaturalSort: true);
foreach ($files as $file) {
$this->migrateFile($file);
}
}
private function migrateFile(SplFileInfo $file): void
{
$transaction = $this->postgres->beginTransaction();
$result = $transaction->execute(
<<<'SQL'
insert into migration (file, migrated_at)
values (?, now())
on conflict (file) do nothing
SQL,
[$file->getRelativePathname()],
);
if ($result->getRowCount() === 0) {
$transaction->rollback();
return;
}
$transaction->query($file->getContents());
$transaction->commit();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment