Beispiel #1
0
/**
 * 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;
}
Beispiel #2
0
function generate_backup($conn, $ext = 'no', $comm = '')
{
    $filename = $conn['dbname'] . "_" . date("Ymd_Hi") . ".sql";
    $filename = db_export($conn, $filename, $ext, $comm);
    return $filename;
}