/** * Output a migrate page for database. * */ function db_migrate() { if (auth() === false) { return; } if (!file_exists(DATABASE_MIGRATE_PATH)) { error('db: ' . DATABASE_MIGRATE_PATH . ' is not found'); } // initialize if (DATABASE_TYPE === 'pdo_mysql' || DATABASE_TYPE === 'mysql') { db_query(' CREATE TABLE IF NOT EXISTS ' . DATABASE_PREFIX . 'levis_migrations( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT \'id\', version VARCHAR(14) NOT NULL UNIQUE COMMENT \'version\', description VARCHAR(255) NOT NULL COMMENT \'description\', status VARCHAR(80) NOT NULL COMMENT \'status\', installed DATETIME COMMENT \'installed\', PRIMARY KEY(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT \'migration\'; '); } elseif (DATABASE_TYPE === 'pdo_pgsql' || DATABASE_TYPE === 'pgsql') { db_query(' CREATE TABLE IF NOT EXISTS ' . DATABASE_PREFIX . 'levis_migrations( id SERIAL NOT NULL, version VARCHAR(14) NOT NULL UNIQUE, description VARCHAR(255) NOT NULL, status VARCHAR(80) NOT NULL, installed TIMESTAMP, PRIMARY KEY(id) ); '); } else { db_query(' CREATE TABLE IF NOT EXISTS ' . DATABASE_PREFIX . 'levis_migrations( id INTEGER, version VARCHAR NOT NULL UNIQUE, description VARCHAR NOT NULL, status VARCHAR NOT NULL, installed DATETIME, PRIMARY KEY(id) ); '); } // succeeded $resource = db_query('SELECT * FROM ' . DATABASE_PREFIX . 'levis_migrations WHERE status = ' . db_escape('success') . ';'); $results = db_result($resource); $succeeded = array(); foreach ($results as $result) { $succeeded[$result['version']] = true; } // target $targets = array(); if ($dh = opendir(DATABASE_MIGRATE_PATH)) { while (($entry = readdir($dh)) !== false) { if (!is_file(DATABASE_MIGRATE_PATH . $entry)) { continue; } if ($regexp = regexp_match('^([0-9\\-]{14})-[_a-zA-Z0-9\\-]+\\.sql$', $entry)) { $version = $regexp[1]; } else { continue; } if (isset($succeeded[$version])) { continue; } $targets[] = $entry; } closedir($dh); } else { if (LOGGING_MESSAGE) { logging('message', 'db: Opendir error: ' . db_error()); } error('db: Opendir error' . (DEBUG_LEVEL ? ': ' . db_error() : '')); } sort($targets, SORT_STRING); // backup if (!empty($targets) && file_exists(DATABASE_BACKUP_PATH)) { db_export(DATABASE_BACKUP_PATH . localdate('YmdHis') . '.sql'); } // migrate $resource = db_query('DELETE FROM ' . DATABASE_PREFIX . 'levis_migrations WHERE status = ' . db_escape('pending') . ';'); if (!$resource) { if (LOGGING_MESSAGE) { logging('message', 'db: Query error: ' . db_error()); } error('db: Query error' . (DEBUG_LEVEL ? ': ' . db_error() : '')); } $migrate = ''; foreach ($targets as $target) { if ($regexp = regexp_match('^([0-9\\-]{14})-([_a-zA-Z0-9\\-]+)\\.sql$', $target)) { $version = $regexp[1]; $description = $regexp[2]; } else { continue; } $resource = db_query('INSERT INTO ' . DATABASE_PREFIX . 'levis_migrations(version, description, status) VALUES(' . db_escape($version) . ', ' . db_escape($description) . ', ' . db_escape('pending') . ');'); if (!$resource) { if (LOGGING_MESSAGE) { logging('message', 'db: Query error: ' . db_error()); } error('db: Query error' . (DEBUG_LEVEL ? ': ' . db_error() : '')); } $error = false; if ($fp = fopen(DATABASE_MIGRATE_PATH . $target, 'r')) { $sql = ''; $flag = true; db_transaction(); while ($line = fgets($fp)) { $line = str_replace("\r\n", "\n", $line); $line = str_replace("\r", "\n", $line); if ((substr_count($line, '\'') - substr_count($line, '\\\'')) % 2 !== 0) { $flag = !$flag; } $sql .= $line; if (preg_match('/;$/', trim($line)) && $flag) { $resource = db_query($sql, false, false); if (!$resource) { db_rollback(); $error = true; $migrate .= $target . " ... NG\n"; break; } $sql = ''; } } fclose($fp); if ($error === true) { break; } db_commit(); } else { if (LOGGING_MESSAGE) { logging('message', 'db: File can\'t read: ' . db_error()); } error('db: File can\'t read' . (DEBUG_LEVEL ? ': ' . db_error() : '')); } if ($error === false) { $resource = db_query('UPDATE ' . DATABASE_PREFIX . 'levis_migrations SET status = ' . db_escape('success') . ', installed = ' . db_escape(localdate('Y-m-d H:i:s')) . ' WHERE version = ' . db_escape($version) . ';'); if (!$resource) { if (LOGGING_MESSAGE) { logging('message', 'db: Query error: ' . db_error()); } error('db: Query error' . (DEBUG_LEVEL ? ': ' . db_error() : '')); } $migrate .= $target . " ... OK\n"; } } $resource = db_query('SELECT version FROM ' . DATABASE_PREFIX . 'levis_migrations WHERE status = ' . db_escape('success') . ' ORDER BY version DESC LIMIT 1;'); $results = db_result($resource); if (empty($results)) { $version = '-'; } else { $version = $results[0]['version']; } if ($migrate) { $migrate .= "\n"; } $migrate .= "Database: " . DATABASE_NAME . "\n"; $migrate .= "Version: " . $version . "\n"; // history $resource = db_query('SELECT * FROM ' . DATABASE_PREFIX . 'levis_migrations ORDER BY version;'); $migrations = db_result($resource); // result echo "<!DOCTYPE html>\n"; echo "<html>\n"; echo "<head>\n"; echo "<meta charset=\"" . t(MAIN_CHARSET, true) . "\" />\n"; echo "<title>DB Migrate</title>\n"; style(); echo "</head>\n"; echo "<body>\n"; echo "<h1>DB Migrate</h1>\n"; echo "<pre><code>" . t($migrate, true) . "</code></pre>\n"; echo "<table summary=\"migrations\">\n"; echo "<tr>\n"; echo "<th>version</th>\n"; echo "<th>description</th>\n"; echo "<th>status</th>\n"; echo "<th>installed</th>\n"; echo "</tr>\n"; foreach ($migrations as $migration) { echo "<tr>\n"; echo "<td><span style=\"font-family:monospace;\">" . h($migration['version'], true) . "</span></td>\n"; echo "<td><span style=\"font-family:monospace;\">" . h($migration['description'], true) . "</span></td>\n"; echo "<td><span style=\"font-family:monospace;\">" . h($migration['status'], true) . "</span></td>\n"; echo "<td><span style=\"font-family:monospace;\">" . h($migration['installed'], true) . "</span></td>\n"; echo "</tr>\n"; } echo "</table>\n"; echo "</body>\n"; echo "</html>\n"; exit; }
function generate_backup($conn, $ext = 'no', $comm = '') { $filename = $conn['dbname'] . "_" . date("Ymd_Hi") . ".sql"; $filename = db_export($conn, $filename, $ext, $comm); return $filename; }