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

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

ef5584
ef5584
	
ef5584
ef5584
	

:: sql_layer; ?>

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

';
ef5584
ef5584
$current_version = str_replace('rc', 'RC', strtolower($config['version']));
ef5584
$latest_version = str_replace('rc', 'RC', strtolower($updates_to_version));
ef5584
$orig_version = $config['version'];
ef5584
ef5584
// If the latest version and the current version are 'unequal', we will update the version_update_from, else we do not update anything.
ef5584
if ($inline_update)
ef5584
{
ef5584
	if ($current_version !== $latest_version)
ef5584
	{
ef5584
		set_config('version_update_from', $orig_version);
ef5584
	}
ef5584
}
ef5584
else
ef5584
{
ef5584
	// If not called from the update script, we will actually remove the traces
ef5584
	$db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'");
ef5584
}
ef5584
ef5584
// Checks/Operations that have to be completed prior to starting the update itself
ef5584
$exit = false;
ef5584
if (version_compare($current_version, '3.0.RC8', '<=')) /* && $debug_from_version === false) */
ef5584
{
ef5584
	// Define missing language entries...
ef5584
	if (!isset($lang['CLEANING_USERNAMES']))
ef5584
	{
ef5584
		$lang = array_merge($lang, array(
ef5584
			'CLEANING_USERNAMES'		=> 'Cleaning usernames',
ef5584
			'LONG_SCRIPT_EXECUTION'		=> 'Please note that this can take a while... Please do not stop the script.',
ef5584
			'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.',
ef5584
			'USER_ACTIVE'				=> 'Active user',
ef5584
			'USER_INACTIVE'				=> 'Inactive user',
ef5584
			'BOT'						=> 'Spider/Robot',
ef5584
			'UPDATE_REQUIRES_FILE'		=> 'The updater requires that the following file is present: %s',
ef5584
ef5584
			'DELETE_USER_REMOVE'		=> 'Delete user and remove posts',
ef5584
			'DELETE_USER_RETAIN'		=> 'Delete user but keep posts',
ef5584
			'EDIT_USERNAME'				=> 'Edit username',
ef5584
			'KEEP_OLD_NAME'				=> 'Keep username',
ef5584
			'NEW_USERNAME'				=> 'New username',
ef5584
		));
ef5584
	}
ef5584
?>
ef5584
	

ef5584
ef5584
	

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

' . $lang[$error] . '

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

ef5584
	

::

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


ef5584
ef5584

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

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

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

ef5584
ef5584
	

ef5584
ef5584
	
ef5584
	

::

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


ef5584

ef5584

ef5584

::

ef5584
ef5584
ef5584
ef5584
flush();
ef5584
ef5584
$no_updates = true;
ef5584
$versions = array_keys($database_update_info);
ef5584
ef5584
// some code magic
ef5584
for ($i = 0; $i < sizeof($versions); $i++)
ef5584
{
ef5584
	$version = $versions[$i];
ef5584
	$next_version = (isset($versions[$i + 1])) ? $versions[$i + 1] : $updates_to_version;
ef5584
ef5584
	// 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
ef5584
	if (version_compare($version, $current_version, '<') && version_compare($current_version, $next_version, '>='))
ef5584
	{
ef5584
		continue;
ef5584
	}
ef5584
ef5584
/*	if ($debug_from_version !== false)
ef5584
	{
ef5584
		// Applying update schema for version array with key '$version'
ef5584
		// for version '$version' to '$next_version'
ef5584
		continue;
ef5584
	}*/
ef5584
ef5584
	change_database_data($no_updates, $version);
ef5584
}
ef5584
ef5584
_write_result($no_updates, $errored, $error_ary);
ef5584
ef5584
$error_ary = array();
ef5584
$errored = $no_updates = false;
ef5584
ef5584
?>
ef5584
ef5584


ef5584

ef5584

ef5584

::

ef5584
ef5584
ef5584
ef5584
flush();
ef5584
ef5584
//if ($debug_from_version === false)
ef5584
// {
ef5584
ef5584
// update the version
ef5584
$sql = "UPDATE " . CONFIG_TABLE . "
ef5584
	SET config_value = '$updates_to_version'
ef5584
	WHERE config_name = 'version'";
ef5584
_sql($sql, $errored, $error_ary);
ef5584
ef5584
// Reset permissions
ef5584
$sql = 'UPDATE ' . USERS_TABLE . "
ef5584
	SET user_permissions = '',
ef5584
		user_perm_from = 0";
ef5584
_sql($sql, $errored, $error_ary);
ef5584
ef5584
// }
ef5584
ef5584
/* Optimize/vacuum analyze the tables where appropriate
ef5584
// this should be done for each version in future along with
ef5584
// the version number update
ef5584
switch ($db->sql_layer)
ef5584
{
ef5584
	case 'mysql':
ef5584
	case 'mysqli':
ef5584
	case 'mysql4':
ef5584
		$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';
ef5584
		_sql($sql, $errored, $error_ary);
ef5584
	break;
ef5584
ef5584
	case 'postgresql':
ef5584
		_sql("VACUUM ANALYZE", $errored, $error_ary);
ef5584
	break;
ef5584
}
ef5584
*/
ef5584
ef5584
_write_result($no_updates, $errored, $error_ary);
ef5584
ef5584
?>
ef5584
ef5584

ef5584

ef5584
ef5584

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

ef5584
ef5584
	

ef5584
ef5584
ef5584
}
ef5584
else
ef5584
{
ef5584
?>
ef5584
ef5584
	

ef5584
ef5584
	

" class="button1">

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

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

    ';
    ef5584
    			}
    ef5584
    ef5584
    			echo ' 

    ' . $lang['SQL_FAILURE_EXPLAIN'] . '

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

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