Пример #1
0
function camp_upgrade_database($p_dbName, $p_silent = false, $p_showRolls = false)
{
    global $Campsite;
    $campsite_dir = $Campsite['CAMPSITE_DIR'];
    $etc_dir = $Campsite['ETC_DIR'];
    if (!camp_database_exists($p_dbName)) {
        return "Can't upgrade database {$p_dbName}: it doesn't exist";
    }
    $lockFileName = __FILE__;
    $lockFile = fopen($lockFileName, "r");
    if ($lockFile === false) {
        return "Unable to create single process lock control!";
    }
    if (!flock($lockFile, LOCK_EX | LOCK_NB)) {
        // do an exclusive lock
        return "The upgrade process is already running.";
    }
    $old_version = '';
    // what version was imported before running the upgrade
    $old_roll = '';
    // what roll was imported before running the upgrade
    if (!($res = camp_detect_database_version($p_dbName, $old_version, $old_roll)) == 0) {
        flock($lockFile, LOCK_UN);
        // release the lock
        return $res;
    }
    $last_db_version = $old_version;
    // keeping the last imported version throughout the upgrade process
    $last_db_roll = $old_roll;
    // keeping the last imported roll throughout the upgrade process
    $db_host = $Campsite['DATABASE_SERVER_ADDRESS'];
    $db_port = $Campsite['DATABASE_SERVER_PORT'];
    $db_username = $Campsite['DATABASE_USER'];
    $db_userpass = $Campsite['DATABASE_PASSWORD'];
    $db_database = $p_dbName;
    $first = true;
    $skipped = array();
    $versions = array_map('basename', glob($campsite_dir . '/install/Resources/sql/upgrade/[2-9].[0-9]*'));
    usort($versions, 'camp_version_compare');
    if (-1 == camp_version_compare($old_version, '3.5.x')) {
        return "Can not upgrade from version older than 3.5.\nUpgrade into Newscoop 3.5 first.\n";
    }
    // the $db_version, $db_roll are for keeping the last imported db changes
    // when $db_version is lesser then 3.5.x, we do not support upgrade
    // for $db_version 3.5.x and greater, the rolls can be:
    //     ''    ... no changes from the $db_version yet applied => apply both main and all the roll updates
    //     '.'   ... just the main changes applied => apply just all the roll updates
    //     roll  ... applied the main changes, plus rolls upto the given roll => apply roll updates greater then the current roll
    // it is supposed that from 3.6.x on, we will not use db change sets in the $db_version directory itslef
    // when (in the upgrade cycle) going to a greater version, roll is set to '', since all changes there have to be applied
    foreach ($versions as $index => $db_version) {
        //if ($old_version > $db_version) {
        //    continue;
        //}
        if (-1 == camp_version_compare($db_version, $old_version)) {
            continue;
        }
        $last_db_version = $db_version;
        $last_db_roll = '';
        $cur_old_roll = '';
        // the roll of the running version that was imported before the upgrade ($old_roll or '')
        if ($first) {
            $last_db_roll = $old_roll;
            $cur_old_roll = $old_roll;
            if (!$p_silent) {
                $db_ver_roll_info = "{$db_version}";
                if (!in_array($old_roll, array('', '.'))) {
                    $db_ver_roll_info .= ", roll {$old_roll}";
                }
                echo "\n\t* Upgrading the database from version {$db_ver_roll_info}...";
            }
            if ($old_version < '3.4.x') {
                $res = camp_utf8_convert(null, $skipped);
                if ($res !== true) {
                    flock($lockFile, LOCK_UN);
                    // release the lock
                    return $res;
                }
            }
            $first = false;
        }
        $output = array();
        $upgrade_base_dir = $campsite_dir . "/install/Resources/sql/upgrade/{$db_version}/";
        $rolls = camp_search_db_rolls($upgrade_base_dir, $cur_old_roll);
        $db_conf_file = $etc_dir . '/database_conf.php';
        $install_conf_file = $etc_dir . "/install_conf.php";
        // run upgrade scripts
        $sql_scripts = array("tables.sql", "data-required.sql", "data-optional.sql", "tables-post.sql");
        foreach ($rolls as $upgrade_dir_roll => $upgrade_dir_path) {
            $upgrade_dir = $upgrade_dir_path . DIRECTORY_SEPARATOR;
            $last_db_roll = $upgrade_dir_roll;
            if ($p_showRolls || !$p_silent) {
                echo "\n<pre>\t\t * importing database roll {$last_db_version} / {$last_db_roll}</pre>\n";
            }
            foreach ($sql_scripts as $index => $script) {
                if (!is_file($upgrade_dir . $script)) {
                    continue;
                }
                $error_queries = array();
                $sq_file = $upgrade_dir . $script;
                $err_count = camp_import_dbfile($db_host . ":" . $db_port, $db_username, $db_userpass, $db_database, $sq_file, $error_queries);
                if ($err_count && $script != "data-optional.sql") {
                    flock($lockFile, LOCK_UN);
                    // release the lock
                    return "{$script} ({$db_version}) errors on:\n" . implode("\n", $error_queries);
                }
            }
            $res = camp_save_database_version($p_dbName, $last_db_version, $last_db_roll);
            if (0 !== $res) {
                echo $res;
            }
        }
    }
    if (!$p_silent) {
        echo "done.\n";
    }
    if (count($skipped) > 0 && !$p_silent) {
        echo "\nEncountered non-critical errors while converting data to UTF-8 encoding!\nThe following database queries were unsuccessful because after conversion\ntext values become case insensitive. Words written in different case were\nunique before the conversion; after the conversion they are identical,\nbreaking some constraints in the database.\n\nThe upgrade script can not fix these issues automatically!\n\nYou can continue to use the data as is and manually fix these issues\nlater. The table fields that were not converted will not support case\ninsensitive searches.\n\nPlease save the following list of skipped queries:\n";
        foreach ($skipped as $query) {
            echo "{$query};\n";
        }
        echo "-- end of queries list --\n";
    }
    //$res = camp_save_database_version($p_dbName, $last_db_version, $last_db_roll);
    //if (0 !== $res) {
    //    echo $res;
    //}
    flock($lockFile, LOCK_UN);
    // release the lock
    return 0;
}
Пример #2
0
/**
 * @param string $p_dbName
 */
function camp_upgrade_database($p_dbName, $p_silent = false)
{
    global $Campsite;

    $campsite_dir = $Campsite['CAMPSITE_DIR'];
    $etc_dir = $Campsite['ETC_DIR'];

    if (!camp_database_exists($p_dbName)) {
        return "Can't upgrade database $p_dbName: it doesn't exist";
    }

    $lockFileName = __FILE__;
    $lockFile = fopen($lockFileName, "r");
    if ($lockFile === false) {
        return "Unable to create single process lock control!";
    }
    if (!flock($lockFile, LOCK_EX | LOCK_NB)) { // do an exclusive lock
        return "The upgrade process is already running.";
    }

    if (!($res = camp_detect_database_version($p_dbName, $old_version)) == 0) {
        flock($lockFile, LOCK_UN); // release the lock
        return $res;
    }

    $first = true;
    $skipped = array();
    $versions = array_map('basename', glob($campsite_dir . '/install/sql/upgrade/[2-9].[0-9]*'));
    usort($versions, 'camp_version_compare');
    foreach ($versions as $index=>$db_version) {
        if ($old_version > $db_version) {
            continue;
        }
        if ($first) {
            if (!$p_silent) {
                echo "\n\t* Upgrading the database from version $db_version...";
            }
            if ($old_version < '3.4.x') {
                $res = camp_utf8_convert(null, $skipped);
                if ($res !== true) {
                    flock($lockFile, LOCK_UN); // release the lock
                    return $res;
                }
            }
            $first = false;
        }
        $output = array();

        $upgrade_dir = $campsite_dir . "/install/sql/upgrade/$db_version/";
        $db_conf_file = $etc_dir . '/database_conf.php';
        $install_conf_file = $etc_dir . "/install_conf.php";

        // run upgrade scripts
        $cmd_prefix = "cd " . escapeshellarg($upgrade_dir)
            . " && mysql --user="******" --host=" . $Campsite['DATABASE_SERVER_ADDRESS']
            . " --port=" . $Campsite['DATABASE_SERVER_PORT']
            . ' --default-character-set=utf8';
        if ($Campsite['DATABASE_PASSWORD'] != "") {
            $cmd_prefix .= " --password=\"" . $Campsite['DATABASE_PASSWORD'] . "\"";
        }
        $cmd_prefix .= " " . escapeshellarg($p_dbName) . " < ";
        $sql_scripts = array("tables.sql", "data-required.sql", "data-optional.sql");
        foreach ($sql_scripts as $index=>$script) {
            if (!is_file($upgrade_dir . $script)) {
                continue;
            }
            $cmd = $cmd_prefix . $script . " 2>&1";
            exec($cmd, $output, $res);
            if ($res != 0 && $script != "data-optional.sql") {
                flock($lockFile, LOCK_UN); // release the lock
                return "$script ($db_version): " . implode("\n", $output);
            }
        }
    }
    if (!$p_silent) {
        echo "done.\n";
    }

    if (count($skipped) > 0 && !$p_silent) {
        echo "
Encountered non-critical errors while converting data to UTF-8 encoding!
The following database queries were unsuccessful because after conversion
text values become case insensitive. Words written in different case were
unique before the conversion; after the conversion they are identical,
breaking some constraints in the database.

The upgrade script can not fix these issues automatically!

You can continue to use the data as is and manually fix these issues
later. The table fields that were not converted will not support case
insensitive searches.

Please save the following list of skipped queries:\n";
        foreach ($skipped as $query) {
            echo "$query;\n";
        }
        echo "-- end of queries list --\n";
    }

    flock($lockFile, LOCK_UN); // release the lock
    return 0;
} // fn camp_upgrade_database