Ejemplo n.º 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;
}
Ejemplo n.º 2
0
 /**
  *
  */
 private function databaseConfiguration($p_input)
 {
     global $g_db;
     if (file_exists(CS_PATH_SITE . DIR_SEP . '.htaccess')) {
         if (!file_exists(CS_PATH_SITE . DIR_SEP . '.htaccess-default')) {
             @copy(CS_PATH_SITE . DIR_SEP . '.htaccess', CS_PATH_SITE . DIR_SEP . '.htaccess-default');
         }
         @unlink(CS_PATH_SITE . DIR_SEP . '.htaccess');
     }
     $session = CampSession::singleton();
     $db_hostname = Input::Get('db_hostname', 'text');
     $db_hostport = Input::Get('db_hostport', 'int');
     $db_username = Input::Get('db_username', 'text');
     $db_userpass = Input::Get('db_userpass', 'text');
     $db_database = Input::Get('db_database', 'text');
     $db_overwrite = Input::Get('db_overwrite', 'int', 0);
     $dbhost = $db_hostname;
     if (empty($db_hostport)) {
         $db_hostport = 3306;
     }
     if (empty($db_hostname) || empty($db_hostport) || empty($db_username) || empty($db_database)) {
         $this->m_step = 'database';
         $this->m_message = 'Error: Please input the requested data';
         return false;
     }
     $error = false;
     $connectionParams = array('dbname' => $db_database, 'user' => $db_username, 'password' => $db_userpass, 'host' => $db_hostname, 'port' => $db_hostport);
     $g_db = $this->getTestDbConnection($connectionParams);
     if (!$g_db->isConnected(true)) {
         $error = true;
     } else {
         $isDbEmpty = TRUE;
         $selectDb = $g_db->hasDatabase($db_database);
         if ($selectDb) {
             $g_db = $this->getDbConnection($connectionParams);
             $dbTables = $g_db->GetAll('SHOW TABLES');
             $isDbEmpty = empty($dbTables) ? TRUE : FALSE;
         }
         if (!$isDbEmpty && !$db_overwrite) {
             $this->m_step = 'database';
             $this->m_overwriteDb = true;
             $this->m_message = '<p>There is already a database named <i>' . $db_database . '</i>.</p><p>If you are sure to overwrite it, check <i>Yes</i> for the option below. If not, just change the <i>Database Name</i> and continue.</p>';
             $this->m_config['database'] = array('hostname' => $db_hostname, 'hostport' => $db_hostport, 'username' => $db_username, 'userpass' => $db_userpass, 'database' => $db_database);
             $session->unsetData('config.db', 'installation');
             $session->setData('config.db', $this->m_config['database'], 'installation', true);
             return false;
         }
     }
     if (!$error && !$selectDb) {
         try {
             $g_db->createDatabase($db_database);
             $g_db = $this->getDbConnection($connectionParams);
         } catch (\Exception $e) {
             $error = true;
         }
     }
     if ($error == true) {
         $this->m_step = 'database';
         $this->m_message = 'Error: Database parameters invalid. Could not ' . 'connect to database server.';
         return false;
     }
     $sqlFile = CS_INSTALL_DIR . DIR_SEP . 'sql' . DIR_SEP . 'campsite_core.sql';
     $errors = CampInstallationBaseHelper::ImportDB($sqlFile, $errorQueries);
     if ($errors > 0) {
         $this->m_step = 'database';
         $this->m_message = 'Error: Importing Database';
         foreach ($errorQueries as $query) {
             $this->m_message .= "<br>{$query}";
         }
         return false;
     }
     // load geonames
     set_time_limit(0);
     foreach (array('CityNames', 'CityLocations') as $table) {
         $conn_specs = 'mysql:host=' . $db_hostname . ';';
         if (!empty($db_hostport)) {
             $conn_specs .= 'port=' . $db_hostport . ';';
         }
         $conn_specs .= 'dbname=' . $db_database . '';
         $l_db = new PDO($conn_specs, $db_username, $db_userpass, array(PDO::MYSQL_ATTR_LOCAL_INFILE => 1, PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
         $l_db->exec("TRUNCATE `{$table}`");
         $l_db->exec("ALTER TABLE `{$table}` DISABLE KEYS");
         $csvFile = CS_INSTALL_DIR . DIR_SEP . 'sql' . DIR_SEP . "{$table}.csv";
         $csvFile = str_replace("\\", "\\\\", $csvFile);
         $l_db->exec("LOAD DATA LOCAL INFILE '{$csvFile}' INTO TABLE {$table} FIELDS TERMINATED BY ';' ENCLOSED BY '\"'");
         $l_db->exec("ALTER TABLE `{$table}` ENABLE KEYS");
     }
     require_once $GLOBALS['g_campsiteDir'] . '/bin/cli_script_lib.php';
     if (!camp_geodata_loaded($g_db)) {
         $which_output = '';
         $which_ret = '';
         @exec('which mysql', $which_output, $which_ret);
         if (is_array($which_output) && isset($which_output[0])) {
             $mysql_client_command = $which_output[0];
             if (0 < strlen($mysql_client_command)) {
                 $db_conf = array('host' => $db_hostname, 'port' => $db_hostport, 'user' => $db_username, 'pass' => $db_userpass, 'name' => $db_database);
                 camp_load_geodata($mysql_client_command, $db_conf);
             }
         }
     }
     // installing the stored function for 'point in polygon' checking
     $sqlFile = CS_INSTALL_DIR . DIR_SEP . 'sql' . DIR_SEP . "checkpp.sql";
     importSqlStoredProgram($g_db, $sqlFile);
     $this->m_config['database'] = array('hostname' => $db_hostname, 'hostport' => $db_hostport, 'username' => $db_username, 'userpass' => $db_userpass, 'database' => $db_database);
     require_once $GLOBALS['g_campsiteDir'] . '/bin/cli_script_lib.php';
     camp_remove_dir(CS_PATH_TEMPLATES . DIR_SEP . '*', null, array('system_templates', 'unassigned'));
     $db_versions = array_map('basename', glob($GLOBALS['g_campsiteDir'] . '/install/sql/upgrade/[2-9].[0-9]*'));
     if (!empty($db_versions)) {
         usort($db_versions, 'camp_version_compare');
         $db_last_version = array_pop($db_versions);
         $db_last_version_dir = $GLOBALS['g_campsiteDir'] . "/install/sql/upgrade/{$db_last_version}/";
         $db_last_roll = '';
         $db_rolls = camp_search_db_rolls($db_last_version_dir, '');
         if (!empty($db_rolls)) {
             $db_last_roll_info = array_slice($db_rolls, -1, 1, true);
             $db_last_roll_info_keys = array_keys($db_last_roll_info);
             $db_last_roll = $db_last_roll_info_keys[0];
         }
         camp_save_database_version($g_db, $db_last_version, $db_last_roll);
     }
     return true;
 }