function scheduled_auto_optimize() { global $modSettings, $db_prefix, $db_type; // By default do it now! $delay = false; // As a kind of hack, if the server load is too great delay, but only by a bit! if (!empty($modSettings['load_average']) && !empty($modSettings['loadavg_auto_opt']) && $modSettings['load_average'] >= $modSettings['loadavg_auto_opt']) { $delay = true; } // Otherwise are we restricting the number of people online for this? if (!empty($modSettings['autoOptMaxOnline'])) { $request = smf_db_query(' SELECT COUNT(*) FROM {db_prefix}log_online', array()); list($dont_do_it) = mysql_fetch_row($request); mysql_free_result($request); if ($dont_do_it > $modSettings['autoOptMaxOnline']) { $delay = true; } } // If we are gonna delay, do so now! if ($delay) { return false; } db_extend(); // Get all the tables. $tables = smf_db_list_tables(false, $db_prefix . '%'); // Actually do the optimisation. if ($db_type == 'sqlite') { smf_db_optimize_table($table[0]); } else { foreach ($tables as $table) { smf_db_optimize_table($table); } } // Return for the log... return true; }
function DatabasePopulation() { global $txt, $db_connection, $databases, $modSettings, $db_type, $db_prefix, $incontext, $db_name, $boardurl; $incontext['sub_template'] = 'populate_database'; $incontext['page_title'] = $txt['db_populate']; $incontext['continue'] = 1; // Already done? if (isset($_POST['pop_done'])) { return true; } // Reload settings. require dirname(__FILE__) . '/Settings.php'; load_database(); // Before running any of the queries, let's make sure another version isn't already installed. $result = smf_db_query(' SELECT variable, value FROM {db_prefix}settings', array('db_error_skip' => true)); $modSettings = array(); if ($result !== false) { while ($row = mysql_fetch_assoc($result)) { $modSettings[$row['variable']] = $row['value']; } mysql_free_result($result); // Do they match? If so, this is just a refresh so charge on! if (!isset($modSettings['smfVersion']) || $modSettings['smfVersion'] != $GLOBALS['current_smf_version']) { $incontext['error'] = $txt['error_versions_do_not_match']; return false; } } smf_db_query(' SET NAMES utf8', array()); $boardurl = $_POST['boardurl']; echo $boardurl; $replaces = array('{$db_prefix}' => $db_prefix, '{$boarddir}' => mysql_real_escape_string(dirname(__FILE__)), '{$boardurl}' => $boardurl, '{$enableCompressedOutput}' => isset($_POST['compress']) ? '1' : '0', '{$databaseSession_enable}' => isset($_POST['dbsession']) ? '1' : '0', '{$smf_version}' => $GLOBALS['current_smf_version'], '{$current_time}' => time(), '{$sched_task_offset}' => 82800 + mt_rand(0, 86399)); foreach ($txt as $key => $value) { if (substr($key, 0, 8) == 'default_') { $replaces['{$' . $key . '}'] = mysql_real_escape_string($value); } } $replaces['{$default_reserved_names}'] = strtr($replaces['{$default_reserved_names}'], array('\\\\n' => '\\n')); $replaces[') ENGINE=MyISAM;'] = ') ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;'; // Read in the SQL. Turn this on and that off... internationalize... etc. $sql_lines = explode("\n", strtr(implode(' ', file(dirname(__FILE__) . '/install_' . $GLOBALS['db_script_version'] . '_' . $db_type . '.sql')), $replaces)); // Execute the SQL. $current_statement = ''; $exists = array(); $incontext['failures'] = array(); $incontext['sql_results'] = array('tables' => 0, 'inserts' => 0, 'table_dups' => 0, 'insert_dups' => 0); foreach ($sql_lines as $count => $line) { // No comments allowed! if (substr(trim($line), 0, 1) != '#') { $current_statement .= "\n" . rtrim($line); } // Is this the end of the query string? if (empty($current_statement) || preg_match('~;[\\s]*$~s', $line) == 0 && $count != count($sql_lines)) { continue; } // Does this table already exist? If so, don't insert more data into it! if (preg_match('~^\\s*INSERT INTO ([^\\s\\n\\r]+?)~', $current_statement, $match) != 0 && in_array($match[1], $exists)) { $incontext['sql_results']['insert_dups']++; $current_statement = ''; continue; } if (smf_db_query($current_statement, array('security_override' => true, 'db_error_skip' => true), $db_connection) === false) { // Error 1050: Table already exists! //!!! Needs to be made better! if (($db_type != 'mysql' || mysql_errno($db_connection) === 1050) && preg_match('~^\\s*CREATE TABLE ([^\\s\\n\\r]+?)~', $current_statement, $match) == 1) { $exists[] = $match[1]; $incontext['sql_results']['table_dups']++; } elseif (!preg_match('~^\\s*CREATE( UNIQUE)? INDEX ([^\\n\\r]+?)~', $current_statement, $match) && !($db_type == 'postgresql' && preg_match('~^\\s*CREATE OPERATOR (^\\n\\r]+?)~', $current_statement, $match))) { $incontext['failures'][$count] = mysql_error($db_connection); } } else { if (preg_match('~^\\s*CREATE TABLE ([^\\s\\n\\r]+?)~', $current_statement, $match) == 1) { $incontext['sql_results']['tables']++; } else { preg_match_all('~\\)[,;]~', $current_statement, $matches); if (!empty($matches[0])) { $incontext['sql_results']['inserts'] += count($matches[0]); } else { $incontext['sql_results']['inserts']++; } } } $current_statement = ''; } // Sort out the context for the SQL. foreach ($incontext['sql_results'] as $key => $number) { if ($number == 0) { unset($incontext['sql_results'][$key]); } else { $incontext['sql_results'][$key] = sprintf($txt['db_populate_' . $key], $number); } } // Make sure UTF will be used globally. if (isset($_POST['utf8']) && !empty($databases[$db_type]['utf8_support'])) { smf_db_insert('replace', $db_prefix . 'settings', array('variable' => 'string-255', 'value' => 'string-65534'), array('global_character_set', 'UTF-8'), array('variable')); } // Maybe we can auto-detect better cookie settings? preg_match('~^http[s]?://([^\\.]+?)([^/]*?)(/.*)?$~', $boardurl, $matches); if (!empty($matches)) { // Default = both off. $localCookies = false; $globalCookies = false; // Okay... let's see. Using a subdomain other than www.? (not a perfect check.) if ($matches[2] != '' && (strpos(substr($matches[2], 1), '.') === false || in_array($matches[1], array('forum', 'board', 'community', 'forums', 'support', 'chat', 'help', 'talk', 'boards', 'www')))) { $globalCookies = true; } // If there's a / in the middle of the path, or it starts with ~... we want local. if (isset($matches[3]) && strlen($matches[3]) > 3 && (substr($matches[3], 0, 2) == '/~' || strpos(substr($matches[3], 1), '/') !== false)) { $localCookies = true; } $rows = array(); if ($globalCookies) { $rows[] = array('globalCookies', '1'); } if ($localCookies) { $rows[] = array('localCookies', '1'); } if (!empty($rows)) { smf_db_insert('replace', $db_prefix . 'settings', array('variable' => 'string-255', 'value' => 'string-65534'), $rows, array('variable')); } } // As of PHP 5.1, setting a timezone is required. if (!isset($modSettings['default_timezone'])) { $server_offset = mktime(0, 0, 0, 1, 1, 1970); $timezone_id = 'Etc/GMT' . ($server_offset > 0 ? '+' : '') . $server_offset / 3600; if (date_default_timezone_set($timezone_id)) { smf_db_insert('', $db_prefix . 'settings', array('variable' => 'string-255', 'value' => 'string-65534'), array('default_timezone', $timezone_id), array('variable')); } } // Let's optimize those new tables. db_extend(); $tables = smf_db_list_tables($db_name, $db_prefix . '%'); foreach ($tables as $table) { smf_db_optimize_table($table) != -1 or $db_messed = true; // Optimizing one sqlite table, optimizes them all if ($db_type == 'sqlite') { break; } if (!empty($db_messed)) { $incontext['failures'][-1] = mysql_error($db_connection); break; } } // Check for the ALTER privilege. if (!empty($databases[$db_type]['alter_support']) && smf_db_query("ALTER TABLE {$db_prefix}boards ORDER BY id_board", array('security_override' => true, 'db_error_skip' => true)) === false) { $incontext['error'] = $txt['error_db_alter_priv']; return false; } if (!empty($exists)) { $incontext['page_title'] = $txt['user_refresh_install']; $incontext['was_refresh'] = true; } return false; }
function OptimizeTables() { global $db_type, $db_name, $db_prefix, $txt, $context, $scripturl, $sourcedir, $smcFunc; isAllowedTo('admin_forum'); checkSession('post'); ignore_user_abort(true); db_extend(); // Start with no tables optimized. $opttab = 0; $context['page_title'] = $txt['database_optimize']; $context['sub_template'] = 'optimize'; // Only optimize the tables related to this smf install, not all the tables in the db $real_prefix = preg_match('~^(`?)(.+?)\\1\\.(.*?)$~', $db_prefix, $match) === 1 ? $match[3] : $db_prefix; // Get a list of tables, as well as how many there are. $temp_tables = smf_db_list_tables(false, $real_prefix . '%'); $tables = array(); foreach ($temp_tables as $table) { $tables[] = array('table_name' => $table); } // If there aren't any tables then I believe that would mean the world has exploded... $context['num_tables'] = count($tables); if ($context['num_tables'] == 0) { fatal_error('You appear to be running SMF in a flat file mode... fantastic!', false); } // For each table.... $context['optimized_tables'] = array(); foreach ($tables as $table) { // Optimize the table! We use backticks here because it might be a custom table. $data_freed = smf_db_optimize_table($table['table_name']); if ($data_freed > 0) { $context['optimized_tables'][] = array('name' => $table['table_name'], 'data_freed' => $data_freed); } } // Number of tables, etc.... $txt['database_numb_tables'] = sprintf($txt['database_numb_tables'], $context['num_tables']); $context['num_tables_optimized'] = count($context['optimized_tables']); // Check that we don't auto optimise again too soon! require_once $sourcedir . '/ScheduledTasks.php'; CalculateNextTrigger('auto_optimize', true); }