DB::WLOCK], $fun); } public static function getStatus($name) { $u = DB::selectFirst([ "select * from upgrades", "where", ["name" => $name] ]); if ($u) { return $u['status']; } else { return 'down'; } } public static function upgrade($name, $type) { if ($type != 'up' && $type != 'down') { die("invalid upgrade type\n"); } echo $type . ' ' . HTML::escape($name) . ': '; $dir = self::upgraderRoot() . '/' . $name; if (!is_dir($dir)) { die("invalid upgrade name\n"); } if (self::getStatus($name) == $type) { echo "OK\n"; return; } if (is_file($dir . '/upgrade.php')) { $fun = include $dir . '/upgrade.php'; $fun($type); } if (is_file($dir . '/' . $type . '.sql')) { self::runSQL($dir . '/' . $type . '.sql'); } if (is_file($dir . '/upgrade.php')) { $fun = include $dir . '/upgrade.php'; $fun("{$type}_after_sql"); } if (is_file($dir . '/upgrade.sh')) { self::runShell('/bin/bash' . ' ' . escapeshellarg($dir . '/upgrade.sh') . ' ' . $type); } DB::insert([ "insert into upgrades", "(name, status, updated_at)", "values", DB::tuple([$name, $type, DB::now()]), "on duplicate key update", ["status" => $type, "updated_at" => DB::now()] ]); echo "DONE\n"; } public static function up($name) { self::upgrade($name, 'up'); } public static function down($name) { self::upgrade($name, 'down'); } public static function refresh($name) { self::upgrade($name, 'down'); self::upgrade($name, 'up'); } public static function remove($name) { self::upgrade($name, 'down'); DB::delete([ "delete from upgrades", "where", ["name" => $name] ]); } public static function removeAll() { $names = []; foreach (DB::selectAll("select * from upgrades") as $u) { $names[] = $u['name']; } natsort($names); foreach (array_reverse($names) as $name) { self::upgrade($name, 'down'); } DB::delete("delete from upgrades"); } public static function upgradeToLatest() { $names = array_filter(scandir(self::upgraderRoot()), function ($name) { return is_dir(self::upgraderRoot() . '/' . $name) && preg_match('/^\d+_[0-9a-zA-Z\._]+$/', $name); }); natsort($names); $names_table = []; foreach ($names as $name) { $names_table[$name] = true; } $dres = DB::selectAll("select * from upgrades"); foreach ($dres as $u) { if (!isset($names_table[$u['name']])) { die('missing: ' . HTML::escape($name) . "\n"); } } foreach ($names as $name) { self::up($name); } } }