exec( "select 1 ". "from `".self::version_table()."` ". "where version = {$pdo->quote(static::version())}" ); if($count === false){ throw $pdo->getError(); } return $count; } final public static function migrations(){ $migrations = array_filter(get_declared_classes(), function($class){ return 0 === strpos($class, "Migration\\"); }); sort($migrations); return $migrations; } final public static function migrate(string $direction, int $amount = 1){ if($amount < 1){ throw new \Exception("Migration amount must be a positive integer"); } $pdo = self::$pdo; $table = $pdo->table(self::version_table()); $table ->column('version', 'varchar(100)') ->primaryKey('version') ->commit(); switch($direction){ case self::MIGRATE_UP: foreach(self::migrations() as $migration){ if(!$migration::installed()){ $pdo->transaction(function($pdo) use($migration, $table){ $migration::up($pdo); $migration::change($pdo, self::MIGRATE_UP); }); $table->insert(['version'=>$migration::version()]); if(!$migration::installed()){ throw new \Exception("Migration {$migration::version()} {$direction} failed"); } if(--$amount == 0){ break; } } } break; case self::MIGRATE_DOWN: foreach(array_reverse(self::migrations()) as $migration){ if($migration::installed()){ $pdo->transaction(function($pdo) use($migration, $table){ $migration::change($pdo, self::MIGRATE_DOWN); $migration::down($pdo); }); $table->delete(['version'=>$migration::version()]); if($migration::installed()){ throw new \Exception("Migration {$migration::version()} {$direction} failed"); } if(--$amount == 0){ break; } } } break; default: throw new \Exception("Invalid migration direction '{$direction}'"); } } final public static function migrate_all(string $direction){ self::migrate($direction, count(self::migrations())); } final public static function bind(string $dsn){ self::$pdo = PDO::from($dsn); } final public static function release(){ self::$pdo = null; } } ?>