]> git.andy128k.dev Git - migrations.git/commitdiff
initial version
authorAndrey Kutejko <andy128k@gmail.com>
Thu, 14 Aug 2014 19:01:37 +0000 (22:01 +0300)
committerAndrey Kutejko <andy128k@gmail.com>
Thu, 14 Aug 2014 19:01:37 +0000 (22:01 +0300)
.gitignore [new file with mode: 0644]
composer.json [new file with mode: 0644]
src/migration.php [new file with mode: 0644]
src/migrations.php [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..fcac4a7
--- /dev/null
@@ -0,0 +1,2 @@
+/vendor
+
diff --git a/composer.json b/composer.json
new file mode 100644 (file)
index 0000000..3bc937f
--- /dev/null
@@ -0,0 +1,24 @@
+{
+  "name": "andy128k/migrations",
+  "description": "Simple DB schema migrations",
+  "license": "MIT",
+  "authors": [
+    {
+      "name": "Andrey Kutejko",
+      "email": "andy128k@gmail.com"
+    }
+  ],
+  "autoload": {
+    "classmap" : ["src/"]
+  },
+  "require": {
+    "php": ">=5.3"
+  },
+  "repositories": [
+    {
+      "type": "composer",
+      "url": "http://packages.andy128k.net/php/"
+    }
+  ]
+}
+
diff --git a/src/migration.php b/src/migration.php
new file mode 100644 (file)
index 0000000..66ea729
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace PFF\Migrations;
+
+abstract class Migration
+{
+    public $connection;
+
+    public abstract function migrate();
+
+    protected function query($query, $params=array())
+    {
+        $st = $this->connection->prepare($query);
+        $st->execute($params);
+
+        $rows = array();
+        foreach ($st->fetchAll(\PDO::FETCH_ASSOC) as $r)
+            $rows[] = (object)$r;
+
+        $st->closeCursor();
+        return $rows;
+    }
+}
+
diff --git a/src/migrations.php b/src/migrations.php
new file mode 100644 (file)
index 0000000..0711854
--- /dev/null
@@ -0,0 +1,83 @@
+<?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')");
+    }
+}
+