Blame Identity/Webenv/App/phpBB/3.0.4/install/database_update.php

f2e824
f2e824
/**
f2e824
*
f2e824
* @package install
f2e824
* @version $Id: database_update.php 9187 2008-12-12 14:47:03Z acydburn $
f2e824
* @copyright (c) 2006 phpBB Group
f2e824
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
f2e824
*
f2e824
*/
f2e824
f2e824
$updates_to_version = '3.0.4';
f2e824
f2e824
// Return if we "just include it" to find out for which version the database update is responsible for
f2e824
if (defined('IN_PHPBB') && defined('IN_INSTALL'))
f2e824
{
f2e824
	return;
f2e824
}
f2e824
f2e824
/**
f2e824
*/
f2e824
define('IN_PHPBB', true);
f2e824
define('IN_INSTALL', true);
f2e824
f2e824
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../';
f2e824
$phpEx = substr(strrchr(__FILE__, '.'), 1);
f2e824
f2e824
// Report all errors, except notices
f2e824
//error_reporting(E_ALL ^ E_NOTICE);
f2e824
error_reporting(E_ALL);
f2e824
f2e824
@set_time_limit(0);
f2e824
f2e824
// Include essential scripts
f2e824
include($phpbb_root_path . 'config.' . $phpEx);
f2e824
f2e824
if (!defined('PHPBB_INSTALLED') || empty($dbms) || empty($acm_type))
f2e824
{
f2e824
	die("Please read: INSTALL.html before attempting to update.");
f2e824
}
f2e824
f2e824
// Load Extensions
f2e824
if (!empty($load_extensions))
f2e824
{
f2e824
	$load_extensions = explode(',', $load_extensions);
f2e824
f2e824
	foreach ($load_extensions as $extension)
f2e824
	{
f2e824
		@dl(trim($extension));
f2e824
	}
f2e824
}
f2e824
f2e824
// Include files
f2e824
require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx);
f2e824
require($phpbb_root_path . 'includes/cache.' . $phpEx);
f2e824
require($phpbb_root_path . 'includes/template.' . $phpEx);
f2e824
require($phpbb_root_path . 'includes/session.' . $phpEx);
f2e824
require($phpbb_root_path . 'includes/auth.' . $phpEx);
f2e824
f2e824
require($phpbb_root_path . 'includes/functions.' . $phpEx);
f2e824
f2e824
if (file_exists($phpbb_root_path . 'includes/functions_content.' . $phpEx))
f2e824
{
f2e824
	require($phpbb_root_path . 'includes/functions_content.' . $phpEx);
f2e824
}
f2e824
f2e824
require($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
f2e824
require($phpbb_root_path . 'includes/constants.' . $phpEx);
f2e824
require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
f2e824
require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
f2e824
f2e824
// If we are on PHP >= 6.0.0 we do not need some code
f2e824
if (version_compare(PHP_VERSION, '6.0.0-dev', '>='))
f2e824
{
f2e824
	/**
f2e824
	* @ignore
f2e824
	*/
f2e824
	define('STRIP', false);
f2e824
}
f2e824
else
f2e824
{
f2e824
	@set_magic_quotes_runtime(0);
f2e824
	define('STRIP', (get_magic_quotes_gpc()) ? true : false);
f2e824
}
f2e824
f2e824
$user = new user();
f2e824
$cache = new cache();
f2e824
$db = new $sql_db();
f2e824
f2e824
// Add own hook handler, if present. :o
f2e824
if (file_exists($phpbb_root_path . 'includes/hooks/index.' . $phpEx))
f2e824
{
f2e824
	require($phpbb_root_path . 'includes/hooks/index.' . $phpEx);
f2e824
	$phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display')));
f2e824
f2e824
	foreach ($cache->obtain_hooks() as $hook)
f2e824
	{
f2e824
		@include($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx);
f2e824
	}
f2e824
}
f2e824
else
f2e824
{
f2e824
	$phpbb_hook = false;
f2e824
}
f2e824
f2e824
// Connect to DB
f2e824
$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false);
f2e824
f2e824
// We do not need this any longer, unset for safety purposes
f2e824
unset($dbpasswd);
f2e824
f2e824
$user->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
f2e824
f2e824
$sql = "SELECT config_value
f2e824
	FROM " . CONFIG_TABLE . "
f2e824
	WHERE config_name = 'default_lang'";
f2e824
$result = $db->sql_query($sql);
f2e824
$row = $db->sql_fetchrow($result);
f2e824
$db->sql_freeresult($result);
f2e824
f2e824
$language = basename(request_var('language', ''));
f2e824
f2e824
if (!$language)
f2e824
{
f2e824
	$language = $row['config_value'];
f2e824
}
f2e824
f2e824
if (!file_exists($phpbb_root_path . 'language/' . $language))
f2e824
{
f2e824
	die('No language found!');
f2e824
}
f2e824
f2e824
// And finally, load the relevant language files
f2e824
include($phpbb_root_path . 'language/' . $language . '/common.' . $phpEx);
f2e824
include($phpbb_root_path . 'language/' . $language . '/acp/common.' . $phpEx);
f2e824
include($phpbb_root_path . 'language/' . $language . '/install.' . $phpEx);
f2e824
f2e824
// Set PHP error handler to ours
f2e824
//set_error_handler('msg_handler');
f2e824
f2e824
// Define some variables for the database update
f2e824
$inline_update = (request_var('type', 0)) ? true : false;
f2e824
f2e824
// Database column types mapping
f2e824
$dbms_type_map = array(
f2e824
	'mysql_41'	=> array(
f2e824
		'INT:'		=> 'int(%d)',
f2e824
		'BINT'		=> 'bigint(20)',
f2e824
		'UINT'		=> 'mediumint(8) UNSIGNED',
f2e824
		'UINT:'		=> 'int(%d) UNSIGNED',
f2e824
		'TINT:'		=> 'tinyint(%d)',
f2e824
		'USINT'		=> 'smallint(4) UNSIGNED',
f2e824
		'BOOL'		=> 'tinyint(1) UNSIGNED',
f2e824
		'VCHAR'		=> 'varchar(255)',
f2e824
		'VCHAR:'	=> 'varchar(%d)',
f2e824
		'CHAR:'		=> 'char(%d)',
f2e824
		'XSTEXT'	=> 'text',
f2e824
		'XSTEXT_UNI'=> 'varchar(100)',
f2e824
		'STEXT'		=> 'text',
f2e824
		'STEXT_UNI'	=> 'varchar(255)',
f2e824
		'TEXT'		=> 'text',
f2e824
		'TEXT_UNI'	=> 'text',
f2e824
		'MTEXT'		=> 'mediumtext',
f2e824
		'MTEXT_UNI'	=> 'mediumtext',
f2e824
		'TIMESTAMP'	=> 'int(11) UNSIGNED',
f2e824
		'DECIMAL'	=> 'decimal(5,2)',
f2e824
		'VCHAR_UNI'	=> 'varchar(255)',
f2e824
		'VCHAR_UNI:'=> 'varchar(%d)',
f2e824
		'VCHAR_CI'	=> 'varchar(255)',
f2e824
		'VARBINARY'	=> 'varbinary(255)',
f2e824
	),
f2e824
f2e824
	'mysql_40'	=> array(
f2e824
		'INT:'		=> 'int(%d)',
f2e824
		'BINT'		=> 'bigint(20)',
f2e824
		'UINT'		=> 'mediumint(8) UNSIGNED',
f2e824
		'UINT:'		=> 'int(%d) UNSIGNED',
f2e824
		'TINT:'		=> 'tinyint(%d)',
f2e824
		'USINT'		=> 'smallint(4) UNSIGNED',
f2e824
		'BOOL'		=> 'tinyint(1) UNSIGNED',
f2e824
		'VCHAR'		=> 'varbinary(255)',
f2e824
		'VCHAR:'	=> 'varbinary(%d)',
f2e824
		'CHAR:'		=> 'binary(%d)',
f2e824
		'XSTEXT'	=> 'blob',
f2e824
		'XSTEXT_UNI'=> 'blob',
f2e824
		'STEXT'		=> 'blob',
f2e824
		'STEXT_UNI'	=> 'blob',
f2e824
		'TEXT'		=> 'blob',
f2e824
		'TEXT_UNI'	=> 'blob',
f2e824
		'MTEXT'		=> 'mediumblob',
f2e824
		'MTEXT_UNI'	=> 'mediumblob',
f2e824
		'TIMESTAMP'	=> 'int(11) UNSIGNED',
f2e824
		'DECIMAL'	=> 'decimal(5,2)',
f2e824
		'VCHAR_UNI'	=> 'blob',
f2e824
		'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')),
f2e824
		'VCHAR_CI'	=> 'blob',
f2e824
		'VARBINARY'	=> 'varbinary(255)',
f2e824
	),
f2e824
f2e824
	'firebird'	=> array(
f2e824
		'INT:'		=> 'INTEGER',
f2e824
		'BINT'		=> 'DOUBLE PRECISION',
f2e824
		'UINT'		=> 'INTEGER',
f2e824
		'UINT:'		=> 'INTEGER',
f2e824
		'TINT:'		=> 'INTEGER',
f2e824
		'USINT'		=> 'INTEGER',
f2e824
		'BOOL'		=> 'INTEGER',
f2e824
		'VCHAR'		=> 'VARCHAR(255) CHARACTER SET NONE',
f2e824
		'VCHAR:'	=> 'VARCHAR(%d) CHARACTER SET NONE',
f2e824
		'CHAR:'		=> 'CHAR(%d) CHARACTER SET NONE',
f2e824
		'XSTEXT'	=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
f2e824
		'STEXT'		=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
f2e824
		'TEXT'		=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
f2e824
		'MTEXT'		=> 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
f2e824
		'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8',
f2e824
		'STEXT_UNI'	=> 'VARCHAR(255) CHARACTER SET UTF8',
f2e824
		'TEXT_UNI'	=> 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
f2e824
		'MTEXT_UNI'	=> 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
f2e824
		'TIMESTAMP'	=> 'INTEGER',
f2e824
		'DECIMAL'	=> 'DOUBLE PRECISION',
f2e824
		'VCHAR_UNI'	=> 'VARCHAR(255) CHARACTER SET UTF8',
f2e824
		'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8',
f2e824
		'VCHAR_CI'	=> 'VARCHAR(255) CHARACTER SET UTF8',
f2e824
		'VARBINARY'	=> 'CHAR(255) CHARACTER SET NONE',
f2e824
	),
f2e824
f2e824
	'mssql'		=> array(
f2e824
		'INT:'		=> '[int]',
f2e824
		'BINT'		=> '[float]',
f2e824
		'UINT'		=> '[int]',
f2e824
		'UINT:'		=> '[int]',
f2e824
		'TINT:'		=> '[int]',
f2e824
		'USINT'		=> '[int]',
f2e824
		'BOOL'		=> '[int]',
f2e824
		'VCHAR'		=> '[varchar] (255)',
f2e824
		'VCHAR:'	=> '[varchar] (%d)',
f2e824
		'CHAR:'		=> '[char] (%d)',
f2e824
		'XSTEXT'	=> '[varchar] (1000)',
f2e824
		'STEXT'		=> '[varchar] (3000)',
f2e824
		'TEXT'		=> '[varchar] (8000)',
f2e824
		'MTEXT'		=> '[text]',
f2e824
		'XSTEXT_UNI'=> '[varchar] (100)',
f2e824
		'STEXT_UNI'	=> '[varchar] (255)',
f2e824
		'TEXT_UNI'	=> '[varchar] (4000)',
f2e824
		'MTEXT_UNI'	=> '[text]',
f2e824
		'TIMESTAMP'	=> '[int]',
f2e824
		'DECIMAL'	=> '[float]',
f2e824
		'VCHAR_UNI'	=> '[varchar] (255)',
f2e824
		'VCHAR_UNI:'=> '[varchar] (%d)',
f2e824
		'VCHAR_CI'	=> '[varchar] (255)',
f2e824
		'VARBINARY'	=> '[varchar] (255)',
f2e824
	),
f2e824
f2e824
	'oracle'	=> array(
f2e824
		'INT:'		=> 'number(%d)',
f2e824
		'BINT'		=> 'number(20)',
f2e824
		'UINT'		=> 'number(8)',
f2e824
		'UINT:'		=> 'number(%d)',
f2e824
		'TINT:'		=> 'number(%d)',
f2e824
		'USINT'		=> 'number(4)',
f2e824
		'BOOL'		=> 'number(1)',
f2e824
		'VCHAR'		=> 'varchar2(255)',
f2e824
		'VCHAR:'	=> 'varchar2(%d)',
f2e824
		'CHAR:'		=> 'char(%d)',
f2e824
		'XSTEXT'	=> 'varchar2(1000)',
f2e824
		'STEXT'		=> 'varchar2(3000)',
f2e824
		'TEXT'		=> 'clob',
f2e824
		'MTEXT'		=> 'clob',
f2e824
		'XSTEXT_UNI'=> 'varchar2(300)',
f2e824
		'STEXT_UNI'	=> 'varchar2(765)',
f2e824
		'TEXT_UNI'	=> 'clob',
f2e824
		'MTEXT_UNI'	=> 'clob',
f2e824
		'TIMESTAMP'	=> 'number(11)',
f2e824
		'DECIMAL'	=> 'number(5, 2)',
f2e824
		'VCHAR_UNI'	=> 'varchar2(765)',
f2e824
		'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')),
f2e824
		'VCHAR_CI'	=> 'varchar2(255)',
f2e824
		'VARBINARY'	=> 'raw(255)',
f2e824
	),
f2e824
f2e824
	'sqlite'	=> array(
f2e824
		'INT:'		=> 'int(%d)',
f2e824
		'BINT'		=> 'bigint(20)',
f2e824
		'UINT'		=> 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED',
f2e824
		'UINT:'		=> 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED',
f2e824
		'TINT:'		=> 'tinyint(%d)',
f2e824
		'USINT'		=> 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED',
f2e824
		'BOOL'		=> 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED',
f2e824
		'VCHAR'		=> 'varchar(255)',
f2e824
		'VCHAR:'	=> 'varchar(%d)',
f2e824
		'CHAR:'		=> 'char(%d)',
f2e824
		'XSTEXT'	=> 'text(65535)',
f2e824
		'STEXT'		=> 'text(65535)',
f2e824
		'TEXT'		=> 'text(65535)',
f2e824
		'MTEXT'		=> 'mediumtext(16777215)',
f2e824
		'XSTEXT_UNI'=> 'text(65535)',
f2e824
		'STEXT_UNI'	=> 'text(65535)',
f2e824
		'TEXT_UNI'	=> 'text(65535)',
f2e824
		'MTEXT_UNI'	=> 'mediumtext(16777215)',
f2e824
		'TIMESTAMP'	=> 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
f2e824
		'DECIMAL'	=> 'decimal(5,2)',
f2e824
		'VCHAR_UNI'	=> 'varchar(255)',
f2e824
		'VCHAR_UNI:'=> 'varchar(%d)',
f2e824
		'VCHAR_CI'	=> 'varchar(255)',
f2e824
		'VARBINARY'	=> 'blob',
f2e824
	),
f2e824
f2e824
	'postgres'	=> array(
f2e824
		'INT:'		=> 'INT4',
f2e824
		'BINT'		=> 'INT8',
f2e824
		'UINT'		=> 'INT4', // unsigned
f2e824
		'UINT:'		=> 'INT4', // unsigned
f2e824
		'USINT'		=> 'INT2', // unsigned
f2e824
		'BOOL'		=> 'INT2', // unsigned
f2e824
		'TINT:'		=> 'INT2',
f2e824
		'VCHAR'		=> 'varchar(255)',
f2e824
		'VCHAR:'	=> 'varchar(%d)',
f2e824
		'CHAR:'		=> 'char(%d)',
f2e824
		'XSTEXT'	=> 'varchar(1000)',
f2e824
		'STEXT'		=> 'varchar(3000)',
f2e824
		'TEXT'		=> 'varchar(8000)',
f2e824
		'MTEXT'		=> 'TEXT',
f2e824
		'XSTEXT_UNI'=> 'varchar(100)',
f2e824
		'STEXT_UNI'	=> 'varchar(255)',
f2e824
		'TEXT_UNI'	=> 'varchar(4000)',
f2e824
		'MTEXT_UNI'	=> 'TEXT',
f2e824
		'TIMESTAMP'	=> 'INT4', // unsigned
f2e824
		'DECIMAL'	=> 'decimal(5,2)',
f2e824
		'VCHAR_UNI'	=> 'varchar(255)',
f2e824
		'VCHAR_UNI:'=> 'varchar(%d)',
f2e824
		'VCHAR_CI'	=> 'varchar_ci',
f2e824
		'VARBINARY'	=> 'bytea',
f2e824
	),
f2e824
);
f2e824
f2e824
// A list of types being unsigned for better reference in some db's
f2e824
$unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP');
f2e824
f2e824
// Only an example, but also commented out
f2e824
$database_update_info = array(
f2e824
	// Changes from 3.0.RC2 to the next version
f2e824
	'3.0.RC2'			=> array(
f2e824
		// Change the following columns
f2e824
		'change_columns'		=> array(
f2e824
			BANLIST_TABLE	=> array(
f2e824
				'ban_reason'		=> array('VCHAR_UNI', ''),
f2e824
				'ban_give_reason'	=> array('VCHAR_UNI', ''),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
	// Changes from 3.0.RC3 to the next version
f2e824
	'3.0.RC3'			=> array(
f2e824
		// Change the following columns
f2e824
		'change_columns'		=> array(
f2e824
			BANLIST_TABLE				=> array(
f2e824
				'ban_reason'		=> array('VCHAR_UNI', ''),
f2e824
				'ban_give_reason'	=> array('VCHAR_UNI', ''),
f2e824
			),
f2e824
			STYLES_TABLE				=> array(
f2e824
				'style_id'			=> array('USINT', 0),
f2e824
				'template_id'		=> array('USINT', 0),
f2e824
				'theme_id'			=> array('USINT', 0),
f2e824
				'imageset_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			STYLES_TEMPLATE_TABLE		=> array(
f2e824
				'template_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			STYLES_TEMPLATE_DATA_TABLE	=> array(
f2e824
				'template_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			STYLES_THEME_TABLE			=> array(
f2e824
				'theme_id'			=> array('USINT', 0),
f2e824
			),
f2e824
			STYLES_IMAGESET_TABLE		=> array(
f2e824
				'imageset_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			STYLES_IMAGESET_DATA_TABLE	=> array(
f2e824
				'imageset_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			USERS_TABLE	=> array(
f2e824
				'user_style'		=> array('USINT', 0),
f2e824
			),
f2e824
			FORUMS_TABLE				=> array(
f2e824
				'forum_style'		=> array('USINT', 0),
f2e824
			),
f2e824
			GROUPS_TABLE			=> array(
f2e824
				'group_avatar_type'		=> array('TINT:2', 0),
f2e824
				'group_avatar_width'	=> array('USINT', 0),
f2e824
				'group_avatar_height'	=> array('USINT', 0),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
	// Changes from 3.0.RC4 to the next version
f2e824
	'3.0.RC4'			=> array(
f2e824
		// Change the following columns
f2e824
		'change_columns'		=> array(
f2e824
			STYLES_TABLE				=> array(
f2e824
				'style_id'			=> array('USINT', NULL, 'auto_increment'),
f2e824
				'template_id'		=> array('USINT', 0),
f2e824
				'theme_id'			=> array('USINT', 0),
f2e824
				'imageset_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			STYLES_TEMPLATE_TABLE		=> array(
f2e824
				'template_id'		=> array('USINT', NULL, 'auto_increment'),
f2e824
			),
f2e824
			STYLES_TEMPLATE_DATA_TABLE	=> array(
f2e824
				'template_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			STYLES_THEME_TABLE			=> array(
f2e824
				'theme_id'			=> array('USINT', NULL, 'auto_increment'),
f2e824
			),
f2e824
			STYLES_IMAGESET_TABLE		=> array(
f2e824
				'imageset_id'		=> array('USINT', NULL, 'auto_increment'),
f2e824
			),
f2e824
			STYLES_IMAGESET_DATA_TABLE	=> array(
f2e824
				'imageset_id'		=> array('USINT', 0),
f2e824
			),
f2e824
			USERS_TABLE	=> array(
f2e824
				'user_style'		=> array('USINT', 0),
f2e824
			),
f2e824
			FORUMS_TABLE				=> array(
f2e824
				'forum_style'		=> array('USINT', 0),
f2e824
			),
f2e824
			GROUPS_TABLE			=> array(
f2e824
				'group_avatar_width'	=> array('USINT', 0),
f2e824
				'group_avatar_height'	=> array('USINT', 0),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
	// Changes from 3.0.RC5 to the next version
f2e824
	'3.0.RC5'			=> array(
f2e824
		// Add the following columns
f2e824
		'add_columns'		=> array(
f2e824
			USERS_TABLE	=> array(
f2e824
				'user_form_salt'	=> array('VCHAR_UNI:32', ''),
f2e824
			),
f2e824
		),
f2e824
		// Change the following columns
f2e824
		'change_columns'		=> array(
f2e824
			POSTS_TABLE				=> array(
f2e824
				'bbcode_uid'			=> array('VCHAR:8', ''),
f2e824
			),
f2e824
			PRIVMSGS_TABLE		=> array(
f2e824
				'bbcode_uid'			=> array('VCHAR:8', ''),
f2e824
			),
f2e824
			USERS_TABLE			=> array(
f2e824
				'user_sig_bbcode_uid'	=> array('VCHAR:8', ''),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
	// Changes from 3.0.RC6 to the next version
f2e824
	'3.0.RC6'			=> array(
f2e824
		// Change the following columns
f2e824
		'change_columns'		=> array(
f2e824
			FORUMS_TABLE				=> array(
f2e824
				'forum_desc_uid'		=> array('VCHAR:8', ''),
f2e824
				'forum_rules_uid'		=> array('VCHAR:8', ''),
f2e824
			),
f2e824
			GROUPS_TABLE		=> array(
f2e824
				'group_desc_uid'		=> array('VCHAR:8', ''),
f2e824
			),
f2e824
			USERS_TABLE			=> array(
f2e824
				'user_newpasswd'			=> array('VCHAR_UNI:40', ''),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
	// Changes from 3.0.RC8 to the next version
f2e824
	'3.0.RC8'			=> array(
f2e824
		// Change the following columns
f2e824
		'change_columns'		=> array(
f2e824
			USERS_TABLE			=> array(
f2e824
				'user_new_privmsg'			=> array('INT:4', 0),
f2e824
				'user_unread_privmsg'		=> array('INT:4', 0),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
	// Changes from 3.0.0 to the next version
f2e824
	'3.0.0'			=> array(
f2e824
		// Add the following columns
f2e824
		'add_columns'		=> array(
f2e824
			FORUMS_TABLE			=> array(
f2e824
				'display_subforum_list'		=> array('BOOL', 1),
f2e824
			),
f2e824
			SESSIONS_TABLE			=> array(
f2e824
				'session_forum_id'		=> array('UINT', 0),
f2e824
			),
f2e824
		),
f2e824
		'add_index'		=> array(
f2e824
			SESSIONS_TABLE			=> array(
f2e824
				'session_forum_id'		=> array('session_forum_id'),
f2e824
			),
f2e824
			GROUPS_TABLE			=> array(
f2e824
				'group_legend_name'		=> array('group_legend', 'group_name'),
f2e824
			),
f2e824
		),
f2e824
		'drop_keys'		=> array(
f2e824
			GROUPS_TABLE			=> array('group_legend'),
f2e824
		),
f2e824
	),
f2e824
	// No changes from 3.0.1-RC1 to 3.0.1
f2e824
	'3.0.1-RC1'		=> array(),
f2e824
	// No changes from 3.0.1 to 3.0.2-RC1
f2e824
	'3.0.1'			=> array(),
f2e824
	// Changes from 3.0.2-RC1 to 3.0.2-RC2
f2e824
	'3.0.2-RC1'		=> array(
f2e824
		'change_columns'	=> array(
f2e824
			DRAFTS_TABLE			=> array(
f2e824
				'draft_subject'		=> array('STEXT_UNI', ''),
f2e824
			),
f2e824
			FORUMS_TABLE	=> array(
f2e824
				'forum_last_post_subject' => array('STEXT_UNI', ''),
f2e824
			),
f2e824
			POSTS_TABLE		=> array(
f2e824
				'post_subject'			=> array('STEXT_UNI', '', 'true_sort'),
f2e824
			),
f2e824
			PRIVMSGS_TABLE	=> array(
f2e824
				'message_subject'		=> array('STEXT_UNI', ''),
f2e824
			),
f2e824
			TOPICS_TABLE	=> array(
f2e824
				'topic_title'				=> array('STEXT_UNI', '', 'true_sort'),
f2e824
				'topic_last_post_subject'	=> array('STEXT_UNI', ''),
f2e824
			),
f2e824
		),
f2e824
		'drop_keys'		=> array(
f2e824
			SESSIONS_TABLE			=> array('session_forum_id'),
f2e824
		),
f2e824
		'add_index'		=> array(
f2e824
			SESSIONS_TABLE			=> array(
f2e824
				'session_fid'		=> array('session_forum_id'),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
	// No changes from 3.0.2-RC2 to 3.0.2
f2e824
	'3.0.2-RC2'		=> array(),
f2e824
f2e824
	// Changes from 3.0.2 to 3.0.3-RC1
f2e824
	'3.0.2'			=> array(
f2e824
		// Add the following columns
f2e824
		'add_columns'		=> array(
f2e824
			STYLES_TEMPLATE_TABLE			=> array(
f2e824
				'template_inherits_id'		=> array('UINT:4', 0),
f2e824
				'template_inherit_path'		=> array('VCHAR', ''),
f2e824
			),
f2e824
			GROUPS_TABLE					=> array(
f2e824
				'group_max_recipients'		=> array('UINT', 0),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
f2e824
	// No changes from 3.0.3-RC1 to 3.0.3
f2e824
	'3.0.3-RC1'		=> array(),
f2e824
f2e824
	// Changes from 3.0.3 to 3.0.4-RC1
f2e824
	'3.0.3'			=> array(
f2e824
		'add_columns'		=> array(
f2e824
			PROFILE_FIELDS_TABLE			=> array(
f2e824
				'field_show_profile'		=> array('BOOL', 0),
f2e824
			),
f2e824
		),
f2e824
		'change_columns'	=> array(
f2e824
			STYLES_TABLE				=> array(
f2e824
				'style_id'				=> array('UINT', NULL, 'auto_increment'),
f2e824
				'template_id'			=> array('UINT', 0),
f2e824
				'theme_id'				=> array('UINT', 0),
f2e824
				'imageset_id'			=> array('UINT', 0),
f2e824
			),
f2e824
			STYLES_IMAGESET_TABLE		=> array(
f2e824
				'imageset_id'				=> array('UINT', NULL, 'auto_increment'),
f2e824
			),
f2e824
			STYLES_IMAGESET_DATA_TABLE	=> array(
f2e824
				'image_id'				=> array('UINT', NULL, 'auto_increment'),
f2e824
				'imageset_id'			=> array('UINT', 0),
f2e824
			),
f2e824
			STYLES_THEME_TABLE			=> array(
f2e824
				'theme_id'				=> array('UINT', NULL, 'auto_increment'),
f2e824
			),
f2e824
			STYLES_TEMPLATE_TABLE		=> array(
f2e824
				'template_id'			=> array('UINT', NULL, 'auto_increment'),
f2e824
			),
f2e824
			STYLES_TEMPLATE_DATA_TABLE	=> array(
f2e824
				'template_id'			=> array('UINT', 0),
f2e824
			),
f2e824
			FORUMS_TABLE				=> array(
f2e824
				'forum_style'			=> array('USINT', 0),
f2e824
			),
f2e824
			USERS_TABLE					=> array(
f2e824
				'user_style'			=> array('UINT', 0),
f2e824
			),
f2e824
		),
f2e824
	),
f2e824
f2e824
	// Changes from 3.0.4-RC1 to 3.0.4
f2e824
	'3.0.4-RC1'		=> array(),
f2e824
);
f2e824
f2e824
// Determine mapping database type
f2e824
switch ($db->sql_layer)
f2e824
{
f2e824
	case 'mysql':
f2e824
		$map_dbms = 'mysql_40';
f2e824
	break;
f2e824
f2e824
	case 'mysql4':
f2e824
		if (version_compare($db->sql_server_info(true), '4.1.3', '>='))
f2e824
		{
f2e824
			$map_dbms = 'mysql_41';
f2e824
		}
f2e824
		else
f2e824
		{
f2e824
			$map_dbms = 'mysql_40';
f2e824
		}
f2e824
	break;
f2e824
f2e824
	case 'mysqli':
f2e824
		$map_dbms = 'mysql_41';
f2e824
	break;
f2e824
f2e824
	case 'mssql':
f2e824
	case 'mssql_odbc':
f2e824
		$map_dbms = 'mssql';
f2e824
	break;
f2e824
f2e824
	default:
f2e824
		$map_dbms = $db->sql_layer;
f2e824
	break;
f2e824
}
f2e824
f2e824
$error_ary = array();
f2e824
$errored = false;
f2e824
f2e824
header('Content-type: text/html; charset=UTF-8');
f2e824
f2e824
?>
f2e824
f2e824
<html xmlns="http://www.w3.org/1999/xhtml" dir="<?php echo $lang['DIRECTION']; ?>" lang="<?php echo $lang['USER_LANG']; ?>" xml:lang="<?php echo $lang['USER_LANG']; ?>">
f2e824
<head>
f2e824
f2e824
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
f2e824
<meta http-equiv="content-language" content="<?php echo $lang['USER_LANG']; ?>" />
f2e824
<meta http-equiv="content-style-type" content="text/css" />
f2e824
<meta http-equiv="imagetoolbar" content="no" />
f2e824
f2e824
<title></title>
f2e824
f2e824
<link href="../adm/style/admin.css" rel="stylesheet" type="text/css" media="screen" />
f2e824
f2e824
</head>
f2e824
f2e824
<body>
f2e824
f2e824
	
f2e824
f2e824
	
f2e824
		
f2e824
		
f2e824
			
f2e824
				
f2e824
					
f2e824
f2e824
	

f2e824
f2e824
	
f2e824
f2e824
	

:: sql_layer; ?>

f2e824
f2e824
f2e824
// To let set_config() calls succeed, we need to make the config array available globally
f2e824
$config = array();
f2e824
$sql = 'SELECT *
f2e824
	FROM ' . CONFIG_TABLE;
f2e824
$result = $db->sql_query($sql);
f2e824
f2e824
while ($row = $db->sql_fetchrow($result))
f2e824
{
f2e824
	$config[$row['config_name']] = $row['config_value'];
f2e824
}
f2e824
$db->sql_freeresult($result);
f2e824
f2e824
/*if ($debug_from_version !== false)
f2e824
{
f2e824
	$config['version'] = $debug_from_version;
f2e824
}*/
f2e824
f2e824
echo $lang['PREVIOUS_VERSION'] . ' :: ' . $config['version'] . '
';
f2e824
echo $lang['UPDATED_VERSION'] . ' :: ' . $updates_to_version . '

';
f2e824
f2e824
$current_version = str_replace('rc', 'RC', strtolower($config['version']));
f2e824
$latest_version = str_replace('rc', 'RC', strtolower($updates_to_version));
f2e824
$orig_version = $config['version'];
f2e824
f2e824
// If the latest version and the current version are 'unequal', we will update the version_update_from, else we do not update anything.
f2e824
if ($inline_update)
f2e824
{
f2e824
	if ($current_version !== $latest_version)
f2e824
	{
f2e824
		set_config('version_update_from', $orig_version);
f2e824
	}
f2e824
}
f2e824
else
f2e824
{
f2e824
	// If not called from the update script, we will actually remove the traces
f2e824
	$db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'");
f2e824
}
f2e824
f2e824
// Checks/Operations that have to be completed prior to starting the update itself
f2e824
$exit = false;
f2e824
if (version_compare($current_version, '3.0.RC8', '<=')) /* && $debug_from_version === false) */
f2e824
{
f2e824
	// Define missing language entries...
f2e824
	if (!isset($lang['CLEANING_USERNAMES']))
f2e824
	{
f2e824
		$lang = array_merge($lang, array(
f2e824
			'CLEANING_USERNAMES'		=> 'Cleaning usernames',
f2e824
			'LONG_SCRIPT_EXECUTION'		=> 'Please note that this can take a while... Please do not stop the script.',
f2e824
			'CHANGE_CLEAN_NAMES'		=> 'The method used to make sure a username is not used by multiple users has been changed. There are some users which have the same name when compared with the new method. You have to delete or rename these users to make sure that each name is only used by one user before you can proceed.',
f2e824
			'USER_ACTIVE'				=> 'Active user',
f2e824
			'USER_INACTIVE'				=> 'Inactive user',
f2e824
			'BOT'						=> 'Spider/Robot',
f2e824
			'UPDATE_REQUIRES_FILE'		=> 'The updater requires that the following file is present: %s',
f2e824
f2e824
			'DELETE_USER_REMOVE'		=> 'Delete user and remove posts',
f2e824
			'DELETE_USER_RETAIN'		=> 'Delete user but keep posts',
f2e824
			'EDIT_USERNAME'				=> 'Edit username',
f2e824
			'KEEP_OLD_NAME'				=> 'Keep username',
f2e824
			'NEW_USERNAME'				=> 'New username',
f2e824
		));
f2e824
	}
f2e824
?>
f2e824
	

f2e824
f2e824
	

f2e824
f2e824
	
f2e824
f2e824
f2e824
	flush();
f2e824
f2e824
	$submit			= (isset($_POST['resolve_conflicts'])) ? true : false;
f2e824
	$modify_users	= request_var('modify_users', array(0 => ''));
f2e824
	$new_usernames	= request_var('new_usernames', array(0 => ''), true);
f2e824
f2e824
	// We need this file if someone wants to edit usernames.
f2e824
	include($phpbb_root_path . 'includes/utf/utf_normalizer.' . $phpEx);
f2e824
f2e824
	if (!class_exists('utf_new_normalizer'))
f2e824
	{
f2e824
		if (!file_exists($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx))
f2e824
		{
f2e824
			global $lang;
f2e824
			trigger_error(sprintf($lang['UPDATE_REQUIRES_FILE'], $phpbb_root_path . 'install/data/new_normalizer.' . $phpEx), E_USER_ERROR);
f2e824
		}
f2e824
		include($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx);
f2e824
	}
f2e824
f2e824
	// the admin decided to change some usernames
f2e824
	if (sizeof($modify_users) && $submit)
f2e824
	{
f2e824
		$sql = 'SELECT user_id, username, user_type
f2e824
			FROM ' . USERS_TABLE . '
f2e824
			WHERE ' . $db->sql_in_set('user_id', array_keys($modify_users));
f2e824
		$result = $db->sql_query($sql);
f2e824
f2e824
		$users = 0;
f2e824
		while ($row = $db->sql_fetchrow($result))
f2e824
		{
f2e824
			$users++;
f2e824
			$user_id = (int) $row['user_id'];
f2e824
f2e824
			if (isset($modify_users[$user_id]))
f2e824
			{
f2e824
				$row['action'] = $modify_users[$user_id];
f2e824
				$modify_users[$user_id] = $row;
f2e824
			}
f2e824
		}
f2e824
		$db->sql_freeresult($result);
f2e824
f2e824
		// only if all ids really existed
f2e824
		if (sizeof($modify_users) == $users)
f2e824
		{
f2e824
			$user->data['user_id'] = ANONYMOUS;
f2e824
			include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
f2e824
			foreach ($modify_users as $user_id => $row)
f2e824
			{
f2e824
				switch ($row['action'])
f2e824
				{
f2e824
					case 'edit':
f2e824
						if (isset($new_usernames[$user_id]))
f2e824
						{
f2e824
							$data = array('username' => utf8_new_normalize_nfc($new_usernames[$user_id]));
f2e824
							// Need to update config, forum, topic, posting, messages, etc.
f2e824
							if ($data['username'] != $row['username'])
f2e824
							{
f2e824
								$check_ary = array('username' => array(
f2e824
									array('string', false, $config['min_name_chars'], $config['max_name_chars']),
f2e824
									array('username'),
f2e824
								));
f2e824
								// need a little trick for this to work properly
f2e824
								$user->data['username_clean'] = utf8_clean_string($data['username']) . 'a';
f2e824
								$errors = validate_data($data, $check_ary);
f2e824
f2e824
								if ($errors)
f2e824
								{
f2e824
									include($phpbb_root_path . 'language/' . $language . '/ucp.' . $phpEx);
f2e824
									echo '
';
f2e824
									foreach ($errors as $error)
f2e824
									{
f2e824
										echo '

' . $lang[$error] . '

';
f2e824
									}
f2e824
									echo '';
f2e824
								}
f2e824
f2e824
								if (!$errors)
f2e824
								{
f2e824
									$sql = 'UPDATE ' . USERS_TABLE . '
f2e824
										SET ' . $db->sql_build_array('UPDATE', array(
f2e824
												'username' => $data['username'],
f2e824
												'username_clean' => utf8_clean_string($data['username'])
f2e824
											)) . '
f2e824
										WHERE user_id = ' . $user_id;
f2e824
									$db->sql_query($sql);
f2e824
f2e824
									add_log('user', $user_id, 'LOG_USER_UPDATE_NAME', $row['username'], $data['username']);
f2e824
									user_update_name($row['username'], $data['username']);
f2e824
								}
f2e824
							}
f2e824
						}
f2e824
					break;
f2e824
f2e824
					case 'delete_retain':
f2e824
					case 'delete_remove':
f2e824
						if ($user_id != ANONYMOUS && $row['user_type'] != USER_FOUNDER)
f2e824
						{
f2e824
							user_delete(substr($row['action'], 7), $user_id, $row['username']);
f2e824
							add_log('admin', 'LOG_USER_DELETED', $row['username']);
f2e824
						}
f2e824
					break;
f2e824
				}
f2e824
			}
f2e824
		}
f2e824
	}
f2e824
?>
f2e824
f2e824
	

f2e824
	

::

f2e824
f2e824
f2e824
	flush();
f2e824
f2e824
	// after RC3 a different utf8_clean_string function is used, this requires that
f2e824
	// the unique column username_clean is recalculated, during this recalculation
f2e824
	// duplicates might be created. Since the column has to be unique such usernames
f2e824
	// must not exist. We need identify them and let the admin decide what to do
f2e824
	// about them.
f2e824
	// After RC8 this was changed again, but this time only usernames containing spaces
f2e824
	// are affected.
f2e824
	$sql_where = (version_compare($current_version, '3.0.RC4', '<=')) ? '' : "WHERE username_clean LIKE '% %'";
f2e824
	$sql = 'SELECT user_id, username, username_clean
f2e824
		FROM ' . USERS_TABLE . "
f2e824
		$sql_where
f2e824
		ORDER BY user_id ASC";
f2e824
	$result = $db->sql_query($sql);
f2e824
f2e824
	$colliding_users = $found_names = array();
f2e824
	$echos = 0;
f2e824
f2e824
	while ($row = $db->sql_fetchrow($result))
f2e824
	{
f2e824
		// Calculate the new clean name. If it differs from the old one we need
f2e824
		// to make sure there is no collision
f2e824
		$clean_name = utf8_new_clean_string($row['username']);
f2e824
f2e824
		if ($clean_name != $row['username_clean'])
f2e824
		{
f2e824
			// Check if there would be a collission, if not put it up for changing
f2e824
			$user_id = (int) $row['user_id'];
f2e824
f2e824
			// If this clean name was not the result of another user already ...
f2e824
			if (!isset($found_names[$clean_name]))
f2e824
			{
f2e824
				// then we need to figure out whether there are any other users
f2e824
				// who already had this clean name with the old version
f2e824
				$sql = 'SELECT user_id, username
f2e824
					FROM ' . USERS_TABLE . '
f2e824
					WHERE username_clean = \'' . $db->sql_escape($clean_name) . '\'';
f2e824
				$result2 = $db->sql_query($sql);
f2e824
f2e824
				$user_ids = array($user_id);
f2e824
				while ($row = $db->sql_fetchrow($result2))
f2e824
				{
f2e824
					// For not trimmed entries this could happen, yes. ;)
f2e824
					if ($row['user_id'] == $user_id)
f2e824
					{
f2e824
						continue;
f2e824
					}
f2e824
f2e824
					// Make sure this clean name will still be the same with the
f2e824
					// new function. If it is, then we have to add it to the list
f2e824
					// of user ids for this clean name
f2e824
					if (utf8_new_clean_string($row['username']) == $clean_name)
f2e824
					{
f2e824
						$user_ids[] = (int) $row['user_id'];
f2e824
					}
f2e824
				}
f2e824
				$db->sql_freeresult($result2);
f2e824
f2e824
				// if we already found a collision save it
f2e824
				if (sizeof($user_ids) > 1)
f2e824
				{
f2e824
					$colliding_users[$clean_name] = $user_ids;
f2e824
					$found_names[$clean_name] = true;
f2e824
				}
f2e824
				else
f2e824
				{
f2e824
					// otherwise just mark this name as found
f2e824
					$found_names[$clean_name] = $user_id;
f2e824
				}
f2e824
			}
f2e824
			// Else, if we already found the username
f2e824
			else
f2e824
			{
f2e824
				// If the value in the found_names lookup table is only true ...
f2e824
				if ($found_names[$clean_name] === true)
f2e824
				{
f2e824
					// then the actual data was already added to $colliding_users
f2e824
					// and we only need to append the user_id
f2e824
					$colliding_users[$clean_name][] = $user_id;
f2e824
				}
f2e824
				else
f2e824
				{
f2e824
					// otherwise it still keeps the first user_id for this name
f2e824
					// and we need to move the data to $colliding_users, and set
f2e824
					// the value in the found_names lookup table to true, so
f2e824
					// following users will directly be appended to $colliding_users
f2e824
					$colliding_users[$clean_name] = array($found_names[$clean_name], $user_id);
f2e824
					$found_names[$clean_name] = true;
f2e824
				}
f2e824
			}
f2e824
		}
f2e824
f2e824
		if (($echos % 1000) == 0)
f2e824
		{
f2e824
			echo '.';
f2e824
			flush();
f2e824
		}
f2e824
		$echos++;
f2e824
	}
f2e824
	$db->sql_freeresult($result);
f2e824
f2e824
	_write_result(false, $errored, $error_ary);
f2e824
f2e824
	// now retrieve all information about the users and let the admin decide what to do
f2e824
	if (sizeof($colliding_users))
f2e824
	{
f2e824
		$exit = true;
f2e824
		include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
f2e824
		include($phpbb_root_path . 'language/' . $language . '/memberlist.' . $phpEx);
f2e824
		include($phpbb_root_path . 'language/' . $language . '/acp/users.' . $phpEx);
f2e824
f2e824
		// link a few things to the correct place so we don't get any problems
f2e824
		$user->lang = &$lang;
f2e824
		$user->data['user_id'] = ANONYMOUS;
f2e824
		$user->date_format = $config['default_dateformat'];
f2e824
f2e824
		// a little trick to get all user_ids
f2e824
		$user_ids = call_user_func_array('array_merge', array_values($colliding_users));
f2e824
f2e824
		$sql = 'SELECT session_user_id, MAX(session_time) AS session_time
f2e824
			FROM ' . SESSIONS_TABLE . '
f2e824
			WHERE session_time >= ' . (time() - $config['session_length']) . '
f2e824
				AND ' . $db->sql_in_set('session_user_id', $user_ids) . '
f2e824
			GROUP BY session_user_id';
f2e824
		$result = $db->sql_query($sql);
f2e824
f2e824
		$session_times = array();
f2e824
		while ($row = $db->sql_fetchrow($result))
f2e824
		{
f2e824
			$session_times[$row['session_user_id']] = $row['session_time'];
f2e824
		}
f2e824
		$db->sql_freeresult($result);
f2e824
f2e824
		$sql = 'SELECT *
f2e824
			FROM ' . USERS_TABLE . '
f2e824
			WHERE ' . $db->sql_in_set('user_id', $user_ids);
f2e824
		$result = $db->sql_query($sql);
f2e824
f2e824
		$users = array();
f2e824
		while ($row = $db->sql_fetchrow($result))
f2e824
		{
f2e824
			if (isset($session_times[$row['user_id']]))
f2e824
			{
f2e824
				$row['session_time'] = $session_times[$row['user_id']];
f2e824
			}
f2e824
			else
f2e824
			{
f2e824
				$row['session_time'] = 0;
f2e824
			}
f2e824
			$users[(int) $row['user_id']] = $row;
f2e824
		}
f2e824
		$db->sql_freeresult($result);
f2e824
		unset($session_times);
f2e824
f2e824
		// now display a table with all users, some information about them and options
f2e824
		// for the admin: keep name, change name (with text input) or delete user
f2e824
		$u_action = "database_update.$phpEx?language=$language&type=$inline_update";
f2e824
?>
f2e824


f2e824
f2e824

f2e824
<form id="change_clean_names" method="post" action="<?php echo $u_action; ?>">
f2e824
f2e824
f2e824
f2e824
		foreach ($colliding_users as $clean_name => $user_ids)
f2e824
		{
f2e824
?>
f2e824
	<fieldset class="tabulated">
f2e824
		
f2e824
			<caption></caption>
f2e824
			
f2e824
				
f2e824
					 
f2e824
					
f2e824
					
f2e824
					
f2e824
					
f2e824
					
f2e824
					
f2e824
				
f2e824
			
f2e824
			
f2e824
f2e824
			foreach ($user_ids as $i => $user_id)
f2e824
			{
f2e824
				$row = $users[$user_id];
f2e824
f2e824
				$rank_title = $rank_img = '';
f2e824
				get_user_rank($row['user_rank'], $row['user_posts'], $rank_title, $rank_img, $rank_img_src);
f2e824
f2e824
				$last_visit = (!empty($row['session_time'])) ? $row['session_time'] : $row['user_lastvisit'];
f2e824
f2e824
				$info = '';
f2e824
				switch ($row['user_type'])
f2e824
				{
f2e824
					case USER_INACTIVE:
f2e824
						$info .= $lang['USER_INACTIVE'];
f2e824
					break;
f2e824
f2e824
					case USER_IGNORE:
f2e824
						$info .= $lang['BOT'];
f2e824
					break;
f2e824
f2e824
					case USER_FOUNDER:
f2e824
						$info .= $lang['FOUNDER'];
f2e824
					break;
f2e824
f2e824
					default:
f2e824
						$info .= $lang['USER_ACTIVE'];
f2e824
				}
f2e824
f2e824
				if ($user_id == ANONYMOUS)
f2e824
				{
f2e824
					$info = $lang['GUEST'];
f2e824
				}
f2e824
?>
f2e824
				
f2e824
					
f2e824
						
f2e824
						
f2e824
					
f2e824
					
f2e824
					
f2e824
					format_date($row['user_regdate']) ?>
f2e824
					format_date($last_visit); ?> 
f2e824
					
f2e824
						<label><input type="radio" class="radio" id="keep_user_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="keep" checked="checked" /> </label>
f2e824
						<label><input type="radio" class="radio" id="edit_user_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="edit" /> </label>
f2e824
f2e824
				// some users must not be deleted
f2e824
				if ($user_id != ANONYMOUS && $row['user_type'] != USER_FOUNDER)
f2e824
				{
f2e824
?>
f2e824
						<label><input type="radio" class="radio" id="delete_user_retain_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="delete_retain" /> </label>
f2e824
						<label><input type="radio" class="radio" id="delete_user_remove_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="delete_remove" /> </label>
f2e824
f2e824
				}
f2e824
?>
f2e824
					
f2e824
					
f2e824
						<input id="new_username_<?php echo $user_id; ?>" type="text" name="new_usernames[<?php echo $user_id; ?>]" value="<?php echo $row['username']; ?>" />
f2e824
					
f2e824
				
f2e824
f2e824
			}
f2e824
?>
f2e824
			
f2e824
		
f2e824
	</fieldset>
f2e824
f2e824
		}
f2e824
?>
f2e824
		

f2e824
			<input class="button2" id="resolve_conflicts" type="submit" name="resolve_conflicts" value="<?php echo $lang['SUBMIT']; ?>" />
f2e824
		

f2e824
	</form>
f2e824
f2e824
	}
f2e824
	else if (sizeof($found_names))
f2e824
	{
f2e824
		$sql = 'SELECT user_id, username, username_clean
f2e824
			FROM ' . USERS_TABLE . '
f2e824
			WHERE ' . $db->sql_in_set('user_id', array_values($found_names));
f2e824
		$result = $db->sql_query($sql);
f2e824
f2e824
		$found_names = array();
f2e824
		while ($row = $db->sql_fetchrow($result))
f2e824
		{
f2e824
			$clean_name = utf8_new_clean_string($row['username']);
f2e824
f2e824
			if ($clean_name != $row['username_clean'])
f2e824
			{
f2e824
				$user_id = (int) $row['user_id'];
f2e824
				$found_names[$user_id] = $clean_name;
f2e824
f2e824
				// impossible unique clean name
f2e824
				$sql = 'UPDATE ' . USERS_TABLE . "
f2e824
					SET username_clean = '  {$user_id}'
f2e824
					WHERE user_id = {$user_id}";
f2e824
				$db->sql_query($sql);
f2e824
			}
f2e824
		}
f2e824
		$db->sql_freeresult($result);
f2e824
f2e824
		foreach ($found_names as $user_id => $clean_name)
f2e824
		{
f2e824
			$sql = 'UPDATE ' . USERS_TABLE . '
f2e824
				SET username_clean = \'' . $db->sql_escape($clean_name) . '\'
f2e824
				WHERE user_id = ' . $user_id;
f2e824
			$db->sql_query($sql);
f2e824
		}
f2e824
	}
f2e824
	unset($found_names);
f2e824
	unset($colliding_users);
f2e824
}
f2e824
f2e824
if ($exit)
f2e824
{
f2e824
?>
f2e824
f2e824
					
f2e824
				
f2e824
			
f2e824
		
f2e824
		
f2e824
	
f2e824
f2e824
	
f2e824
		Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
f2e824
	
f2e824
f2e824
f2e824
</body>
f2e824
</html>
f2e824
f2e824
f2e824
	if (function_exists('exit_handler'))
f2e824
	{
f2e824
		exit_handler();
f2e824
	}
f2e824
}
f2e824
f2e824
// Schema updates
f2e824
?>
f2e824
	

f2e824
f2e824
	

f2e824
f2e824
	
f2e824
	

::

f2e824
f2e824
f2e824
f2e824
flush();
f2e824
f2e824
// We go through the schema changes from the lowest to the highest version
f2e824
// We try to also include versions 'in-between'...
f2e824
$no_updates = true;
f2e824
$versions = array_keys($database_update_info);
f2e824
for ($i = 0; $i < sizeof($versions); $i++)
f2e824
{
f2e824
	$version = $versions[$i];
f2e824
	$schema_changes = $database_update_info[$version];
f2e824
f2e824
	$next_version = (isset($versions[$i + 1])) ? $versions[$i + 1] : $updates_to_version;
f2e824
f2e824
	// If the installed version to be updated to is < than the current version, and if the current version is >= as the version to be updated to next, we will skip the process
f2e824
	if (version_compare($version, $current_version, '<') && version_compare($current_version, $next_version, '>='))
f2e824
	{
f2e824
		continue;
f2e824
	}
f2e824
f2e824
/*	if ($debug_from_version !== false)
f2e824
	{
f2e824
		// Applying update schema for version array with key '$version'
f2e824
		// for version '$version' to '$next_version'
f2e824
		continue;
f2e824
	}*/
f2e824
f2e824
	if (!sizeof($schema_changes))
f2e824
	{
f2e824
		continue;
f2e824
	}
f2e824
f2e824
	$no_updates = false;
f2e824
f2e824
	// Change columns?
f2e824
	if (!empty($schema_changes['change_columns']))
f2e824
	{
f2e824
		foreach ($schema_changes['change_columns'] as $table => $columns)
f2e824
		{
f2e824
			foreach ($columns as $column_name => $column_data)
f2e824
			{
f2e824
				sql_column_change($map_dbms, $table, $column_name, $column_data);
f2e824
			}
f2e824
		}
f2e824
	}
f2e824
f2e824
	// Add columns?
f2e824
	if (!empty($schema_changes['add_columns']))
f2e824
	{
f2e824
		foreach ($schema_changes['add_columns'] as $table => $columns)
f2e824
		{
f2e824
			foreach ($columns as $column_name => $column_data)
f2e824
			{
f2e824
				// Only add the column if it does not exist yet
f2e824
				if (!column_exists($map_dbms, $table, $column_name))
f2e824
				{
f2e824
					sql_column_add($map_dbms, $table, $column_name, $column_data);
f2e824
				}
f2e824
			}
f2e824
		}
f2e824
	}
f2e824
f2e824
	// Remove keys?
f2e824
	if (!empty($schema_changes['drop_keys']))
f2e824
	{
f2e824
		foreach ($schema_changes['drop_keys'] as $table => $indexes)
f2e824
		{
f2e824
			foreach ($indexes as $index_name)
f2e824
			{
f2e824
				sql_index_drop($map_dbms, $index_name, $table);
f2e824
			}
f2e824
		}
f2e824
	}
f2e824
f2e824
	// Drop columns?
f2e824
	if (!empty($schema_changes['drop_columns']))
f2e824
	{
f2e824
		foreach ($schema_changes['drop_columns'] as $table => $columns)
f2e824
		{
f2e824
			foreach ($columns as $column)
f2e824
			{
f2e824
				sql_column_remove($map_dbms, $table, $column);
f2e824
			}
f2e824
		}
f2e824
	}
f2e824
f2e824
	// Add primary keys?
f2e824
	if (!empty($schema_changes['add_primary_keys']))
f2e824
	{
f2e824
		foreach ($schema_changes['add_primary_keys'] as $table => $columns)
f2e824
		{
f2e824
			sql_create_primary_key($map_dbms, $table, $columns);
f2e824
		}
f2e824
	}
f2e824
f2e824
	// Add unqiue indexes?
f2e824
	if (!empty($schema_changes['add_unique_index']))
f2e824
	{
f2e824
		foreach ($schema_changes['add_unique_index'] as $table => $index_array)
f2e824
		{
f2e824
			foreach ($index_array as $index_name => $column)
f2e824
			{
f2e824
				sql_create_unique_index($map_dbms, $index_name, $table, $column);
f2e824
			}
f2e824
		}
f2e824
	}
f2e824
f2e824
	// Add indexes?
f2e824
	if (!empty($schema_changes['add_index']))
f2e824
	{
f2e824
		foreach ($schema_changes['add_index'] as $table => $index_array)
f2e824
		{
f2e824
			foreach ($index_array as $index_name => $column)
f2e824
			{
f2e824
				sql_create_index($map_dbms, $index_name, $table, $column);
f2e824
			}
f2e824
		}
f2e824
	}
f2e824
}
f2e824
f2e824
_write_result($no_updates, $errored, $error_ary);
f2e824
f2e824
// Data updates
f2e824
$error_ary = array();
f2e824
$errored = $no_updates = false;
f2e824
f2e824
?>
f2e824
f2e824


f2e824

f2e824

f2e824

::

f2e824
f2e824
f2e824
f2e824
flush();
f2e824
f2e824
$no_updates = true;
f2e824
$versions = array_keys($database_update_info);
f2e824
f2e824
// some code magic
f2e824
for ($i = 0; $i < sizeof($versions); $i++)
f2e824
{
f2e824
	$version = $versions[$i];
f2e824
	$next_version = (isset($versions[$i + 1])) ? $versions[$i + 1] : $updates_to_version;
f2e824
f2e824
	// If the installed version to be updated to is < than the current version, and if the current version is >= as the version to be updated to next, we will skip the process
f2e824
	if (version_compare($version, $current_version, '<') && version_compare($current_version, $next_version, '>='))
f2e824
	{
f2e824
		continue;
f2e824
	}
f2e824
f2e824
/*	if ($debug_from_version !== false)
f2e824
	{
f2e824
		// Applying update schema for version array with key '$version'
f2e824
		// for version '$version' to '$next_version'
f2e824
		continue;
f2e824
	}*/
f2e824
f2e824
	change_database_data($no_updates, $version);
f2e824
}
f2e824
f2e824
_write_result($no_updates, $errored, $error_ary);
f2e824
f2e824
$error_ary = array();
f2e824
$errored = $no_updates = false;
f2e824
f2e824
?>
f2e824
f2e824


f2e824

f2e824

f2e824

::

f2e824
f2e824
f2e824
f2e824
flush();
f2e824
f2e824
//if ($debug_from_version === false)
f2e824
// {
f2e824
f2e824
// update the version
f2e824
$sql = "UPDATE " . CONFIG_TABLE . "
f2e824
	SET config_value = '$updates_to_version'
f2e824
	WHERE config_name = 'version'";
f2e824
_sql($sql, $errored, $error_ary);
f2e824
f2e824
// Reset permissions
f2e824
$sql = 'UPDATE ' . USERS_TABLE . "
f2e824
	SET user_permissions = '',
f2e824
		user_perm_from = 0";
f2e824
_sql($sql, $errored, $error_ary);
f2e824
f2e824
// }
f2e824
f2e824
/* Optimize/vacuum analyze the tables where appropriate
f2e824
// this should be done for each version in future along with
f2e824
// the version number update
f2e824
switch ($db->sql_layer)
f2e824
{
f2e824
	case 'mysql':
f2e824
	case 'mysqli':
f2e824
	case 'mysql4':
f2e824
		$sql = 'OPTIMIZE TABLE ' . $table_prefix . 'auth_access, ' . $table_prefix . 'banlist, ' . $table_prefix . 'categories, ' . $table_prefix . 'config, ' . $table_prefix . 'disallow, ' . $table_prefix . 'forum_prune, ' . $table_prefix . 'forums, ' . $table_prefix . 'groups, ' . $table_prefix . 'posts, ' . $table_prefix . 'posts_text, ' . $table_prefix . 'privmsgs, ' . $table_prefix . 'privmsgs_text, ' . $table_prefix . 'ranks, ' . $table_prefix . 'search_results, ' . $table_prefix . 'search_wordlist, ' . $table_prefix . 'search_wordmatch, ' . $table_prefix . 'sessions_keys' . $table_prefix . 'smilies, ' . $table_prefix . 'themes, ' . $table_prefix . 'themes_name, ' . $table_prefix . 'topics, ' . $table_prefix . 'topics_watch, ' . $table_prefix . 'user_group, ' . $table_prefix . 'users, ' . $table_prefix . 'vote_desc, ' . $table_prefix . 'vote_results, ' . $table_prefix . 'vote_voters, ' . $table_prefix . 'words';
f2e824
		_sql($sql, $errored, $error_ary);
f2e824
	break;
f2e824
f2e824
	case 'postgresql':
f2e824
		_sql("VACUUM ANALYZE", $errored, $error_ary);
f2e824
	break;
f2e824
}
f2e824
*/
f2e824
f2e824
_write_result($no_updates, $errored, $error_ary);
f2e824
f2e824
?>
f2e824
f2e824

f2e824

f2e824
f2e824

f2e824
f2e824
f2e824
f2e824
if (!$inline_update)
f2e824
{
f2e824
	// Purge the cache...
f2e824
	$cache->purge();
f2e824
?>
f2e824
f2e824
	

f2e824
f2e824
	

f2e824
f2e824
f2e824
}
f2e824
else
f2e824
{
f2e824
?>
f2e824
f2e824
	

f2e824
f2e824
	

" class="button1">

f2e824
f2e824
f2e824
}
f2e824
f2e824
// Add database update to log
f2e824
add_log('admin', 'LOG_UPDATE_DATABASE', $orig_version, $updates_to_version);
f2e824
f2e824
// Now we purge the session table as well as all cache files
f2e824
$cache->purge();
f2e824
f2e824
?>
f2e824
f2e824
					
f2e824
				
f2e824
			
f2e824
		
f2e824
		
f2e824
	
f2e824
f2e824
	
f2e824
		Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
f2e824
	
f2e824
f2e824
f2e824
</body>
f2e824
</html>
f2e824
f2e824
f2e824
f2e824
garbage_collection();
f2e824
f2e824
if (function_exists('exit_handler'))
f2e824
{
f2e824
	exit_handler();
f2e824
}
f2e824
f2e824
/**
f2e824
* Function where all data changes are executed
f2e824
*/
f2e824
function change_database_data(&$no_updates, $version)
f2e824
{
f2e824
	global $db, $map_dbms, $errored, $error_ary, $config, $phpbb_root_path, $phpEx;
f2e824
f2e824
	switch ($version)
f2e824
	{
f2e824
		case '3.0.RC2':
f2e824
f2e824
			$smileys = array();
f2e824
f2e824
			$sql = 'SELECT smiley_id, code
f2e824
				FROM ' . SMILIES_TABLE;
f2e824
			$result = $db->sql_query($sql);
f2e824
f2e824
			while ($row = $db->sql_fetchrow($result))
f2e824
			{
f2e824
				$smileys[$row['smiley_id']] = $row['code'];
f2e824
			}
f2e824
			$db->sql_freeresult($result);
f2e824
f2e824
			foreach ($smileys as $id => $code)
f2e824
			{
f2e824
				// 2.0 only entitized lt and gt; We need to do something about double quotes.
f2e824
				if (strchr($code, '"') === false)
f2e824
				{
f2e824
					continue;
f2e824
				}
f2e824
f2e824
				$new_code = str_replace('&', '&', $code);
f2e824
				$new_code = str_replace('<', '<', $new_code);
f2e824
				$new_code = str_replace('>', '>', $new_code);
f2e824
				$new_code = utf8_htmlspecialchars($new_code);
f2e824
f2e824
				$sql = 'UPDATE ' . SMILIES_TABLE . '
f2e824
					SET code = \'' . $db->sql_escape($new_code) . '\'
f2e824
					WHERE smiley_id = ' . (int) $id;
f2e824
				$db->sql_query($sql);
f2e824
			}
f2e824
f2e824
			$index_list = sql_list_index($map_dbms, ACL_ROLES_DATA_TABLE);
f2e824
f2e824
			if (in_array('ath_opt_id', $index_list))
f2e824
			{
f2e824
				sql_index_drop($map_dbms, 'ath_opt_id', ACL_ROLES_DATA_TABLE);
f2e824
				sql_create_index($map_dbms, 'ath_op_id', ACL_ROLES_DATA_TABLE, array('auth_option_id'));
f2e824
			}
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		case '3.0.RC3':
f2e824
f2e824
			if ($map_dbms === 'postgres')
f2e824
			{
f2e824
				$sql = "SELECT SETVAL('" . FORUMS_TABLE . "_seq',(select case when max(forum_id)>0 then max(forum_id)+1 else 1 end from " . FORUMS_TABLE . '));';
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
			}
f2e824
f2e824
			// we check for:
f2e824
			// ath_opt_id
f2e824
			// ath_op_id
f2e824
			// ACL_ROLES_DATA_TABLE_ath_opt_id
f2e824
			// we want ACL_ROLES_DATA_TABLE_ath_op_id
f2e824
f2e824
			$table_index_fix = array(
f2e824
				ACL_ROLES_DATA_TABLE => array(
f2e824
					'ath_opt_id'							=> 'ath_op_id',
f2e824
					'ath_op_id'								=> 'ath_op_id',
f2e824
					ACL_ROLES_DATA_TABLE . '_ath_opt_id'	=> 'ath_op_id'
f2e824
				),
f2e824
				STYLES_IMAGESET_DATA_TABLE => array(
f2e824
					'i_id'									=> 'i_d',
f2e824
					'i_d'									=> 'i_d',
f2e824
					STYLES_IMAGESET_DATA_TABLE . '_i_id'	=> 'i_d'
f2e824
				)
f2e824
			);
f2e824
f2e824
			// we need to create some indicies...
f2e824
			$needed_creation = array();
f2e824
f2e824
			foreach ($table_index_fix as $table_name => $index_info)
f2e824
			{
f2e824
				$index_list = sql_list_fake($map_dbms, $table_name);
f2e824
				foreach ($index_info as $bad_index => $good_index)
f2e824
				{
f2e824
					if (in_array($bad_index, $index_list))
f2e824
					{
f2e824
						// mysql is actually OK, it won't get a hand in this crud
f2e824
						switch ($map_dbms)
f2e824
						{
f2e824
							// last version, mssql had issues with index removal
f2e824
							case 'mssql':
f2e824
								$sql = 'DROP INDEX ' . $table_name . '.' . $bad_index;
f2e824
								_sql($sql, $errored, $error_ary);
f2e824
							break;
f2e824
f2e824
							// last version, firebird, oracle, postgresql and sqlite all got bad index names
f2e824
							// we got kinda lucky, tho: they all support the same syntax
f2e824
							case 'firebird':
f2e824
							case 'oracle':
f2e824
							case 'postgres':
f2e824
							case 'sqlite':
f2e824
								$sql = 'DROP INDEX ' . $bad_index;
f2e824
								_sql($sql, $errored, $error_ary);
f2e824
							break;
f2e824
						}
f2e824
f2e824
						// If the good index already exist we do not need to create it again...
f2e824
						if (($map_dbms == 'mysql_40' || $map_dbms == 'mysql_41') && $bad_index == $good_index)
f2e824
						{
f2e824
						}
f2e824
						else
f2e824
						{
f2e824
							$needed_creation[$table_name][$good_index] = 1;
f2e824
						}
f2e824
					}
f2e824
				}
f2e824
			}
f2e824
f2e824
			$new_index_defs = array('ath_op_id' => array('auth_option_id'), 'i_d' => array('imageset_id'));
f2e824
f2e824
			foreach ($needed_creation as $bad_table => $index_repair_list)
f2e824
			{
f2e824
				foreach ($index_repair_list as $new_index => $garbage)
f2e824
				{
f2e824
					sql_create_index($map_dbms, $new_index, $bad_table, $new_index_defs[$new_index]);
f2e824
				}
f2e824
			}
f2e824
f2e824
			// Make sure empty smiley codes do not exist
f2e824
			$sql = 'DELETE FROM ' . SMILIES_TABLE . "
f2e824
				WHERE code = ''";
f2e824
			_sql($sql, $errored, $error_ary);
f2e824
f2e824
			set_config('allow_birthdays', '1');
f2e824
			set_config('cron_lock', '0', true);
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		case '3.0.RC4':
f2e824
f2e824
			$update_auto_increment = array(
f2e824
				STYLES_TABLE				=> 'style_id',
f2e824
				STYLES_TEMPLATE_TABLE		=> 'template_id',
f2e824
				STYLES_THEME_TABLE			=> 'theme_id',
f2e824
				STYLES_IMAGESET_TABLE		=> 'imageset_id'
f2e824
			);
f2e824
f2e824
			$sql = 'SELECT *
f2e824
				FROM ' . STYLES_TABLE . '
f2e824
				WHERE style_id = 0';
f2e824
			$result = _sql($sql, $errored, $error_ary);
f2e824
			$bad_style_row = $db->sql_fetchrow($result);
f2e824
			$db->sql_freeresult($result);
f2e824
f2e824
			if ($bad_style_row)
f2e824
			{
f2e824
				$sql = 'SELECT MAX(style_id) as max_id
f2e824
					FROM ' . STYLES_TABLE;
f2e824
				$result = _sql($sql, $errored, $error_ary);
f2e824
				$row = $db->sql_fetchrow($result);
f2e824
				$db->sql_freeresult($result);
f2e824
f2e824
				$proper_id = $row['max_id'] + 1;
f2e824
f2e824
				_sql('UPDATE ' . STYLES_TABLE . " SET style_id = $proper_id WHERE style_id = 0", $errored, $error_ary);
f2e824
				_sql('UPDATE ' . FORUMS_TABLE . " SET forum_style = $proper_id WHERE forum_style = 0", $errored, $error_ary);
f2e824
				_sql('UPDATE ' . USERS_TABLE . " SET user_style = $proper_id WHERE user_style = 0", $errored, $error_ary);
f2e824
f2e824
				$sql = 'SELECT config_value
f2e824
					FROM ' . CONFIG_TABLE . "
f2e824
					WHERE config_name = 'default_style'";
f2e824
				$result = _sql($sql, $errored, $error_ary);
f2e824
				$style_config = $db->sql_fetchrow($result);
f2e824
				$db->sql_freeresult($result);
f2e824
f2e824
				if ($style_config['config_value'] === '0')
f2e824
				{
f2e824
					set_config('default_style', (string) $proper_id);
f2e824
				}
f2e824
			}
f2e824
f2e824
			$sql = 'SELECT *
f2e824
				FROM ' . STYLES_TEMPLATE_TABLE . '
f2e824
				WHERE template_id = 0';
f2e824
			$result = _sql($sql, $errored, $error_ary);
f2e824
			$bad_style_row = $db->sql_fetchrow($result);
f2e824
			$db->sql_freeresult($result);
f2e824
f2e824
			if ($bad_style_row)
f2e824
			{
f2e824
				$sql = 'SELECT MAX(template_id) as max_id
f2e824
					FROM ' . STYLES_TEMPLATE_TABLE;
f2e824
				$result = _sql($sql, $errored, $error_ary);
f2e824
				$row = $db->sql_fetchrow($result);
f2e824
				$db->sql_freeresult($result);
f2e824
f2e824
				$proper_id = $row['max_id'] + 1;
f2e824
f2e824
				_sql('UPDATE ' . STYLES_TABLE . " SET template_id = $proper_id WHERE template_id = 0", $errored, $error_ary);
f2e824
			}
f2e824
f2e824
			$sql = 'SELECT *
f2e824
				FROM ' . STYLES_THEME_TABLE . '
f2e824
				WHERE theme_id = 0';
f2e824
			$result = _sql($sql, $errored, $error_ary);
f2e824
			$bad_style_row = $db->sql_fetchrow($result);
f2e824
			$db->sql_freeresult($result);
f2e824
f2e824
			if ($bad_style_row)
f2e824
			{
f2e824
				$sql = 'SELECT MAX(theme_id) as max_id
f2e824
					FROM ' . STYLES_THEME_TABLE;
f2e824
				$result = _sql($sql, $errored, $error_ary);
f2e824
				$row = $db->sql_fetchrow($result);
f2e824
				$db->sql_freeresult($result);
f2e824
f2e824
				$proper_id = $row['max_id'] + 1;
f2e824
f2e824
				_sql('UPDATE ' . STYLES_TABLE . " SET theme_id = $proper_id WHERE theme_id = 0", $errored, $error_ary);
f2e824
			}
f2e824
f2e824
			$sql = 'SELECT *
f2e824
				FROM ' . STYLES_IMAGESET_TABLE . '
f2e824
				WHERE imageset_id = 0';
f2e824
			$result = _sql($sql, $errored, $error_ary);
f2e824
			$bad_style_row = $db->sql_fetchrow($result);
f2e824
			$db->sql_freeresult($result);
f2e824
f2e824
			if ($bad_style_row)
f2e824
			{
f2e824
				$sql = 'SELECT MAX(imageset_id) as max_id
f2e824
					FROM ' . STYLES_IMAGESET_TABLE;
f2e824
				$result = _sql($sql, $errored, $error_ary);
f2e824
				$row = $db->sql_fetchrow($result);
f2e824
				$db->sql_freeresult($result);
f2e824
f2e824
				$proper_id = $row['max_id'] + 1;
f2e824
f2e824
				_sql('UPDATE ' . STYLES_TABLE . " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
f2e824
				_sql('UPDATE ' . STYLES_IMAGESET_DATA_TABLE . " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
f2e824
			}
f2e824
f2e824
			if ($map_dbms == 'mysql_40' || $map_dbms == 'mysql_41')
f2e824
			{
f2e824
				foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
f2e824
				{
f2e824
					$sql = "SELECT MAX({$auto_column_name}) as max_id
f2e824
						FROM {$auto_table_name}";
f2e824
					$result = _sql($sql, $errored, $error_ary);
f2e824
					$row = $db->sql_fetchrow($result);
f2e824
					$db->sql_freeresult($result);
f2e824
f2e824
					$max_id = ((int) $row['max_id']) + 1;
f2e824
					_sql("ALTER TABLE {$auto_table_name} AUTO_INCREMENT = {$max_id}", $errored, $error_ary);
f2e824
				}
f2e824
			}
f2e824
			else if ($map_dbms == 'postgres')
f2e824
			{
f2e824
				foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
f2e824
				{
f2e824
					$sql = "SELECT SETVAL('" . $auto_table_name . "_seq',(select case when max({$auto_column_name})>0 then max({$auto_column_name})+1 else 1 end from " . $auto_table_name . '));';
f2e824
					_sql($sql, $errored, $error_ary);
f2e824
				}
f2e824
f2e824
				$sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE . '_seq';
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
			}
f2e824
			else if ($map_dbms == 'firebird')
f2e824
			{
f2e824
				$sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE;
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
f2e824
				$sql = 'DROP GENERATOR ' . STYLES_TEMPLATE_DATA_TABLE . '_gen';
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
			}
f2e824
			else if ($map_dbms == 'oracle')
f2e824
			{
f2e824
				$sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE;
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
f2e824
				$sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE . '_seq';
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
			}
f2e824
			else if ($map_dbms == 'mssql')
f2e824
			{
f2e824
				// we use transactions because we need to have a working DB at the end of all of this
f2e824
				$db->sql_transaction('begin');
f2e824
f2e824
				$sql = 'SELECT *
f2e824
					FROM ' . STYLES_TEMPLATE_DATA_TABLE;
f2e824
				$result = _sql($sql, $errored, $error_ary);
f2e824
				$old_style_rows = array();
f2e824
				while ($row = $db->sql_fetchrow($result))
f2e824
				{
f2e824
					$old_style_rows[] = $row;
f2e824
				}
f2e824
				$db->sql_freeresult($result);
f2e824
f2e824
				// death to the table, it is evil!
f2e824
				$sql = 'DROP TABLE ' . STYLES_TEMPLATE_DATA_TABLE;
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
f2e824
				// the table of awesomeness, praise be to it (or something)
f2e824
				$sql = 'CREATE TABLE [' . STYLES_TEMPLATE_DATA_TABLE . "] (
f2e824
					[template_id] [int] DEFAULT (0) NOT NULL ,
f2e824
					[template_filename] [varchar] (100) DEFAULT ('') NOT NULL ,
f2e824
					[template_included] [varchar] (8000) DEFAULT ('') NOT NULL ,
f2e824
					[template_mtime] [int] DEFAULT (0) NOT NULL ,
f2e824
					[template_data] [text] DEFAULT ('') NOT NULL
f2e824
				) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]";
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
f2e824
				// index? index
f2e824
				$sql = 'CREATE  INDEX [tid] ON [' . STYLES_TEMPLATE_DATA_TABLE . ']([template_id]) ON [PRIMARY]';
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
f2e824
				// yet another index
f2e824
				$sql = 'CREATE  INDEX [tfn] ON [' . STYLES_TEMPLATE_DATA_TABLE . ']([template_filename]) ON [PRIMARY]';
f2e824
				_sql($sql, $errored, $error_ary);
f2e824
f2e824
				foreach ($old_style_rows as $return_row)
f2e824
				{
f2e824
					_sql('INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $return_row), $errored, $error_ary);
f2e824
				}
f2e824
f2e824
				$db->sql_transaction('commit');
f2e824
			}
f2e824
f2e824
			// Setting this here again because new installations may not have it...
f2e824
			set_config('cron_lock', '0', true);
f2e824
			set_config('ldap_port', '');
f2e824
			set_config('ldap_user_filter', '');
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		case '3.0.RC5':
f2e824
f2e824
			// In case the user is having the bot mediapartner google "as is", adjust it.
f2e824
			$sql = 'UPDATE ' . BOTS_TABLE . "
f2e824
				SET bot_agent = '" . $db->sql_escape('Mediapartners-Google') . "'
f2e824
				WHERE bot_agent = '" . $db->sql_escape('Mediapartners-Google/') . "'";
f2e824
			_sql($sql, $errored, $error_ary);
f2e824
f2e824
			set_config('form_token_lifetime', '7200');
f2e824
			set_config('form_token_mintime', '0');
f2e824
			set_config('min_time_reg', '5');
f2e824
			set_config('min_time_terms', '2');
f2e824
			set_config('form_token_sid_guests', '1');
f2e824
f2e824
			$db->sql_transaction('begin');
f2e824
f2e824
			$sql = 'SELECT forum_id, forum_password
f2e824
					FROM ' . FORUMS_TABLE;
f2e824
			$result = _sql($sql, $errored, $error_ary);
f2e824
f2e824
			while ($row = $db->sql_fetchrow($result))
f2e824
			{
f2e824
				if (!empty($row['forum_password']))
f2e824
				{
f2e824
					_sql('UPDATE ' . FORUMS_TABLE . " SET forum_password = '" . md5($row['forum_password']) . "' WHERE forum_id = {$row['forum_id']}", $errored, $error_ary);
f2e824
				}
f2e824
			}
f2e824
			$db->sql_freeresult($result);
f2e824
f2e824
			$db->sql_transaction('commit');
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		case '3.0.0':
f2e824
f2e824
			$sql = 'UPDATE ' . TOPICS_TABLE . "
f2e824
				SET topic_last_view_time = topic_last_post_time
f2e824
				WHERE topic_last_view_time = 0";
f2e824
			_sql($sql, $errored, $error_ary);
f2e824
f2e824
			// Update smiley sizes
f2e824
			$smileys = array('icon_e_surprised.gif', 'icon_eek.gif', 'icon_cool.gif', 'icon_lol.gif', 'icon_mad.gif', 'icon_razz.gif', 'icon_redface.gif', 'icon_cry.gif', 'icon_evil.gif', 'icon_twisted.gif', 'icon_rolleyes.gif', 'icon_exclaim.gif', 'icon_question.gif', 'icon_idea.gif', 'icon_arrow.gif', 'icon_neutral.gif', 'icon_mrgreen.gif', 'icon_e_ugeek.gif');
f2e824
f2e824
			foreach ($smileys as $smiley)
f2e824
			{
f2e824
				if (file_exists($phpbb_root_path . 'images/smilies/' . $smiley))
f2e824
				{
f2e824
					list($width, $height) = getimagesize($phpbb_root_path . 'images/smilies/' . $smiley);
f2e824
f2e824
					$sql = 'UPDATE ' . SMILIES_TABLE . '
f2e824
						SET smiley_width = ' . $width . ', smiley_height = ' . $height . "
f2e824
						WHERE smiley_url = '" . $db->sql_escape($smiley) . "'";
f2e824
f2e824
					_sql($sql, $errored, $error_ary);
f2e824
				}
f2e824
			}
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		// No changes from 3.0.1-RC1 to 3.0.1
f2e824
		case '3.0.1-RC1':
f2e824
		break;
f2e824
f2e824
		// changes from 3.0.1 to 3.0.2-RC1
f2e824
		case '3.0.1':
f2e824
f2e824
			set_config('referer_validation', '1');
f2e824
			set_config('check_attachment_content', '1');
f2e824
			set_config('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title');
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		// No changes from 3.0.2-RC1 to 3.0.2-RC2
f2e824
		case '3.0.2-RC1':
f2e824
		break;
f2e824
f2e824
		// No changes from 3.0.2-RC2 to 3.0.2
f2e824
		case '3.0.2-RC2':
f2e824
		break;
f2e824
f2e824
		// Changes from 3.0.2 to 3.0.3-RC1
f2e824
		case '3.0.2':
f2e824
			set_config('enable_queue_trigger', '0');
f2e824
			set_config('queue_trigger_posts', '3');
f2e824
f2e824
			set_config('pm_max_recipients', '0');
f2e824
f2e824
			// Set maximum number of recipients for the registered users, bots, guests group
f2e824
			$sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_max_recipients = 5
f2e824
				WHERE ' . $db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS'));
f2e824
			_sql($sql, $errored, $error_ary);
f2e824
f2e824
			// Not prefilling yet
f2e824
			set_config('dbms_version', '');
f2e824
f2e824
			// Add new permission u_masspm_group and duplicate settings from u_masspm
f2e824
			include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
f2e824
			$auth_admin = new auth_admin();
f2e824
f2e824
			// Only add the new permission if it does not already exist
f2e824
			if (empty($auth_admin->acl_options['id']['u_masspm_group']))
f2e824
			{
f2e824
				$auth_admin->acl_add_option(array('global' => array('u_masspm_group')));
f2e824
f2e824
				// Now the tricky part, filling the permission
f2e824
				$old_id = $auth_admin->acl_options['id']['u_masspm'];
f2e824
				$new_id = $auth_admin->acl_options['id']['u_masspm_group'];
f2e824
f2e824
				$tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE);
f2e824
f2e824
				foreach ($tables as $table)
f2e824
				{
f2e824
					$sql = 'SELECT *
f2e824
						FROM ' . $table . '
f2e824
						WHERE auth_option_id = ' . $old_id;
f2e824
					$result = _sql($sql, $errored, $error_ary);
f2e824
f2e824
					$sql_ary = array();
f2e824
					while ($row = $db->sql_fetchrow($result))
f2e824
					{
f2e824
						$row['auth_option_id'] = $new_id;
f2e824
						$sql_ary[] = $row;
f2e824
					}
f2e824
					$db->sql_freeresult($result);
f2e824
f2e824
					if (sizeof($sql_ary))
f2e824
					{
f2e824
						$db->sql_multi_insert($table, $sql_ary);
f2e824
					}
f2e824
				}
f2e824
f2e824
				// Remove any old permission entries
f2e824
				$auth_admin->acl_clear_prefetch();
f2e824
			}
f2e824
f2e824
			/**
f2e824
			* Do not resync post counts here. An admin may do this later from the ACP
f2e824
			$start = 0;
f2e824
			$step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000;
f2e824
f2e824
			$sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0';
f2e824
			_sql($sql, $errored, $error_ary);
f2e824
f2e824
			do
f2e824
			{
f2e824
				$sql = 'SELECT COUNT(post_id) AS num_posts, poster_id
f2e824
					FROM ' . POSTS_TABLE . '
f2e824
					WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . '
f2e824
						AND post_postcount = 1 AND post_approved = 1
f2e824
					GROUP BY poster_id';
f2e824
				$result = _sql($sql, $errored, $error_ary);
f2e824
f2e824
				if ($row = $db->sql_fetchrow($result))
f2e824
				{
f2e824
					do
f2e824
					{
f2e824
						$sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}";
f2e824
						_sql($sql, $errored, $error_ary);
f2e824
					}
f2e824
					while ($row = $db->sql_fetchrow($result));
f2e824
f2e824
					$start += $step;
f2e824
				}
f2e824
				else
f2e824
				{
f2e824
					$start = 0;
f2e824
				}
f2e824
				$db->sql_freeresult($result);
f2e824
			}
f2e824
			while ($start);
f2e824
			*/
f2e824
f2e824
			$sql = 'UPDATE ' . MODULES_TABLE . '
f2e824
				SET module_auth = \'acl_a_email && cfg_email_enable\'
f2e824
				WHERE module_class = \'acp\'
f2e824
					AND module_basename = \'email\'';
f2e824
			_sql($sql, $errored, $error_ary);
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		// Changes from 3.0.3-RC1 to 3.0.3
f2e824
		case '3.0.3-RC1':
f2e824
			$sql = 'UPDATE ' . LOG_TABLE . "
f2e824
				SET log_operation = 'LOG_DELETE_TOPIC'
f2e824
				WHERE log_operation = 'LOG_TOPIC_DELETED'";
f2e824
			_sql($sql, $errored, $error_ary);
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		// Changes from 3.0.3 to 3.0.4-RC1
f2e824
		case '3.0.3':
f2e824
			// Update the Custom Profile Fields based on previous settings to the new format
f2e824
			$sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide
f2e824
					FROM ' . PROFILE_FIELDS_TABLE;
f2e824
			$result = _sql($sql, $errored, $error_ary);
f2e824
f2e824
			while ($row = $db->sql_fetchrow($result))
f2e824
			{
f2e824
				$sql_ary = array(
f2e824
					'field_required'	=> 0,
f2e824
					'field_show_on_reg'	=> 0,
f2e824
					'field_hide'		=> 0,
f2e824
					'field_show_profile'=> 0,
f2e824
				);
f2e824
f2e824
				if ($row['field_required'])
f2e824
				{
f2e824
					$sql_ary['field_required'] = $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1;
f2e824
				}
f2e824
				else if ($row['field_show_on_reg'])
f2e824
				{
f2e824
					$sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1;
f2e824
				}
f2e824
				else if ($row['field_hide'])
f2e824
				{
f2e824
					// Only administrators and moderators can see this CPF, if the view is enabled, they can see it, otherwise just admins in the acp_users module
f2e824
					$sql_ary['field_hide'] = 1;
f2e824
				}
f2e824
				else
f2e824
				{
f2e824
					// equivelant to "none", which is the "Display in user control panel" option
f2e824
					$sql_ary['field_show_profile'] = 1;
f2e824
				}
f2e824
f2e824
				_sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary);
f2e824
			}
f2e824
f2e824
			$no_updates = false;
f2e824
		break;
f2e824
f2e824
		// Changes from 3.0.4-RC1 to 3.0.4
f2e824
		case '3.0.4-RC1':
f2e824
		break;
f2e824
	}
f2e824
}
f2e824
f2e824
/**
f2e824
* Function for triggering an sql statement
f2e824
*/
f2e824
function _sql($sql, &$errored, &$error_ary, $echo_dot = true)
f2e824
{
f2e824
	global $db;
f2e824
f2e824
	if (defined('DEBUG_EXTRA'))
f2e824
	{
f2e824
		echo "
\n{$sql}\n
";
f2e824
	}
f2e824
f2e824
	$db->sql_return_on_error(true);
f2e824
f2e824
	$result = $db->sql_query($sql);
f2e824
	if ($db->sql_error_triggered)
f2e824
	{
f2e824
		$errored = true;
f2e824
		$error_ary['sql'][] = $db->sql_error_sql;
f2e824
		$error_ary['error_code'][] = $db->_sql_error();
f2e824
	}
f2e824
f2e824
	$db->sql_return_on_error(false);
f2e824
f2e824
	if ($echo_dot)
f2e824
	{
f2e824
		echo ". \n";
f2e824
		flush();
f2e824
	}
f2e824
f2e824
	return $result;
f2e824
}
f2e824
f2e824
function _write_result($no_updates, $errored, $error_ary)
f2e824
{
f2e824
	global $lang;
f2e824
f2e824
	if ($no_updates)
f2e824
	{
f2e824
		echo ' ' . $lang['NO_UPDATES_REQUIRED'] . '

';
f2e824
	}
f2e824
	else
f2e824
	{
f2e824
		echo ' ' . $lang['DONE'] . '
' . $lang['RESULT'] . ' :: ';
f2e824
f2e824
		if ($errored)
f2e824
		{
f2e824
			echo ' ' . $lang['SOME_QUERIES_FAILED'] . ' 
    ';
f2e824
f2e824
			for ($i = 0; $i < sizeof($error_ary['sql']); $i++)
f2e824
			{
f2e824
				echo '
  • ' . $lang['ERROR'] . ' :: ' . htmlspecialchars($error_ary['error_code'][$i]['message']) . '
    ';
  • f2e824
    				echo $lang['SQL'] . ' :: ' . htmlspecialchars($error_ary['sql'][$i]) . '

    ';
    f2e824
    			}
    f2e824
    f2e824
    			echo ' 

    ' . $lang['SQL_FAILURE_EXPLAIN'] . '

    ';
    f2e824
    		}
    f2e824
    		else
    f2e824
    		{
    f2e824
    			echo '' . $lang['NO_ERRORS'] . '

    ';
    f2e824
    		}
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    /**
    f2e824
    * Check if a specified column exist
    f2e824
    */
    f2e824
    function column_exists($dbms, $table, $column_name)
    f2e824
    {
    f2e824
    	global $db;
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = "SHOW COLUMNS
    f2e824
    				FROM $table";
    f2e824
    			$result = $db->sql_query($sql);
    f2e824
    			while ($row = $db->sql_fetchrow($result))
    f2e824
    			{
    f2e824
    				// lower case just in case
    f2e824
    				if (strtolower($row['Field']) == $column_name)
    f2e824
    				{
    f2e824
    					$db->sql_freeresult($result);
    f2e824
    					return true;
    f2e824
    				}
    f2e824
    			}
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    			return false;
    f2e824
    		break;
    f2e824
    f2e824
    		// PostgreSQL has a way of doing this in a much simpler way but would
    f2e824
    		// not allow us to support all versions of PostgreSQL
    f2e824
    		case 'postgres':
    f2e824
    			$sql = "SELECT a.attname
    f2e824
    				FROM pg_class c, pg_attribute a
    f2e824
    				WHERE c.relname = '{$table}'
    f2e824
    					AND a.attnum > 0
    f2e824
    					AND a.attrelid = c.oid";
    f2e824
    			$result = $db->sql_query($sql);
    f2e824
    			while ($row = $db->sql_fetchrow($result))
    f2e824
    			{
    f2e824
    				// lower case just in case
    f2e824
    				if (strtolower($row['attname']) == $column_name)
    f2e824
    				{
    f2e824
    					$db->sql_freeresult($result);
    f2e824
    					return true;
    f2e824
    				}
    f2e824
    			}
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    			return false;
    f2e824
    		break;
    f2e824
    f2e824
    		// same deal with PostgreSQL, we must perform more complex operations than
    f2e824
    		// we technically could
    f2e824
    		case 'mssql':
    f2e824
    			$sql = "SELECT c.name
    f2e824
    				FROM syscolumns c
    f2e824
    				LEFT JOIN sysobjects o ON c.id = o.id
    f2e824
    				WHERE o.name = '{$table}'";
    f2e824
    			$result = $db->sql_query($sql);
    f2e824
    			while ($row = $db->sql_fetchrow($result))
    f2e824
    			{
    f2e824
    				// lower case just in case
    f2e824
    				if (strtolower($row['name']) == $column_name)
    f2e824
    				{
    f2e824
    					$db->sql_freeresult($result);
    f2e824
    					return true;
    f2e824
    				}
    f2e824
    			}
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    			return false;
    f2e824
    		break;
    f2e824
    f2e824
    		case 'oracle':
    f2e824
    			$sql = "SELECT column_name
    f2e824
    				FROM user_tab_columns
    f2e824
    				WHERE table_name = '{$table}'";
    f2e824
    			$result = $db->sql_query($sql);
    f2e824
    			while ($row = $db->sql_fetchrow($result))
    f2e824
    			{
    f2e824
    				// lower case just in case
    f2e824
    				if (strtolower($row['column_name']) == $column_name)
    f2e824
    				{
    f2e824
    					$db->sql_freeresult($result);
    f2e824
    					return true;
    f2e824
    				}
    f2e824
    			}
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    			return false;
    f2e824
    		break;
    f2e824
    f2e824
    		case 'firebird':
    f2e824
    			$sql = "SELECT RDB\$FIELD_NAME as FNAME
    f2e824
    				FROM RDB\$RELATION_FIELDS
    f2e824
    				WHERE RDB\$RELATION_NAME = '{$table}'";
    f2e824
    			$result = $db->sql_query($sql);
    f2e824
    			while ($row = $db->sql_fetchrow($result))
    f2e824
    			{
    f2e824
    				// lower case just in case
    f2e824
    				if (strtolower($row['fname']) == $column_name)
    f2e824
    				{
    f2e824
    					$db->sql_freeresult($result);
    f2e824
    					return true;
    f2e824
    				}
    f2e824
    			}
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    			return false;
    f2e824
    		break;
    f2e824
    f2e824
    		// ugh, SQLite
    f2e824
    		case 'sqlite':
    f2e824
    			$sql = "SELECT sql
    f2e824
    				FROM sqlite_master
    f2e824
    				WHERE type = 'table'
    f2e824
    					AND name = '{$table}'";
    f2e824
    			$result = $db->sql_query($sql);
    f2e824
    f2e824
    			if (!$result)
    f2e824
    			{
    f2e824
    				return false;
    f2e824
    			}
    f2e824
    f2e824
    			$row = $db->sql_fetchrow($result);
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    f2e824
    			preg_match('#\((.*)\)#s', $row['sql'], $matches);
    f2e824
    f2e824
    			$cols = trim($matches[1]);
    f2e824
    			$col_array = preg_split('/,(?![\s\w]+\))/m', $cols);
    f2e824
    f2e824
    			foreach ($col_array as $declaration)
    f2e824
    			{
    f2e824
    				$entities = preg_split('#\s+#', trim($declaration));
    f2e824
    				if ($entities[0] == 'PRIMARY')
    f2e824
    				{
    f2e824
    					continue;
    f2e824
    				}
    f2e824
    f2e824
    				if (strtolower($entities[0]) == $column_name)
    f2e824
    				{
    f2e824
    					return true;
    f2e824
    				}
    f2e824
    			}
    f2e824
    			return false;
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    /**
    f2e824
    * Function to prepare some column information for better usage
    f2e824
    */
    f2e824
    function prepare_column_data($dbms, $column_data, $table_name, $column_name)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $unsigned_types;
    f2e824
    f2e824
    	// Get type
    f2e824
    	if (strpos($column_data[0], ':') !== false)
    f2e824
    	{
    f2e824
    		list($orig_column_type, $column_length) = explode(':', $column_data[0]);
    f2e824
    f2e824
    		if (!is_array($dbms_type_map[$dbms][$orig_column_type . ':']))
    f2e824
    		{
    f2e824
    			$column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'], $column_length);
    f2e824
    		}
    f2e824
    		else
    f2e824
    		{
    f2e824
    			if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['rule']))
    f2e824
    			{
    f2e824
    				switch ($dbms_type_map[$dbms][$orig_column_type . ':']['rule'][0])
    f2e824
    				{
    f2e824
    					case 'div':
    f2e824
    						$column_length /= $dbms_type_map[$dbms][$orig_column_type . ':']['rule'][1];
    f2e824
    						$column_length = ceil($column_length);
    f2e824
    						$column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length);
    f2e824
    					break;
    f2e824
    				}
    f2e824
    			}
    f2e824
    f2e824
    			if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['limit']))
    f2e824
    			{
    f2e824
    				switch ($dbms_type_map[$dbms][$orig_column_type . ':']['limit'][0])
    f2e824
    				{
    f2e824
    					case 'mult':
    f2e824
    						$column_length *= $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][1];
    f2e824
    						if ($column_length > $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][2])
    f2e824
    						{
    f2e824
    							$column_type = $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][3];
    f2e824
    						}
    f2e824
    						else
    f2e824
    						{
    f2e824
    							$column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length);
    f2e824
    						}
    f2e824
    					break;
    f2e824
    				}
    f2e824
    			}
    f2e824
    		}
    f2e824
    		$orig_column_type .= ':';
    f2e824
    	}
    f2e824
    	else
    f2e824
    	{
    f2e824
    		$orig_column_type = $column_data[0];
    f2e824
    		$column_type = $dbms_type_map[$dbms][$column_data[0]];
    f2e824
    	}
    f2e824
    f2e824
    	// Adjust default value if db-dependant specified
    f2e824
    	if (is_array($column_data[1]))
    f2e824
    	{
    f2e824
    		$column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default'];
    f2e824
    	}
    f2e824
    f2e824
    	$sql = '';
    f2e824
    	$return_array = array();
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'firebird':
    f2e824
    			$sql .= " {$column_type} ";
    f2e824
    f2e824
    			if (!is_null($column_data[1]))
    f2e824
    			{
    f2e824
    				$sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' ';
    f2e824
    			}
    f2e824
    f2e824
    			$sql .= 'NOT NULL';
    f2e824
    f2e824
    			// This is a UNICODE column and thus should be given it's fair share
    f2e824
    			if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0]))
    f2e824
    			{
    f2e824
    				$sql .= ' COLLATE UNICODE';
    f2e824
    			}
    f2e824
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mssql':
    f2e824
    			$sql .= " {$column_type} ";
    f2e824
    			$sql_default = " {$column_type} ";
    f2e824
    f2e824
    			// For adding columns we need the default definition
    f2e824
    			if (!is_null($column_data[1]))
    f2e824
    			{
    f2e824
    				// For hexadecimal values do not use single quotes
    f2e824
    				if (strpos($column_data[1], '0x') === 0)
    f2e824
    				{
    f2e824
    					$sql_default .= 'DEFAULT (' . $column_data[1] . ') ';
    f2e824
    				}
    f2e824
    				else
    f2e824
    				{
    f2e824
    					$sql_default .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') ';
    f2e824
    				}
    f2e824
    			}
    f2e824
    f2e824
    			$sql .= 'NOT NULL';
    f2e824
    			$sql_default .= 'NOT NULL';
    f2e824
    f2e824
    			$return_array['column_type_sql_default'] = $sql_default;
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql .= " {$column_type} ";
    f2e824
    f2e824
    			// For hexadecimal values do not use single quotes
    f2e824
    			if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob')
    f2e824
    			{
    f2e824
    				$sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' ";
    f2e824
    			}
    f2e824
    			$sql .= 'NOT NULL';
    f2e824
    f2e824
    			if (isset($column_data[2]))
    f2e824
    			{
    f2e824
    				if ($column_data[2] == 'auto_increment')
    f2e824
    				{
    f2e824
    					$sql .= ' auto_increment';
    f2e824
    				}
    f2e824
    				else if ($dbms === 'mysql_41' && $column_data[2] == 'true_sort')
    f2e824
    				{
    f2e824
    					$sql .= ' COLLATE utf8_unicode_ci';
    f2e824
    				}
    f2e824
    			}
    f2e824
    f2e824
    		break;
    f2e824
    f2e824
    		case 'oracle':
    f2e824
    			$sql .= " {$column_type} ";
    f2e824
    			$sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : '';
    f2e824
    f2e824
    			// In Oracle empty strings ('') are treated as NULL.
    f2e824
    			// Therefore in oracle we allow NULL's for all DEFAULT '' entries
    f2e824
    			// Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields)
    f2e824
    			if (preg_match('/number/i', $column_type))
    f2e824
    			{
    f2e824
    				$sql .= ($column_data[1] === '') ? '' : 'NOT NULL';
    f2e824
    			}
    f2e824
    		break;
    f2e824
    f2e824
    		case 'postgres':
    f2e824
    			$return_array['column_type'] = $column_type;
    f2e824
    f2e824
    			$sql .= " {$column_type} ";
    f2e824
    f2e824
    			if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
    f2e824
    			{
    f2e824
    				$default_val = "nextval('{$table_name}_seq')";
    f2e824
    			}
    f2e824
    			else if (!is_null($column_data[1]))
    f2e824
    			{
    f2e824
    				$default_val = "'" . $column_data[1] . "'";
    f2e824
    				$return_array['null'] = 'NOT NULL';
    f2e824
    				$sql .= 'NOT NULL ';
    f2e824
    			}
    f2e824
    f2e824
    			$return_array['default'] = $default_val;
    f2e824
    f2e824
    			$sql .= "DEFAULT {$default_val}";
    f2e824
    f2e824
    			// Unsigned? Then add a CHECK contraint
    f2e824
    			if (in_array($orig_column_type, $unsigned_types))
    f2e824
    			{
    f2e824
    				$return_array['constraint'] = "CHECK ({$column_name} >= 0)";
    f2e824
    				$sql .= " CHECK ({$column_name} >= 0)";
    f2e824
    			}
    f2e824
    		break;
    f2e824
    f2e824
    		case 'sqlite':
    f2e824
    			if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
    f2e824
    			{
    f2e824
    				$sql .= ' INTEGER PRIMARY KEY';
    f2e824
    			}
    f2e824
    			else
    f2e824
    			{
    f2e824
    				$sql .= ' ' . $column_type;
    f2e824
    			}
    f2e824
    f2e824
    			$sql .= ' NOT NULL ';
    f2e824
    			$sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : '';
    f2e824
    		break;
    f2e824
    	}
    f2e824
    f2e824
    	$return_array['column_type_sql'] = $sql;
    f2e824
    f2e824
    	return $return_array;
    f2e824
    }
    f2e824
    f2e824
    /**
    f2e824
    * Add new column
    f2e824
    */
    f2e824
    function sql_column_add($dbms, $table_name, $column_name, $column_data)
    f2e824
    {
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	$column_data = prepare_column_data($dbms, $column_data, $table_name, $column_name);
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'firebird':
    f2e824
    			$sql = 'ALTER TABLE "' . $table_name . '" ADD "' . $column_name . '" ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mssql':
    f2e824
    			$sql = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'oracle':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'postgres':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'sqlite':
    f2e824
    			if (version_compare(sqlite_libversion(), '3.0') == -1)
    f2e824
    			{
    f2e824
    				global $db;
    f2e824
    				$sql = "SELECT sql
    f2e824
    					FROM sqlite_master
    f2e824
    					WHERE type = 'table'
    f2e824
    						AND name = '{$table_name}'
    f2e824
    					ORDER BY type DESC, name;";
    f2e824
    				$result = $db->sql_query($sql);
    f2e824
    f2e824
    				if (!$result)
    f2e824
    				{
    f2e824
    					break;
    f2e824
    				}
    f2e824
    f2e824
    				$row = $db->sql_fetchrow($result);
    f2e824
    				$db->sql_freeresult($result);
    f2e824
    f2e824
    				$db->sql_transaction('begin');
    f2e824
    f2e824
    				// Create a backup table and populate it, destroy the existing one
    f2e824
    				$db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
    f2e824
    				$db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
    f2e824
    				$db->sql_query('DROP TABLE ' . $table_name);
    f2e824
    f2e824
    				preg_match('#\((.*)\)#s', $row['sql'], $matches);
    f2e824
    f2e824
    				$new_table_cols = trim($matches[1]);
    f2e824
    				$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
    f2e824
    				$column_list = array();
    f2e824
    f2e824
    				foreach ($old_table_cols as $declaration)
    f2e824
    				{
    f2e824
    					$entities = preg_split('#\s+#', trim($declaration));
    f2e824
    					if ($entities[0] == 'PRIMARY')
    f2e824
    					{
    f2e824
    						continue;
    f2e824
    					}
    f2e824
    					$column_list[] = $entities[0];
    f2e824
    				}
    f2e824
    f2e824
    				$columns = implode(',', $column_list);
    f2e824
    f2e824
    				$new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
    f2e824
    f2e824
    				// create a new table and fill it up. destroy the temp one
    f2e824
    				$db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');');
    f2e824
    				$db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
    f2e824
    				$db->sql_query('DROP TABLE ' . $table_name . '_temp');
    f2e824
    f2e824
    				$db->sql_transaction('commit');
    f2e824
    			}
    f2e824
    			else
    f2e824
    			{
    f2e824
    				$sql = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']';
    f2e824
    				_sql($sql, $errored, $error_ary);
    f2e824
    			}
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    /**
    f2e824
    * Drop column
    f2e824
    */
    f2e824
    function sql_column_remove($dbms, $table_name, $column_name)
    f2e824
    {
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'firebird':
    f2e824
    			$sql = 'ALTER TABLE "' . $table_name . '" DROP "' . $column_name . '"';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mssql':
    f2e824
    			$sql = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'oracle':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name;
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'postgres':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'sqlite':
    f2e824
    			if (version_compare(sqlite_libversion(), '3.0') == -1)
    f2e824
    			{
    f2e824
    				global $db;
    f2e824
    				$sql = "SELECT sql
    f2e824
    					FROM sqlite_master
    f2e824
    					WHERE type = 'table'
    f2e824
    						AND name = '{$table_name}'
    f2e824
    					ORDER BY type DESC, name;";
    f2e824
    				$result = $db->sql_query($sql);
    f2e824
    f2e824
    				if (!$result)
    f2e824
    				{
    f2e824
    					break;
    f2e824
    				}
    f2e824
    f2e824
    				$row = $db->sql_fetchrow($result);
    f2e824
    				$db->sql_freeresult($result);
    f2e824
    f2e824
    				$db->sql_transaction('begin');
    f2e824
    f2e824
    				// Create a backup table and populate it, destroy the existing one
    f2e824
    				$db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
    f2e824
    				$db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
    f2e824
    				$db->sql_query('DROP TABLE ' . $table_name);
    f2e824
    f2e824
    				preg_match('#\((.*)\)#s', $row['sql'], $matches);
    f2e824
    f2e824
    				$new_table_cols = trim($matches[1]);
    f2e824
    				$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
    f2e824
    				$column_list = array();
    f2e824
    f2e824
    				foreach ($old_table_cols as $declaration)
    f2e824
    				{
    f2e824
    					$entities = preg_split('#\s+#', trim($declaration));
    f2e824
    					if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
    f2e824
    					{
    f2e824
    						continue;
    f2e824
    					}
    f2e824
    					$column_list[] = $entities[0];
    f2e824
    				}
    f2e824
    f2e824
    				$columns = implode(',', $column_list);
    f2e824
    f2e824
    				$new_table_cols = $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
    f2e824
    f2e824
    				// create a new table and fill it up. destroy the temp one
    f2e824
    				$db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');');
    f2e824
    				$db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
    f2e824
    				$db->sql_query('DROP TABLE ' . $table_name . '_temp');
    f2e824
    f2e824
    				$db->sql_transaction('commit');
    f2e824
    			}
    f2e824
    			else
    f2e824
    			{
    f2e824
    				$sql = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
    f2e824
    				_sql($sql, $errored, $error_ary);
    f2e824
    			}
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    function sql_index_drop($dbms, $index_name, $table_name)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $db;
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'mssql':
    f2e824
    			$sql = 'DROP INDEX ' . $table_name . '.' . $index_name;
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = 'DROP INDEX ' . $index_name . ' ON ' . $table_name;
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'firebird':
    f2e824
    		case 'oracle':
    f2e824
    		case 'postgres':
    f2e824
    		case 'sqlite':
    f2e824
    			$sql = 'DROP INDEX ' . $table_name . '_' . $index_name;
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    function sql_create_primary_key($dbms, $table_name, $column)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $db;
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'firebird':
    f2e824
    		case 'postgres':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mssql':
    f2e824
    			$sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD ";
    f2e824
    			$sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY  CLUSTERED (";
    f2e824
    			$sql .= '[' . implode("],\n\t\t[", $column) . ']';
    f2e824
    			$sql .= ') ON [PRIMARY]';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'oracle':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'sqlite':
    f2e824
    			$sql = "SELECT sql
    f2e824
    				FROM sqlite_master
    f2e824
    				WHERE type = 'table'
    f2e824
    					AND name = '{$table_name}'
    f2e824
    				ORDER BY type DESC, name;";
    f2e824
    			$result = _sql($sql, $errored, $error_ary);
    f2e824
    f2e824
    			if (!$result)
    f2e824
    			{
    f2e824
    				break;
    f2e824
    			}
    f2e824
    f2e824
    			$row = $db->sql_fetchrow($result);
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    f2e824
    			$db->sql_transaction('begin');
    f2e824
    f2e824
    			// Create a backup table and populate it, destroy the existing one
    f2e824
    			$db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
    f2e824
    			$db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
    f2e824
    			$db->sql_query('DROP TABLE ' . $table_name);
    f2e824
    f2e824
    			preg_match('#\((.*)\)#s', $row['sql'], $matches);
    f2e824
    f2e824
    			$new_table_cols = trim($matches[1]);
    f2e824
    			$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
    f2e824
    			$column_list = array();
    f2e824
    f2e824
    			foreach ($old_table_cols as $declaration)
    f2e824
    			{
    f2e824
    				$entities = preg_split('#\s+#', trim($declaration));
    f2e824
    				if ($entities[0] == 'PRIMARY')
    f2e824
    				{
    f2e824
    					continue;
    f2e824
    				}
    f2e824
    				$column_list[] = $entities[0];
    f2e824
    			}
    f2e824
    f2e824
    			$columns = implode(',', $column_list);
    f2e824
    f2e824
    			// create a new table and fill it up. destroy the temp one
    f2e824
    			$db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));');
    f2e824
    			$db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
    f2e824
    			$db->sql_query('DROP TABLE ' . $table_name . '_temp');
    f2e824
    f2e824
    			$db->sql_transaction('commit');
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    function sql_create_unique_index($dbms, $index_name, $table_name, $column)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $db;
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'firebird':
    f2e824
    		case 'postgres':
    f2e824
    		case 'oracle':
    f2e824
    		case 'sqlite':
    f2e824
    			$sql = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mssql':
    f2e824
    			$sql = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    function sql_create_index($dbms, $index_name, $table_name, $column)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $db;
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'firebird':
    f2e824
    		case 'postgres':
    f2e824
    		case 'oracle':
    f2e824
    		case 'sqlite':
    f2e824
    			$sql = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mssql':
    f2e824
    			$sql = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    // List all of the indices that belong to a table,
    f2e824
    // does not count:
    f2e824
    // * UNIQUE indices
    f2e824
    // * PRIMARY keys
    f2e824
    function sql_list_index($dbms, $table_name)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $db;
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	$index_array = array();
    f2e824
    f2e824
    	if ($dbms == 'mssql')
    f2e824
    	{
    f2e824
    		$sql = "EXEC sp_statistics '$table_name'";
    f2e824
    		$result = $db->sql_query($sql);
    f2e824
    		while ($row = $db->sql_fetchrow($result))
    f2e824
    		{
    f2e824
    			if ($row['TYPE'] == 3)
    f2e824
    			{
    f2e824
    				$index_array[] = $row['INDEX_NAME'];
    f2e824
    			}
    f2e824
    		}
    f2e824
    		$db->sql_freeresult($result);
    f2e824
    	}
    f2e824
    	else
    f2e824
    	{
    f2e824
    		switch ($dbms)
    f2e824
    		{
    f2e824
    			case 'firebird':
    f2e824
    				$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
    f2e824
    					FROM RDB\$INDICES
    f2e824
    					WHERE RDB\$RELATION_NAME = " . strtoupper($table_name) . "
    f2e824
    						AND RDB\$UNIQUE_FLAG IS NULL
    f2e824
    						AND RDB\$FOREIGN_KEY IS NULL";
    f2e824
    				$col = 'index_name';
    f2e824
    			break;
    f2e824
    f2e824
    			case 'postgres':
    f2e824
    				$sql = "SELECT ic.relname as index_name
    f2e824
    					FROM pg_class bc, pg_class ic, pg_index i
    f2e824
    					WHERE (bc.oid = i.indrelid)
    f2e824
    						AND (ic.oid = i.indexrelid)
    f2e824
    						AND (bc.relname = '" . $table_name . "')
    f2e824
    						AND (i.indisunique != 't')
    f2e824
    						AND (i.indisprimary != 't')";
    f2e824
    				$col = 'index_name';
    f2e824
    			break;
    f2e824
    f2e824
    			case 'mysql_40':
    f2e824
    			case 'mysql_41':
    f2e824
    				$sql = 'SHOW KEYS
    f2e824
    					FROM ' . $table_name;
    f2e824
    				$col = 'Key_name';
    f2e824
    			break;
    f2e824
    f2e824
    			case 'oracle':
    f2e824
    				$sql = "SELECT index_name
    f2e824
    					FROM user_indexes
    f2e824
    					WHERE table_name = '" . $table_name . "'
    f2e824
    						AND generated = 'N'";
    f2e824
    			break;
    f2e824
    f2e824
    			case 'sqlite':
    f2e824
    				$sql = "PRAGMA index_info('" . $table_name . "');";
    f2e824
    				$col = 'name';
    f2e824
    			break;
    f2e824
    		}
    f2e824
    f2e824
    		$result = $db->sql_query($sql);
    f2e824
    		while ($row = $db->sql_fetchrow($result))
    f2e824
    		{
    f2e824
    			if (($dbms == 'mysql_40' || $dbms == 'mysql_41') && !$row['Non_unique'])
    f2e824
    			{
    f2e824
    				continue;
    f2e824
    			}
    f2e824
    f2e824
    			switch ($dbms)
    f2e824
    			{
    f2e824
    				case 'firebird':
    f2e824
    				case 'oracle':
    f2e824
    				case 'postgres':
    f2e824
    				case 'sqlite':
    f2e824
    					$row[$col] = substr($row[$col], strlen($table_name) + 1);
    f2e824
    				break;
    f2e824
    			}
    f2e824
    f2e824
    			$index_array[] = $row[$col];
    f2e824
    		}
    f2e824
    		$db->sql_freeresult($result);
    f2e824
    	}
    f2e824
    f2e824
    	return array_map('strtolower', $index_array);
    f2e824
    }
    f2e824
    f2e824
    // This is totally fake, never use it
    f2e824
    // it exists only to mend bad update functions introduced
    f2e824
    // * UNIQUE indices
    f2e824
    // * PRIMARY keys
    f2e824
    function sql_list_fake($dbms, $table_name)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $db;
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	$index_array = array();
    f2e824
    f2e824
    	if ($dbms == 'mssql')
    f2e824
    	{
    f2e824
    		$sql = "EXEC sp_statistics '$table_name'";
    f2e824
    		$result = $db->sql_query($sql);
    f2e824
    		while ($row = $db->sql_fetchrow($result))
    f2e824
    		{
    f2e824
    			if ($row['TYPE'] == 3)
    f2e824
    			{
    f2e824
    				$index_array[] = $row['INDEX_NAME'];
    f2e824
    			}
    f2e824
    		}
    f2e824
    		$db->sql_freeresult($result);
    f2e824
    	}
    f2e824
    	else
    f2e824
    	{
    f2e824
    		switch ($dbms)
    f2e824
    		{
    f2e824
    			case 'firebird':
    f2e824
    				$sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
    f2e824
    					FROM RDB\$INDICES
    f2e824
    					WHERE RDB\$RELATION_NAME = " . strtoupper($table_name) . "
    f2e824
    						AND RDB\$UNIQUE_FLAG IS NULL
    f2e824
    						AND RDB\$FOREIGN_KEY IS NULL";
    f2e824
    				$col = 'index_name';
    f2e824
    			break;
    f2e824
    f2e824
    			case 'postgres':
    f2e824
    				$sql = "SELECT ic.relname as index_name
    f2e824
    					FROM pg_class bc, pg_class ic, pg_index i
    f2e824
    					WHERE (bc.oid = i.indrelid)
    f2e824
    						AND (ic.oid = i.indexrelid)
    f2e824
    						AND (bc.relname = '" . $table_name . "')
    f2e824
    						AND (i.indisunique != 't')
    f2e824
    						AND (i.indisprimary != 't')";
    f2e824
    				$col = 'index_name';
    f2e824
    			break;
    f2e824
    f2e824
    			case 'mysql_40':
    f2e824
    			case 'mysql_41':
    f2e824
    				$sql = 'SHOW KEYS
    f2e824
    					FROM ' . $table_name;
    f2e824
    				$col = 'Key_name';
    f2e824
    			break;
    f2e824
    f2e824
    			case 'oracle':
    f2e824
    				$sql = "SELECT index_name
    f2e824
    					FROM user_indexes
    f2e824
    					WHERE table_name = '" . $table_name . "'
    f2e824
    						AND generated = 'N'";
    f2e824
    			break;
    f2e824
    f2e824
    			case 'sqlite':
    f2e824
    				$sql = "PRAGMA index_info('" . $table_name . "');";
    f2e824
    				$col = 'name';
    f2e824
    			break;
    f2e824
    		}
    f2e824
    f2e824
    		$result = $db->sql_query($sql);
    f2e824
    		while ($row = $db->sql_fetchrow($result))
    f2e824
    		{
    f2e824
    			if (($dbms == 'mysql_40' || $dbms == 'mysql_41') && !$row['Non_unique'])
    f2e824
    			{
    f2e824
    				continue;
    f2e824
    			}
    f2e824
    f2e824
    			$index_array[] = $row[$col];
    f2e824
    		}
    f2e824
    		$db->sql_freeresult($result);
    f2e824
    	}
    f2e824
    f2e824
    	return array_map('strtolower', $index_array);
    f2e824
    }
    f2e824
    f2e824
    /**
    f2e824
    * Change column type (not name!)
    f2e824
    */
    f2e824
    function sql_column_change($dbms, $table_name, $column_name, $column_data)
    f2e824
    {
    f2e824
    	global $dbms_type_map, $db;
    f2e824
    	global $errored, $error_ary;
    f2e824
    f2e824
    	$column_data = prepare_column_data($dbms, $column_data, $table_name, $column_name);
    f2e824
    f2e824
    	switch ($dbms)
    f2e824
    	{
    f2e824
    		case 'firebird':
    f2e824
    			// Change type...
    f2e824
    			$sql = 'ALTER TABLE "' . $table_name . '" ALTER COLUMN "' . $column_name . '" TYPE ' . ' ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mssql':
    f2e824
    			$sql = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'mysql_40':
    f2e824
    		case 'mysql_41':
    f2e824
    			$sql = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'oracle':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql'];
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'postgres':
    f2e824
    			$sql = 'ALTER TABLE ' . $table_name . ' ';
    f2e824
    f2e824
    			$sql_array = array();
    f2e824
    			$sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type'];
    f2e824
    f2e824
    			if (isset($column_data['null']))
    f2e824
    			{
    f2e824
    				if ($column_data['null'] == 'NOT NULL')
    f2e824
    				{
    f2e824
    					$sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL';
    f2e824
    				}
    f2e824
    				else if ($column_data['null'] == 'NULL')
    f2e824
    				{
    f2e824
    					$sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL';
    f2e824
    				}
    f2e824
    			}
    f2e824
    f2e824
    			if (isset($column_data['default']))
    f2e824
    			{
    f2e824
    				$sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default'];
    f2e824
    			}
    f2e824
    f2e824
    			// we don't want to double up on constraints if we change different number data types
    f2e824
    			if (isset($column_data['constraint']))
    f2e824
    			{
    f2e824
    				$constraint_sql = "SELECT consrc as constraint_data
    f2e824
    							FROM pg_constraint, pg_class bc
    f2e824
    							WHERE conrelid = bc.oid
    f2e824
    								AND bc.relname = '{$table_name}'
    f2e824
    								AND NOT EXISTS (
    f2e824
    									SELECT *
    f2e824
    										FROM pg_constraint as c, pg_inherits as i
    f2e824
    										WHERE i.inhrelid = pg_constraint.conrelid
    f2e824
    											AND c.conname = pg_constraint.conname
    f2e824
    											AND c.consrc = pg_constraint.consrc
    f2e824
    											AND c.conrelid = i.inhparent
    f2e824
    								)";
    f2e824
    f2e824
    				$constraint_exists = false;
    f2e824
    f2e824
    				$result = $db->sql_query($constraint_sql);
    f2e824
    				while ($row = $db->sql_fetchrow($result))
    f2e824
    				{
    f2e824
    					if (trim($row['constraint_data']) == trim($column_data['constraint']))
    f2e824
    					{
    f2e824
    						$constraint_exists = true;
    f2e824
    						break;
    f2e824
    					}
    f2e824
    				}
    f2e824
    				$db->sql_freeresult($result);
    f2e824
    f2e824
    				if (!$constraint_exists)
    f2e824
    				{
    f2e824
    					$sql_array[] = 'ADD ' . $column_data['constraint'];
    f2e824
    				}
    f2e824
    			}
    f2e824
    f2e824
    			$sql .= implode(', ', $sql_array);
    f2e824
    f2e824
    			_sql($sql, $errored, $error_ary);
    f2e824
    		break;
    f2e824
    f2e824
    		case 'sqlite':
    f2e824
    f2e824
    			$sql = "SELECT sql
    f2e824
    				FROM sqlite_master
    f2e824
    				WHERE type = 'table'
    f2e824
    					AND name = '{$table_name}'
    f2e824
    				ORDER BY type DESC, name;";
    f2e824
    			$result = _sql($sql, $errored, $error_ary);
    f2e824
    f2e824
    			if (!$result)
    f2e824
    			{
    f2e824
    				break;
    f2e824
    			}
    f2e824
    f2e824
    			$row = $db->sql_fetchrow($result);
    f2e824
    			$db->sql_freeresult($result);
    f2e824
    f2e824
    			$db->sql_transaction('begin');
    f2e824
    f2e824
    			// Create a temp table and populate it, destroy the existing one
    f2e824
    			$db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
    f2e824
    			$db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
    f2e824
    			$db->sql_query('DROP TABLE ' . $table_name);
    f2e824
    f2e824
    			preg_match('#\((.*)\)#s', $row['sql'], $matches);
    f2e824
    f2e824
    			$new_table_cols = trim($matches[1]);
    f2e824
    			$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
    f2e824
    			$column_list = array();
    f2e824
    f2e824
    			foreach ($old_table_cols as $key => $declaration)
    f2e824
    			{
    f2e824
    				$entities = preg_split('#\s+#', trim($declaration));
    f2e824
    				$column_list[] = $entities[0];
    f2e824
    				if ($entities[0] == $column_name)
    f2e824
    				{
    f2e824
    					$old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql'];
    f2e824
    				}
    f2e824
    			}
    f2e824
    f2e824
    			$columns = implode(',', $column_list);
    f2e824
    f2e824
    			// create a new table and fill it up. destroy the temp one
    f2e824
    			$db->sql_query('CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');');
    f2e824
    			$db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
    f2e824
    			$db->sql_query('DROP TABLE ' . $table_name . '_temp');
    f2e824
    f2e824
    			$db->sql_transaction('commit');
    f2e824
    f2e824
    		break;
    f2e824
    	}
    f2e824
    }
    f2e824
    f2e824
    function utf8_new_clean_string($text)
    f2e824
    {
    f2e824
    	static $homographs = array();
    f2e824
    	static $utf8_case_fold_nfkc = '';
    f2e824
    	if (empty($homographs))
    f2e824
    	{
    f2e824
    		global $phpbb_root_path, $phpEx;
    f2e824
    		if (!function_exists('utf8_case_fold_nfkc') || !file_exists($phpbb_root_path . 'includes/utf/data/confusables.' . $phpEx))
    f2e824
    		{
    f2e824
    			if (!file_exists($phpbb_root_path . 'install/data/confusables.' . $phpEx))
    f2e824
    			{
    f2e824
    				global $lang;
    f2e824
    				trigger_error(sprintf($lang['UPDATE_REQUIRES_FILE'], $phpbb_root_path . 'install/data/confusables.' . $phpEx), E_USER_ERROR);
    f2e824
    			}
    f2e824
    			$homographs = include($phpbb_root_path . 'install/data/confusables.' . $phpEx);
    f2e824
    			$utf8_case_fold_nfkc = 'utf8_new_case_fold_nfkc';
    f2e824
    		}
    f2e824
    		else
    f2e824
    		{
    f2e824
    			$homographs = include($phpbb_root_path . 'includes/utf/data/confusables.' . $phpEx);
    f2e824
    			$utf8_case_fold_nfkc = 'utf8_case_fold_nfkc';
    f2e824
    		}
    f2e824
    	}
    f2e824
    f2e824
    	$text = $utf8_case_fold_nfkc($text);
    f2e824
    	$text = strtr($text, $homographs);
    f2e824
    	// Other control characters
    f2e824
    	$text = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $text);
    f2e824
    f2e824
    	$text = preg_replace('# {2,}#', ' ', $text);
    f2e824
    f2e824
    	// we can use trim here as all the other space characters should have been turned
    f2e824
    	// into normal ASCII spaces by now
    f2e824
    	return trim($text);
    f2e824
    }
    f2e824
    f2e824
    ?>