<?php
//vim: ts=2 sw=2
include_once "db.php";
class Migration {
public static function instance() {
static $inst = NULL;
if ($inst === NULL) {
$inst = new Migration();
}
return $inst;
}
private function __construct() {
}
public function run() {
$db = DBConn::instance()->db();
$user_version = intval($db->query("PRAGMA user_version")->fetchColumn());
$this->applyMigrations($db, $user_version);
$this->applyDataFixes($db);
}
protected function getMigrationFiles($user_version) {
$result = array();
$glob_pattern = build_file_path(cptBaseDir(), 'app', 'migrations', '*.php');
$migrations = glob($glob_pattern);
if (!is_array($migrations))
return $result;
foreach( $migrations as $mig ) {
$parts = array();
if (preg_match('/\/migrations\/([0-9]+)_[^\/]*.php$/', $mig, $parts)) {
$order = intval($parts[1]);
if ($order < $user_version)
continue;
$result[$order] = $mig;
}
}
return $result;
}
protected function applyMigrations($db, $user_version) {
$migrations = $this->getMigrationFiles($user_version);
if (empty($migrations))
return;
ksort($migrations, SORT_NUMERIC);
error_log('current user_version: ' . $user_version);
error_log('find ' . count($migrations) . ' new db migrations, start to apply ...');
$db->beginTransaction();
foreach($migrations as $order => $path) {
error_log('apply db migration: ' . $path . ' ...');
include($path);
$user_version = $order;
}
$user_version += 1;
error_log('update $user_version to ' . $user_version);
$db->query('PRAGMA user_version = ' . $user_version);
$db->commit();
error_log('db migration done.');
}
protected function applyDataFixes($db) {
if (!$db)
return;
$flag_file = build_file_path(cptBaseDir(), 'RESET_ADMIN_PASSWORD');
if (!file_exists($flag_file))
return;
error_log("start to reset password of 'admin' ...");
$db->beginTransaction();
$db->exec(<<<EOD
UPDATE users SET salt = 'hNsq25IWKmRfSCOu', checksum = 'dc7b9f203aa5cf1bca33d5fc126cd783f98590e9' WHERE name = 'admin';
EOD
);
unlink($flag_file)
$db->commit();
error_log("password reset is done");
}
}
?>