--- /dev/null
+<?php
+
+namespace PFF\Migrations;
+
+class Migrations
+{
+ public function migrate($connection, $paths)
+ {
+ $this->ensureLogExists($connection);
+
+ $files = array();
+ foreach ($paths as $path)
+ $files = array_merge($files, glob($path.'/*.php'));
+
+ sort($files);
+ foreach ($files as $file) {
+ $ts = substr(basename($file), 0, 14);
+
+ if ($this->migrationPassed($connection, $ts))
+ continue;
+
+ echo "Run migration $file\n";
+ require_once $file;
+
+ $connection->beginTransaction();
+ try {
+ $migration = 'Migration_'.$ts;
+ $migration = new $migration;
+ $migration->connection = $connection;
+ $migration->migrate();
+
+ $this->markMigration($connection, $ts);
+ } catch (\Exception $e) {
+ $connection->rollback();
+ throw $e;
+ }
+ $connection->commit();
+ }
+ }
+
+ public function createMigration($path, $hint='')
+ {
+ $ts = date('YmdHis');
+
+ $name = preg_replace('/[^a-z0-9]+/i', '_', $hint);
+ $name = preg_replace('/__+/', '_', $name);
+ $name = preg_replace('/^_/i', '', $name);
+ $name = preg_replace('/_$/i', '', $name);
+ if ($name)
+ $name = '_'.$name;
+
+ $filename = $path.'/'.$ts.$name.'.php';
+
+ file_put_contents($filename, "<?php\n\nclass Migration_$ts extends \PFF\Migrations\Migration\n{\n function migrate()\n {\n }\n}\n\n");
+
+ return $filename;
+ }
+
+ private function ensureLogExists($connection)
+ {
+ $st = $connection->query("SHOW TABLES LIKE 'migration_log'");
+ $exists = $st->fetch();
+ $st->closeCursor();
+
+ if (!$exists) {
+ $connection->exec('CREATE TABLE migration_log (ts CHAR(14) NOT NULL PRIMARY KEY) ENGINE = INNODB');
+ }
+ }
+
+ private function migrationPassed($connection, $ts)
+ {
+ $st = $connection->query("SELECT 1 FROM migration_log WHERE ts = '$ts'");
+ $exists = $st->fetch();
+ $st->closeCursor();
+ return $exists;
+ }
+
+ private function markMigration($connection, $ts)
+ {
+ $st = $connection->exec("INSERT INTO migration_log (ts) VALUES ('$ts')");
+ }
+}
+