aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/install/database_update.php
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/install/database_update.php')
-rw-r--r--phpBB/install/database_update.php3737
1 files changed, 1474 insertions, 2263 deletions
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index fb37b62203..ee28799694 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -8,7 +8,10 @@
*
*/
-$updates_to_version = '3.0.4';
+$updates_to_version = '3.0.5-RC1';
+
+// Enter any version to update from to test updates. The version within the db will not be updated.
+$debug_from_version = false;
// Return if we "just include it" to find out for which version the database update is responsible for
if (defined('IN_PHPBB') && defined('IN_INSTALL'))
@@ -140,489 +143,24 @@ include($phpbb_root_path . 'language/' . $language . '/install.' . $phpEx);
// Define some variables for the database update
$inline_update = (request_var('type', 0)) ? true : false;
-// Database column types mapping
-$dbms_type_map = array(
- 'mysql_41' => array(
- 'INT:' => 'int(%d)',
- 'BINT' => 'bigint(20)',
- 'UINT' => 'mediumint(8) UNSIGNED',
- 'UINT:' => 'int(%d) UNSIGNED',
- 'TINT:' => 'tinyint(%d)',
- 'USINT' => 'smallint(4) UNSIGNED',
- 'BOOL' => 'tinyint(1) UNSIGNED',
- 'VCHAR' => 'varchar(255)',
- 'VCHAR:' => 'varchar(%d)',
- 'CHAR:' => 'char(%d)',
- 'XSTEXT' => 'text',
- 'XSTEXT_UNI'=> 'varchar(100)',
- 'STEXT' => 'text',
- 'STEXT_UNI' => 'varchar(255)',
- 'TEXT' => 'text',
- 'TEXT_UNI' => 'text',
- 'MTEXT' => 'mediumtext',
- 'MTEXT_UNI' => 'mediumtext',
- 'TIMESTAMP' => 'int(11) UNSIGNED',
- 'DECIMAL' => 'decimal(5,2)',
- 'VCHAR_UNI' => 'varchar(255)',
- 'VCHAR_UNI:'=> 'varchar(%d)',
- 'VCHAR_CI' => 'varchar(255)',
- 'VARBINARY' => 'varbinary(255)',
- ),
-
- 'mysql_40' => array(
- 'INT:' => 'int(%d)',
- 'BINT' => 'bigint(20)',
- 'UINT' => 'mediumint(8) UNSIGNED',
- 'UINT:' => 'int(%d) UNSIGNED',
- 'TINT:' => 'tinyint(%d)',
- 'USINT' => 'smallint(4) UNSIGNED',
- 'BOOL' => 'tinyint(1) UNSIGNED',
- 'VCHAR' => 'varbinary(255)',
- 'VCHAR:' => 'varbinary(%d)',
- 'CHAR:' => 'binary(%d)',
- 'XSTEXT' => 'blob',
- 'XSTEXT_UNI'=> 'blob',
- 'STEXT' => 'blob',
- 'STEXT_UNI' => 'blob',
- 'TEXT' => 'blob',
- 'TEXT_UNI' => 'blob',
- 'MTEXT' => 'mediumblob',
- 'MTEXT_UNI' => 'mediumblob',
- 'TIMESTAMP' => 'int(11) UNSIGNED',
- 'DECIMAL' => 'decimal(5,2)',
- 'VCHAR_UNI' => 'blob',
- 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')),
- 'VCHAR_CI' => 'blob',
- 'VARBINARY' => 'varbinary(255)',
- ),
-
- 'firebird' => array(
- 'INT:' => 'INTEGER',
- 'BINT' => 'DOUBLE PRECISION',
- 'UINT' => 'INTEGER',
- 'UINT:' => 'INTEGER',
- 'TINT:' => 'INTEGER',
- 'USINT' => 'INTEGER',
- 'BOOL' => 'INTEGER',
- 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE',
- 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE',
- 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE',
- 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
- 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8',
- 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
- 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
- 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
- 'TIMESTAMP' => 'INTEGER',
- 'DECIMAL' => 'DOUBLE PRECISION',
- 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
- 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8',
- 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8',
- 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE',
- ),
-
- 'mssql' => array(
- 'INT:' => '[int]',
- 'BINT' => '[float]',
- 'UINT' => '[int]',
- 'UINT:' => '[int]',
- 'TINT:' => '[int]',
- 'USINT' => '[int]',
- 'BOOL' => '[int]',
- 'VCHAR' => '[varchar] (255)',
- 'VCHAR:' => '[varchar] (%d)',
- 'CHAR:' => '[char] (%d)',
- 'XSTEXT' => '[varchar] (1000)',
- 'STEXT' => '[varchar] (3000)',
- 'TEXT' => '[varchar] (8000)',
- 'MTEXT' => '[text]',
- 'XSTEXT_UNI'=> '[varchar] (100)',
- 'STEXT_UNI' => '[varchar] (255)',
- 'TEXT_UNI' => '[varchar] (4000)',
- 'MTEXT_UNI' => '[text]',
- 'TIMESTAMP' => '[int]',
- 'DECIMAL' => '[float]',
- 'VCHAR_UNI' => '[varchar] (255)',
- 'VCHAR_UNI:'=> '[varchar] (%d)',
- 'VCHAR_CI' => '[varchar] (255)',
- 'VARBINARY' => '[varchar] (255)',
- ),
-
- 'oracle' => array(
- 'INT:' => 'number(%d)',
- 'BINT' => 'number(20)',
- 'UINT' => 'number(8)',
- 'UINT:' => 'number(%d)',
- 'TINT:' => 'number(%d)',
- 'USINT' => 'number(4)',
- 'BOOL' => 'number(1)',
- 'VCHAR' => 'varchar2(255)',
- 'VCHAR:' => 'varchar2(%d)',
- 'CHAR:' => 'char(%d)',
- 'XSTEXT' => 'varchar2(1000)',
- 'STEXT' => 'varchar2(3000)',
- 'TEXT' => 'clob',
- 'MTEXT' => 'clob',
- 'XSTEXT_UNI'=> 'varchar2(300)',
- 'STEXT_UNI' => 'varchar2(765)',
- 'TEXT_UNI' => 'clob',
- 'MTEXT_UNI' => 'clob',
- 'TIMESTAMP' => 'number(11)',
- 'DECIMAL' => 'number(5, 2)',
- 'VCHAR_UNI' => 'varchar2(765)',
- 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')),
- 'VCHAR_CI' => 'varchar2(255)',
- 'VARBINARY' => 'raw(255)',
- ),
-
- 'sqlite' => array(
- 'INT:' => 'int(%d)',
- 'BINT' => 'bigint(20)',
- 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED',
- 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED',
- 'TINT:' => 'tinyint(%d)',
- 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED',
- 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED',
- 'VCHAR' => 'varchar(255)',
- 'VCHAR:' => 'varchar(%d)',
- 'CHAR:' => 'char(%d)',
- 'XSTEXT' => 'text(65535)',
- 'STEXT' => 'text(65535)',
- 'TEXT' => 'text(65535)',
- 'MTEXT' => 'mediumtext(16777215)',
- 'XSTEXT_UNI'=> 'text(65535)',
- 'STEXT_UNI' => 'text(65535)',
- 'TEXT_UNI' => 'text(65535)',
- 'MTEXT_UNI' => 'mediumtext(16777215)',
- 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
- 'DECIMAL' => 'decimal(5,2)',
- 'VCHAR_UNI' => 'varchar(255)',
- 'VCHAR_UNI:'=> 'varchar(%d)',
- 'VCHAR_CI' => 'varchar(255)',
- 'VARBINARY' => 'blob',
- ),
-
- 'postgres' => array(
- 'INT:' => 'INT4',
- 'BINT' => 'INT8',
- 'UINT' => 'INT4', // unsigned
- 'UINT:' => 'INT4', // unsigned
- 'USINT' => 'INT2', // unsigned
- 'BOOL' => 'INT2', // unsigned
- 'TINT:' => 'INT2',
- 'VCHAR' => 'varchar(255)',
- 'VCHAR:' => 'varchar(%d)',
- 'CHAR:' => 'char(%d)',
- 'XSTEXT' => 'varchar(1000)',
- 'STEXT' => 'varchar(3000)',
- 'TEXT' => 'varchar(8000)',
- 'MTEXT' => 'TEXT',
- 'XSTEXT_UNI'=> 'varchar(100)',
- 'STEXT_UNI' => 'varchar(255)',
- 'TEXT_UNI' => 'varchar(4000)',
- 'MTEXT_UNI' => 'TEXT',
- 'TIMESTAMP' => 'INT4', // unsigned
- 'DECIMAL' => 'decimal(5,2)',
- 'VCHAR_UNI' => 'varchar(255)',
- 'VCHAR_UNI:'=> 'varchar(%d)',
- 'VCHAR_CI' => 'varchar_ci',
- 'VARBINARY' => 'bytea',
- ),
-);
-
-// A list of types being unsigned for better reference in some db's
-$unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP');
-
-// Only an example, but also commented out
-$database_update_info = array(
- // Changes from 3.0.RC2 to the next version
- '3.0.RC2' => array(
- // Change the following columns
- 'change_columns' => array(
- BANLIST_TABLE => array(
- 'ban_reason' => array('VCHAR_UNI', ''),
- 'ban_give_reason' => array('VCHAR_UNI', ''),
- ),
- ),
- ),
- // Changes from 3.0.RC3 to the next version
- '3.0.RC3' => array(
- // Change the following columns
- 'change_columns' => array(
- BANLIST_TABLE => array(
- 'ban_reason' => array('VCHAR_UNI', ''),
- 'ban_give_reason' => array('VCHAR_UNI', ''),
- ),
- STYLES_TABLE => array(
- 'style_id' => array('USINT', 0),
- 'template_id' => array('USINT', 0),
- 'theme_id' => array('USINT', 0),
- 'imageset_id' => array('USINT', 0),
- ),
- STYLES_TEMPLATE_TABLE => array(
- 'template_id' => array('USINT', 0),
- ),
- STYLES_TEMPLATE_DATA_TABLE => array(
- 'template_id' => array('USINT', 0),
- ),
- STYLES_THEME_TABLE => array(
- 'theme_id' => array('USINT', 0),
- ),
- STYLES_IMAGESET_TABLE => array(
- 'imageset_id' => array('USINT', 0),
- ),
- STYLES_IMAGESET_DATA_TABLE => array(
- 'imageset_id' => array('USINT', 0),
- ),
- USERS_TABLE => array(
- 'user_style' => array('USINT', 0),
- ),
- FORUMS_TABLE => array(
- 'forum_style' => array('USINT', 0),
- ),
- GROUPS_TABLE => array(
- 'group_avatar_type' => array('TINT:2', 0),
- 'group_avatar_width' => array('USINT', 0),
- 'group_avatar_height' => array('USINT', 0),
- ),
- ),
- ),
- // Changes from 3.0.RC4 to the next version
- '3.0.RC4' => array(
- // Change the following columns
- 'change_columns' => array(
- STYLES_TABLE => array(
- 'style_id' => array('USINT', NULL, 'auto_increment'),
- 'template_id' => array('USINT', 0),
- 'theme_id' => array('USINT', 0),
- 'imageset_id' => array('USINT', 0),
- ),
- STYLES_TEMPLATE_TABLE => array(
- 'template_id' => array('USINT', NULL, 'auto_increment'),
- ),
- STYLES_TEMPLATE_DATA_TABLE => array(
- 'template_id' => array('USINT', 0),
- ),
- STYLES_THEME_TABLE => array(
- 'theme_id' => array('USINT', NULL, 'auto_increment'),
- ),
- STYLES_IMAGESET_TABLE => array(
- 'imageset_id' => array('USINT', NULL, 'auto_increment'),
- ),
- STYLES_IMAGESET_DATA_TABLE => array(
- 'imageset_id' => array('USINT', 0),
- ),
- USERS_TABLE => array(
- 'user_style' => array('USINT', 0),
- ),
- FORUMS_TABLE => array(
- 'forum_style' => array('USINT', 0),
- ),
- GROUPS_TABLE => array(
- 'group_avatar_width' => array('USINT', 0),
- 'group_avatar_height' => array('USINT', 0),
- ),
- ),
- ),
- // Changes from 3.0.RC5 to the next version
- '3.0.RC5' => array(
- // Add the following columns
- 'add_columns' => array(
- USERS_TABLE => array(
- 'user_form_salt' => array('VCHAR_UNI:32', ''),
- ),
- ),
- // Change the following columns
- 'change_columns' => array(
- POSTS_TABLE => array(
- 'bbcode_uid' => array('VCHAR:8', ''),
- ),
- PRIVMSGS_TABLE => array(
- 'bbcode_uid' => array('VCHAR:8', ''),
- ),
- USERS_TABLE => array(
- 'user_sig_bbcode_uid' => array('VCHAR:8', ''),
- ),
- ),
- ),
- // Changes from 3.0.RC6 to the next version
- '3.0.RC6' => array(
- // Change the following columns
- 'change_columns' => array(
- FORUMS_TABLE => array(
- 'forum_desc_uid' => array('VCHAR:8', ''),
- 'forum_rules_uid' => array('VCHAR:8', ''),
- ),
- GROUPS_TABLE => array(
- 'group_desc_uid' => array('VCHAR:8', ''),
- ),
- USERS_TABLE => array(
- 'user_newpasswd' => array('VCHAR_UNI:40', ''),
- ),
- ),
- ),
- // Changes from 3.0.RC8 to the next version
- '3.0.RC8' => array(
- // Change the following columns
- 'change_columns' => array(
- USERS_TABLE => array(
- 'user_new_privmsg' => array('INT:4', 0),
- 'user_unread_privmsg' => array('INT:4', 0),
- ),
- ),
- ),
- // Changes from 3.0.0 to the next version
- '3.0.0' => array(
- // Add the following columns
- 'add_columns' => array(
- FORUMS_TABLE => array(
- 'display_subforum_list' => array('BOOL', 1),
- ),
- SESSIONS_TABLE => array(
- 'session_forum_id' => array('UINT', 0),
- ),
- ),
- 'add_index' => array(
- SESSIONS_TABLE => array(
- 'session_forum_id' => array('session_forum_id'),
- ),
- GROUPS_TABLE => array(
- 'group_legend_name' => array('group_legend', 'group_name'),
- ),
- ),
- 'drop_keys' => array(
- GROUPS_TABLE => array('group_legend'),
- ),
- ),
- // No changes from 3.0.1-RC1 to 3.0.1
- '3.0.1-RC1' => array(),
- // No changes from 3.0.1 to 3.0.2-RC1
- '3.0.1' => array(),
- // Changes from 3.0.2-RC1 to 3.0.2-RC2
- '3.0.2-RC1' => array(
- 'change_columns' => array(
- DRAFTS_TABLE => array(
- 'draft_subject' => array('STEXT_UNI', ''),
- ),
- FORUMS_TABLE => array(
- 'forum_last_post_subject' => array('STEXT_UNI', ''),
- ),
- POSTS_TABLE => array(
- 'post_subject' => array('STEXT_UNI', '', 'true_sort'),
- ),
- PRIVMSGS_TABLE => array(
- 'message_subject' => array('STEXT_UNI', ''),
- ),
- TOPICS_TABLE => array(
- 'topic_title' => array('STEXT_UNI', '', 'true_sort'),
- 'topic_last_post_subject' => array('STEXT_UNI', ''),
- ),
- ),
- 'drop_keys' => array(
- SESSIONS_TABLE => array('session_forum_id'),
- ),
- 'add_index' => array(
- SESSIONS_TABLE => array(
- 'session_fid' => array('session_forum_id'),
- ),
- ),
- ),
- // No changes from 3.0.2-RC2 to 3.0.2
- '3.0.2-RC2' => array(),
-
- // Changes from 3.0.2 to 3.0.3-RC1
- '3.0.2' => array(
- // Add the following columns
- 'add_columns' => array(
- STYLES_TEMPLATE_TABLE => array(
- 'template_inherits_id' => array('UINT:4', 0),
- 'template_inherit_path' => array('VCHAR', ''),
- ),
- GROUPS_TABLE => array(
- 'group_max_recipients' => array('UINT', 0),
- ),
- ),
- ),
-
- // No changes from 3.0.3-RC1 to 3.0.3
- '3.0.3-RC1' => array(),
-
- // Changes from 3.0.3 to 3.0.4-RC1
- '3.0.3' => array(
- 'add_columns' => array(
- PROFILE_FIELDS_TABLE => array(
- 'field_show_profile' => array('BOOL', 0),
- ),
- ),
- 'change_columns' => array(
- STYLES_TABLE => array(
- 'style_id' => array('UINT', NULL, 'auto_increment'),
- 'template_id' => array('UINT', 0),
- 'theme_id' => array('UINT', 0),
- 'imageset_id' => array('UINT', 0),
- ),
- STYLES_IMAGESET_TABLE => array(
- 'imageset_id' => array('UINT', NULL, 'auto_increment'),
- ),
- STYLES_IMAGESET_DATA_TABLE => array(
- 'image_id' => array('UINT', NULL, 'auto_increment'),
- 'imageset_id' => array('UINT', 0),
- ),
- STYLES_THEME_TABLE => array(
- 'theme_id' => array('UINT', NULL, 'auto_increment'),
- ),
- STYLES_TEMPLATE_TABLE => array(
- 'template_id' => array('UINT', NULL, 'auto_increment'),
- ),
- STYLES_TEMPLATE_DATA_TABLE => array(
- 'template_id' => array('UINT', 0),
- ),
- FORUMS_TABLE => array(
- 'forum_style' => array('USINT', 0),
- ),
- USERS_TABLE => array(
- 'user_style' => array('UINT', 0),
- ),
- ),
- ),
+// To let set_config() calls succeed, we need to make the config array available globally
+$config = array();
- // Changes from 3.0.4-RC1 to 3.0.4
- '3.0.4-RC1' => array(),
-);
+$sql = 'SELECT *
+ FROM ' . CONFIG_TABLE;
+$result = $db->sql_query($sql);
-// Determine mapping database type
-switch ($db->sql_layer)
+while ($row = $db->sql_fetchrow($result))
{
- case 'mysql':
- $map_dbms = 'mysql_40';
- break;
-
- case 'mysql4':
- if (version_compare($db->sql_server_info(true), '4.1.3', '>='))
- {
- $map_dbms = 'mysql_41';
- }
- else
- {
- $map_dbms = 'mysql_40';
- }
- break;
-
- case 'mysqli':
- $map_dbms = 'mysql_41';
- break;
+ $config[$row['config_name']] = $row['config_value'];
+}
+$db->sql_freeresult($result);
- case 'mssql':
- case 'mssql_odbc':
- $map_dbms = 'mssql';
- break;
+// We do not include DB Tools here, because we can not be sure the file is up-to-date ;)
+// Instead, this file defines a clean db_tools version (we are also not able to provide a different file, else the database update will not work standalone)
+$db_tools = new updater_db_tools($db, true);
- default:
- $map_dbms = $db->sql_layer;
- break;
-}
+$database_update_info = database_update_info();
$error_ary = array();
$errored = false;
@@ -654,7 +192,7 @@ header('Content-type: text/html; charset=UTF-8');
<div class="panel">
<span class="corners-top"><span></span></span>
<div id="content">
- <div id="main">
+ <div id="main" class="install-body">
<h1><?php echo $lang['UPDATING_TO_LATEST_STABLE']; ?></h1>
@@ -663,22 +201,10 @@ header('Content-type: text/html; charset=UTF-8');
<p><?php echo $lang['DATABASE_TYPE']; ?> :: <strong><?php echo $db->sql_layer; ?></strong><br />
<?php
-// To let set_config() calls succeed, we need to make the config array available globally
-$config = array();
-$sql = 'SELECT *
- FROM ' . CONFIG_TABLE;
-$result = $db->sql_query($sql);
-
-while ($row = $db->sql_fetchrow($result))
-{
- $config[$row['config_name']] = $row['config_value'];
-}
-$db->sql_freeresult($result);
-
-/*if ($debug_from_version !== false)
+if ($debug_from_version !== false)
{
$config['version'] = $debug_from_version;
-}*/
+}
echo $lang['PREVIOUS_VERSION'] . ' :: <strong>' . $config['version'] . '</strong><br />';
echo $lang['UPDATED_VERSION'] . ' :: <strong>' . $updates_to_version . '</strong></p>';
@@ -687,464 +213,40 @@ $current_version = str_replace('rc', 'RC', strtolower($config['version']));
$latest_version = str_replace('rc', 'RC', strtolower($updates_to_version));
$orig_version = $config['version'];
-// If the latest version and the current version are 'unequal', we will update the version_update_from, else we do not update anything.
-if ($inline_update)
-{
- if ($current_version !== $latest_version)
- {
- set_config('version_update_from', $orig_version);
- }
-}
-else
+// Fill DB version
+if (empty($config['dbms_version']))
{
- // If not called from the update script, we will actually remove the traces
- $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'");
+ set_config('dbms_version', $db->sql_server_info(true));
}
-// Checks/Operations that have to be completed prior to starting the update itself
-$exit = false;
-if (version_compare($current_version, '3.0.RC8', '<=')) /* && $debug_from_version === false) */
+// MySQL update from MySQL 3.x/4.x to > 4.1.x required?
+if ($db->sql_layer == 'mysql' || $db->sql_layer == 'mysql4' || $db->sql_layer == 'mysqli')
{
- // Define missing language entries...
- if (!isset($lang['CLEANING_USERNAMES']))
- {
- $lang = array_merge($lang, array(
- 'CLEANING_USERNAMES' => 'Cleaning usernames',
- 'LONG_SCRIPT_EXECUTION' => 'Please note that this can take a while... Please do not stop the script.',
- '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.',
- 'USER_ACTIVE' => 'Active user',
- 'USER_INACTIVE' => 'Inactive user',
- 'BOT' => 'Spider/Robot',
- 'UPDATE_REQUIRES_FILE' => 'The updater requires that the following file is present: %s',
-
- 'DELETE_USER_REMOVE' => 'Delete user and remove posts',
- 'DELETE_USER_RETAIN' => 'Delete user but keep posts',
- 'EDIT_USERNAME' => 'Edit username',
- 'KEEP_OLD_NAME' => 'Keep username',
- 'NEW_USERNAME' => 'New username',
- ));
- }
-?>
- <br /><br />
-
- <h1><?php echo $lang['CLEANING_USERNAMES']; ?></h1>
-
- <br />
-
-<?php
- flush();
-
- $submit = (isset($_POST['resolve_conflicts'])) ? true : false;
- $modify_users = request_var('modify_users', array(0 => ''));
- $new_usernames = request_var('new_usernames', array(0 => ''), true);
-
- // We need this file if someone wants to edit usernames.
- include($phpbb_root_path . 'includes/utf/utf_normalizer.' . $phpEx);
-
- if (!class_exists('utf_new_normalizer'))
- {
- if (!file_exists($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx))
- {
- global $lang;
- trigger_error(sprintf($lang['UPDATE_REQUIRES_FILE'], $phpbb_root_path . 'install/data/new_normalizer.' . $phpEx), E_USER_ERROR);
- }
- include($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx);
- }
-
- // the admin decided to change some usernames
- if (sizeof($modify_users) && $submit)
- {
- $sql = 'SELECT user_id, username, user_type
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', array_keys($modify_users));
- $result = $db->sql_query($sql);
-
- $users = 0;
- while ($row = $db->sql_fetchrow($result))
- {
- $users++;
- $user_id = (int) $row['user_id'];
-
- if (isset($modify_users[$user_id]))
- {
- $row['action'] = $modify_users[$user_id];
- $modify_users[$user_id] = $row;
- }
- }
- $db->sql_freeresult($result);
-
- // only if all ids really existed
- if (sizeof($modify_users) == $users)
- {
- $user->data['user_id'] = ANONYMOUS;
- include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
- foreach ($modify_users as $user_id => $row)
- {
- switch ($row['action'])
- {
- case 'edit':
- if (isset($new_usernames[$user_id]))
- {
- $data = array('username' => utf8_new_normalize_nfc($new_usernames[$user_id]));
- // Need to update config, forum, topic, posting, messages, etc.
- if ($data['username'] != $row['username'])
- {
- $check_ary = array('username' => array(
- array('string', false, $config['min_name_chars'], $config['max_name_chars']),
- array('username'),
- ));
- // need a little trick for this to work properly
- $user->data['username_clean'] = utf8_clean_string($data['username']) . 'a';
- $errors = validate_data($data, $check_ary);
-
- if ($errors)
- {
- include($phpbb_root_path . 'language/' . $language . '/ucp.' . $phpEx);
- echo '<div class="errorbox">';
- foreach ($errors as $error)
- {
- echo '<p>' . $lang[$error] . '</p>';
- }
- echo '</div>';
- }
-
- if (!$errors)
- {
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET ' . $db->sql_build_array('UPDATE', array(
- 'username' => $data['username'],
- 'username_clean' => utf8_clean_string($data['username'])
- )) . '
- WHERE user_id = ' . $user_id;
- $db->sql_query($sql);
-
- add_log('user', $user_id, 'LOG_USER_UPDATE_NAME', $row['username'], $data['username']);
- user_update_name($row['username'], $data['username']);
- }
- }
- }
- break;
-
- case 'delete_retain':
- case 'delete_remove':
- if ($user_id != ANONYMOUS && $row['user_type'] != USER_FOUNDER)
- {
- user_delete(substr($row['action'], 7), $user_id, $row['username']);
- add_log('admin', 'LOG_USER_DELETED', $row['username']);
- }
- break;
- }
- }
- }
- }
-?>
-
- <p><?php echo $lang['LONG_SCRIPT_EXECUTION']; ?></p>
- <p><?php echo $lang['PROGRESS']; ?> :: <strong>
-
-<?php
- flush();
-
- // after RC3 a different utf8_clean_string function is used, this requires that
- // the unique column username_clean is recalculated, during this recalculation
- // duplicates might be created. Since the column has to be unique such usernames
- // must not exist. We need identify them and let the admin decide what to do
- // about them.
- // After RC8 this was changed again, but this time only usernames containing spaces
- // are affected.
- $sql_where = (version_compare($current_version, '3.0.RC4', '<=')) ? '' : "WHERE username_clean LIKE '% %'";
- $sql = 'SELECT user_id, username, username_clean
- FROM ' . USERS_TABLE . "
- $sql_where
- ORDER BY user_id ASC";
+ // Verify by fetching column... if the column type matches the new type we update dbms_version...
+ $sql = "SHOW COLUMNS FROM " . CONFIG_TABLE;
$result = $db->sql_query($sql);
- $colliding_users = $found_names = array();
- $echos = 0;
-
+ $column_type = '';
while ($row = $db->sql_fetchrow($result))
{
- // Calculate the new clean name. If it differs from the old one we need
- // to make sure there is no collision
- $clean_name = utf8_new_clean_string($row['username']);
+ $field = strtolower($row['Field']);
- if ($clean_name != $row['username_clean'])
+ if ($field == 'config_value')
{
- // Check if there would be a collission, if not put it up for changing
- $user_id = (int) $row['user_id'];
-
- // If this clean name was not the result of another user already ...
- if (!isset($found_names[$clean_name]))
- {
- // then we need to figure out whether there are any other users
- // who already had this clean name with the old version
- $sql = 'SELECT user_id, username
- FROM ' . USERS_TABLE . '
- WHERE username_clean = \'' . $db->sql_escape($clean_name) . '\'';
- $result2 = $db->sql_query($sql);
-
- $user_ids = array($user_id);
- while ($row = $db->sql_fetchrow($result2))
- {
- // For not trimmed entries this could happen, yes. ;)
- if ($row['user_id'] == $user_id)
- {
- continue;
- }
-
- // Make sure this clean name will still be the same with the
- // new function. If it is, then we have to add it to the list
- // of user ids for this clean name
- if (utf8_new_clean_string($row['username']) == $clean_name)
- {
- $user_ids[] = (int) $row['user_id'];
- }
- }
- $db->sql_freeresult($result2);
-
- // if we already found a collision save it
- if (sizeof($user_ids) > 1)
- {
- $colliding_users[$clean_name] = $user_ids;
- $found_names[$clean_name] = true;
- }
- else
- {
- // otherwise just mark this name as found
- $found_names[$clean_name] = $user_id;
- }
- }
- // Else, if we already found the username
- else
- {
- // If the value in the found_names lookup table is only true ...
- if ($found_names[$clean_name] === true)
- {
- // then the actual data was already added to $colliding_users
- // and we only need to append the user_id
- $colliding_users[$clean_name][] = $user_id;
- }
- else
- {
- // otherwise it still keeps the first user_id for this name
- // and we need to move the data to $colliding_users, and set
- // the value in the found_names lookup table to true, so
- // following users will directly be appended to $colliding_users
- $colliding_users[$clean_name] = array($found_names[$clean_name], $user_id);
- $found_names[$clean_name] = true;
- }
- }
- }
-
- if (($echos % 1000) == 0)
- {
- echo '.';
- flush();
+ $column_type = strtolower($row['Type']);
+ break;
}
- $echos++;
}
$db->sql_freeresult($result);
- _write_result(false, $errored, $error_ary);
-
- // now retrieve all information about the users and let the admin decide what to do
- if (sizeof($colliding_users))
+ // If column type is blob, but mysql version says we are on > 4.1.3, then the schema needs an update
+ if (strpos($column_type, 'blob') !== false && version_compare($db->sql_server_info(true), '4.1.3', '>='))
{
- $exit = true;
- include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
- include($phpbb_root_path . 'language/' . $language . '/memberlist.' . $phpEx);
- include($phpbb_root_path . 'language/' . $language . '/acp/users.' . $phpEx);
-
- // link a few things to the correct place so we don't get any problems
- $user->lang = &$lang;
- $user->data['user_id'] = ANONYMOUS;
- $user->date_format = $config['default_dateformat'];
-
- // a little trick to get all user_ids
- $user_ids = call_user_func_array('array_merge', array_values($colliding_users));
-
- $sql = 'SELECT session_user_id, MAX(session_time) AS session_time
- FROM ' . SESSIONS_TABLE . '
- WHERE session_time >= ' . (time() - $config['session_length']) . '
- AND ' . $db->sql_in_set('session_user_id', $user_ids) . '
- GROUP BY session_user_id';
- $result = $db->sql_query($sql);
-
- $session_times = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $session_times[$row['session_user_id']] = $row['session_time'];
- }
- $db->sql_freeresult($result);
-
- $sql = 'SELECT *
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', $user_ids);
- $result = $db->sql_query($sql);
-
- $users = array();
- while ($row = $db->sql_fetchrow($result))
- {
- if (isset($session_times[$row['user_id']]))
- {
- $row['session_time'] = $session_times[$row['user_id']];
- }
- else
- {
- $row['session_time'] = 0;
- }
- $users[(int) $row['user_id']] = $row;
- }
- $db->sql_freeresult($result);
- unset($session_times);
+ echo '<br /><br />';
+ echo '<h1>' . $lang['ERROR'] . '</h1><br />';
- // now display a table with all users, some information about them and options
- // for the admin: keep name, change name (with text input) or delete user
- $u_action = "database_update.$phpEx?language=$language&amp;type=$inline_update";
+ echo '<p>' . sprintf($lang['MYSQL_SCHEMA_UPDATE_REQUIRED'], $config['dbms_version'], $db->sql_server_info(true)) . '</p>';
?>
-<br /><br />
-
-<p><?php echo $lang['CHANGE_CLEAN_NAMES']; ?></p>
-<form id="change_clean_names" method="post" action="<?php echo $u_action; ?>">
-
-
-<?php
- foreach ($colliding_users as $clean_name => $user_ids)
- {
-?>
- <fieldset class="tabulated">
- <table>
- <caption><?php echo sprintf($lang['COLLIDING_CLEAN_USERNAME'], $clean_name); ?></caption>
- <thead>
- <tr>
- <th><?php echo $lang['RANK']; ?> <?php echo $lang['USERNAME']; ?></th>
- <th><?php echo $lang['POSTS']; ?></th>
- <th><?php echo $lang['INFORMATION']; ?></th>
- <th><?php echo $lang['JOINED']; ?></th>
- <th><?php echo $lang['LAST_ACTIVE']; ?></th>
- <th><?php echo $lang['ACTION']; ?></th>
- <th><?php echo $lang['NEW_USERNAME']; ?></th>
- </tr>
- </thead>
- <tbody>
-<?php
- foreach ($user_ids as $i => $user_id)
- {
- $row = $users[$user_id];
-
- $rank_title = $rank_img = '';
- get_user_rank($row['user_rank'], $row['user_posts'], $rank_title, $rank_img, $rank_img_src);
-
- $last_visit = (!empty($row['session_time'])) ? $row['session_time'] : $row['user_lastvisit'];
-
- $info = '';
- switch ($row['user_type'])
- {
- case USER_INACTIVE:
- $info .= $lang['USER_INACTIVE'];
- break;
-
- case USER_IGNORE:
- $info .= $lang['BOT'];
- break;
-
- case USER_FOUNDER:
- $info .= $lang['FOUNDER'];
- break;
-
- default:
- $info .= $lang['USER_ACTIVE'];
- }
-
- if ($user_id == ANONYMOUS)
- {
- $info = $lang['GUEST'];
- }
-?>
- <tr class="bg<?php echo ($i % 2) + 1; ?>">
- <td>
- <span class="rank-img"><?php echo ($rank_img) ? $rank_img : $rank_title; ?></span><br />
- <?php echo get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']); ?>
- </td>
- <td class="posts"><?php echo $row['user_posts']; ?></td>
- <td class="info"><?php echo $info; ?></td>
- <td><?php echo $user->format_date($row['user_regdate']) ?></td>
- <td><?php echo (empty($last_visit)) ? ' - ' : $user->format_date($last_visit); ?>&nbsp;</td>
- <td>
- <label><input type="radio" class="radio" id="keep_user_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="keep" checked="checked" /> <?php echo $lang['KEEP_OLD_NAME']; ?></label><br />
- <label><input type="radio" class="radio" id="edit_user_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="edit" /> <?php echo $lang['EDIT_USERNAME']; ?></label><br />
-<?php
- // some users must not be deleted
- if ($user_id != ANONYMOUS && $row['user_type'] != USER_FOUNDER)
- {
-?>
- <label><input type="radio" class="radio" id="delete_user_retain_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="delete_retain" /> <?php echo $lang['DELETE_USER_RETAIN']; ?></label><br />
- <label><input type="radio" class="radio" id="delete_user_remove_<?php echo $user_id; ?>" name="modify_users[<?php echo $user_id; ?>]" value="delete_remove" /> <?php echo $lang['DELETE_USER_REMOVE']; ?></label>
-<?php
- }
-?>
- </td>
- <td>
- <input id="new_username_<?php echo $user_id; ?>" type="text" name="new_usernames[<?php echo $user_id; ?>]" value="<?php echo $row['username']; ?>" />
- </td>
- </tr>
-<?php
- }
-?>
- </tbody>
- </table>
- </fieldset>
-<?php
- }
-?>
- <p class="quick">
- <input class="button2" id="resolve_conflicts" type="submit" name="resolve_conflicts" value="<?php echo $lang['SUBMIT']; ?>" />
- </p>
- </form>
-<?php
- }
- else if (sizeof($found_names))
- {
- $sql = 'SELECT user_id, username, username_clean
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', array_values($found_names));
- $result = $db->sql_query($sql);
-
- $found_names = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $clean_name = utf8_new_clean_string($row['username']);
-
- if ($clean_name != $row['username_clean'])
- {
- $user_id = (int) $row['user_id'];
- $found_names[$user_id] = $clean_name;
-
- // impossible unique clean name
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET username_clean = ' {$user_id}'
- WHERE user_id = {$user_id}";
- $db->sql_query($sql);
- }
- }
- $db->sql_freeresult($result);
-
- foreach ($found_names as $user_id => $clean_name)
- {
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET username_clean = \'' . $db->sql_escape($clean_name) . '\'
- WHERE user_id = ' . $user_id;
- $db->sql_query($sql);
- }
- }
- unset($found_names);
- unset($colliding_users);
-}
-
-if ($exit)
-{
-?>
-
</div>
</div>
<span class="corners-bottom"><span></span></span>
@@ -1159,13 +261,26 @@ if ($exit)
</body>
</html>
-
<?php
- if (function_exists('exit_handler'))
- {
+
exit_handler();
+ exit;
+ }
+}
+
+// If the latest version and the current version are 'unequal', we will update the version_update_from, else we do not update anything.
+if ($inline_update)
+{
+ if ($current_version !== $latest_version)
+ {
+ set_config('version_update_from', $orig_version);
}
}
+else
+{
+ // If not called from the update script, we will actually remove the traces
+ $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'");
+}
// Schema updates
?>
@@ -1197,13 +312,6 @@ for ($i = 0; $i < sizeof($versions); $i++)
continue;
}
-/* if ($debug_from_version !== false)
- {
- // Applying update schema for version array with key '$version'
- // for version '$version' to '$next_version'
- continue;
- }*/
-
if (!sizeof($schema_changes))
{
continue;
@@ -1211,89 +319,11 @@ for ($i = 0; $i < sizeof($versions); $i++)
$no_updates = false;
- // Change columns?
- if (!empty($schema_changes['change_columns']))
- {
- foreach ($schema_changes['change_columns'] as $table => $columns)
- {
- foreach ($columns as $column_name => $column_data)
- {
- sql_column_change($map_dbms, $table, $column_name, $column_data);
- }
- }
- }
-
- // Add columns?
- if (!empty($schema_changes['add_columns']))
- {
- foreach ($schema_changes['add_columns'] as $table => $columns)
- {
- foreach ($columns as $column_name => $column_data)
- {
- // Only add the column if it does not exist yet
- if (!column_exists($map_dbms, $table, $column_name))
- {
- sql_column_add($map_dbms, $table, $column_name, $column_data);
- }
- }
- }
- }
-
- // Remove keys?
- if (!empty($schema_changes['drop_keys']))
- {
- foreach ($schema_changes['drop_keys'] as $table => $indexes)
- {
- foreach ($indexes as $index_name)
- {
- sql_index_drop($map_dbms, $index_name, $table);
- }
- }
- }
+ $statements = $db_tools->perform_schema_changes($schema_changes);
- // Drop columns?
- if (!empty($schema_changes['drop_columns']))
+ foreach ($statements as $sql)
{
- foreach ($schema_changes['drop_columns'] as $table => $columns)
- {
- foreach ($columns as $column)
- {
- sql_column_remove($map_dbms, $table, $column);
- }
- }
- }
-
- // Add primary keys?
- if (!empty($schema_changes['add_primary_keys']))
- {
- foreach ($schema_changes['add_primary_keys'] as $table => $columns)
- {
- sql_create_primary_key($map_dbms, $table, $columns);
- }
- }
-
- // Add unqiue indexes?
- if (!empty($schema_changes['add_unique_index']))
- {
- foreach ($schema_changes['add_unique_index'] as $table => $index_array)
- {
- foreach ($index_array as $index_name => $column)
- {
- sql_create_unique_index($map_dbms, $index_name, $table, $column);
- }
- }
- }
-
- // Add indexes?
- if (!empty($schema_changes['add_index']))
- {
- foreach ($schema_changes['add_index'] as $table => $index_array)
- {
- foreach ($index_array as $index_name => $column)
- {
- sql_create_index($map_dbms, $index_name, $table, $column);
- }
- }
+ _sql($sql, $errored, $error_ary);
}
}
@@ -1329,13 +359,6 @@ for ($i = 0; $i < sizeof($versions); $i++)
continue;
}
-/* if ($debug_from_version !== false)
- {
- // Applying update schema for version array with key '$version'
- // for version '$version' to '$next_version'
- continue;
- }*/
-
change_database_data($no_updates, $version);
}
@@ -1355,14 +378,14 @@ $errored = $no_updates = false;
flush();
-//if ($debug_from_version === false)
-// {
-
-// update the version
-$sql = "UPDATE " . CONFIG_TABLE . "
- SET config_value = '$updates_to_version'
- WHERE config_name = 'version'";
-_sql($sql, $errored, $error_ary);
+if ($debug_from_version === false)
+{
+ // update the version
+ $sql = "UPDATE " . CONFIG_TABLE . "
+ SET config_value = '$updates_to_version'
+ WHERE config_name = 'version'";
+ _sql($sql, $errored, $error_ary);
+}
// Reset permissions
$sql = 'UPDATE ' . USERS_TABLE . "
@@ -1370,7 +393,8 @@ $sql = 'UPDATE ' . USERS_TABLE . "
user_perm_from = 0";
_sql($sql, $errored, $error_ary);
-// }
+// Update the dbms version if everything is ok...
+set_config('dbms_version', $db->sql_server_info(true));
/* Optimize/vacuum analyze the tables where appropriate
// this should be done for each version in future along with
@@ -1403,8 +427,6 @@ _write_result($no_updates, $errored, $error_ary);
if (!$inline_update)
{
- // Purge the cache...
- $cache->purge();
?>
<p style="color:red"><?php echo $lang['UPDATE_FILES_NOTICE']; ?></p>
@@ -1457,380 +479,215 @@ if (function_exists('exit_handler'))
}
/**
-* Function where all data changes are executed
+* Function for triggering an sql statement
*/
-function change_database_data(&$no_updates, $version)
+function _sql($sql, &$errored, &$error_ary, $echo_dot = true)
{
- global $db, $map_dbms, $errored, $error_ary, $config, $phpbb_root_path, $phpEx;
+ global $db;
- switch ($version)
+ if (defined('DEBUG_EXTRA'))
{
- case '3.0.RC2':
-
- $smileys = array();
-
- $sql = 'SELECT smiley_id, code
- FROM ' . SMILIES_TABLE;
- $result = $db->sql_query($sql);
-
- while ($row = $db->sql_fetchrow($result))
- {
- $smileys[$row['smiley_id']] = $row['code'];
- }
- $db->sql_freeresult($result);
-
- foreach ($smileys as $id => $code)
- {
- // 2.0 only entitized lt and gt; We need to do something about double quotes.
- if (strchr($code, '"') === false)
- {
- continue;
- }
-
- $new_code = str_replace('&amp;', '&', $code);
- $new_code = str_replace('&lt;', '<', $new_code);
- $new_code = str_replace('&gt;', '>', $new_code);
- $new_code = utf8_htmlspecialchars($new_code);
-
- $sql = 'UPDATE ' . SMILIES_TABLE . '
- SET code = \'' . $db->sql_escape($new_code) . '\'
- WHERE smiley_id = ' . (int) $id;
- $db->sql_query($sql);
- }
-
- $index_list = sql_list_index($map_dbms, ACL_ROLES_DATA_TABLE);
-
- if (in_array('ath_opt_id', $index_list))
- {
- sql_index_drop($map_dbms, 'ath_opt_id', ACL_ROLES_DATA_TABLE);
- sql_create_index($map_dbms, 'ath_op_id', ACL_ROLES_DATA_TABLE, array('auth_option_id'));
- }
-
- $no_updates = false;
- break;
-
- case '3.0.RC3':
-
- if ($map_dbms === 'postgres')
- {
- $sql = "SELECT SETVAL('" . FORUMS_TABLE . "_seq',(select case when max(forum_id)>0 then max(forum_id)+1 else 1 end from " . FORUMS_TABLE . '));';
- _sql($sql, $errored, $error_ary);
- }
-
- // we check for:
- // ath_opt_id
- // ath_op_id
- // ACL_ROLES_DATA_TABLE_ath_opt_id
- // we want ACL_ROLES_DATA_TABLE_ath_op_id
-
- $table_index_fix = array(
- ACL_ROLES_DATA_TABLE => array(
- 'ath_opt_id' => 'ath_op_id',
- 'ath_op_id' => 'ath_op_id',
- ACL_ROLES_DATA_TABLE . '_ath_opt_id' => 'ath_op_id'
- ),
- STYLES_IMAGESET_DATA_TABLE => array(
- 'i_id' => 'i_d',
- 'i_d' => 'i_d',
- STYLES_IMAGESET_DATA_TABLE . '_i_id' => 'i_d'
- )
- );
-
- // we need to create some indicies...
- $needed_creation = array();
-
- foreach ($table_index_fix as $table_name => $index_info)
- {
- $index_list = sql_list_fake($map_dbms, $table_name);
- foreach ($index_info as $bad_index => $good_index)
- {
- if (in_array($bad_index, $index_list))
- {
- // mysql is actually OK, it won't get a hand in this crud
- switch ($map_dbms)
- {
- // last version, mssql had issues with index removal
- case 'mssql':
- $sql = 'DROP INDEX ' . $table_name . '.' . $bad_index;
- _sql($sql, $errored, $error_ary);
- break;
-
- // last version, firebird, oracle, postgresql and sqlite all got bad index names
- // we got kinda lucky, tho: they all support the same syntax
- case 'firebird':
- case 'oracle':
- case 'postgres':
- case 'sqlite':
- $sql = 'DROP INDEX ' . $bad_index;
- _sql($sql, $errored, $error_ary);
- break;
- }
-
- // If the good index already exist we do not need to create it again...
- if (($map_dbms == 'mysql_40' || $map_dbms == 'mysql_41') && $bad_index == $good_index)
- {
- }
- else
- {
- $needed_creation[$table_name][$good_index] = 1;
- }
- }
- }
- }
-
- $new_index_defs = array('ath_op_id' => array('auth_option_id'), 'i_d' => array('imageset_id'));
-
- foreach ($needed_creation as $bad_table => $index_repair_list)
- {
- foreach ($index_repair_list as $new_index => $garbage)
- {
- sql_create_index($map_dbms, $new_index, $bad_table, $new_index_defs[$new_index]);
- }
- }
-
- // Make sure empty smiley codes do not exist
- $sql = 'DELETE FROM ' . SMILIES_TABLE . "
- WHERE code = ''";
- _sql($sql, $errored, $error_ary);
-
- set_config('allow_birthdays', '1');
- set_config('cron_lock', '0', true);
-
- $no_updates = false;
- break;
-
- case '3.0.RC4':
-
- $update_auto_increment = array(
- STYLES_TABLE => 'style_id',
- STYLES_TEMPLATE_TABLE => 'template_id',
- STYLES_THEME_TABLE => 'theme_id',
- STYLES_IMAGESET_TABLE => 'imageset_id'
- );
-
- $sql = 'SELECT *
- FROM ' . STYLES_TABLE . '
- WHERE style_id = 0';
- $result = _sql($sql, $errored, $error_ary);
- $bad_style_row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($bad_style_row)
- {
- $sql = 'SELECT MAX(style_id) as max_id
- FROM ' . STYLES_TABLE;
- $result = _sql($sql, $errored, $error_ary);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $proper_id = $row['max_id'] + 1;
-
- _sql('UPDATE ' . STYLES_TABLE . " SET style_id = $proper_id WHERE style_id = 0", $errored, $error_ary);
- _sql('UPDATE ' . FORUMS_TABLE . " SET forum_style = $proper_id WHERE forum_style = 0", $errored, $error_ary);
- _sql('UPDATE ' . USERS_TABLE . " SET user_style = $proper_id WHERE user_style = 0", $errored, $error_ary);
-
- $sql = 'SELECT config_value
- FROM ' . CONFIG_TABLE . "
- WHERE config_name = 'default_style'";
- $result = _sql($sql, $errored, $error_ary);
- $style_config = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($style_config['config_value'] === '0')
- {
- set_config('default_style', (string) $proper_id);
- }
- }
-
- $sql = 'SELECT *
- FROM ' . STYLES_TEMPLATE_TABLE . '
- WHERE template_id = 0';
- $result = _sql($sql, $errored, $error_ary);
- $bad_style_row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($bad_style_row)
- {
- $sql = 'SELECT MAX(template_id) as max_id
- FROM ' . STYLES_TEMPLATE_TABLE;
- $result = _sql($sql, $errored, $error_ary);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $proper_id = $row['max_id'] + 1;
-
- _sql('UPDATE ' . STYLES_TABLE . " SET template_id = $proper_id WHERE template_id = 0", $errored, $error_ary);
- }
-
- $sql = 'SELECT *
- FROM ' . STYLES_THEME_TABLE . '
- WHERE theme_id = 0';
- $result = _sql($sql, $errored, $error_ary);
- $bad_style_row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- if ($bad_style_row)
- {
- $sql = 'SELECT MAX(theme_id) as max_id
- FROM ' . STYLES_THEME_TABLE;
- $result = _sql($sql, $errored, $error_ary);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $proper_id = $row['max_id'] + 1;
-
- _sql('UPDATE ' . STYLES_TABLE . " SET theme_id = $proper_id WHERE theme_id = 0", $errored, $error_ary);
- }
+ echo "<br />\n{$sql}\n<br />";
+ }
- $sql = 'SELECT *
- FROM ' . STYLES_IMAGESET_TABLE . '
- WHERE imageset_id = 0';
- $result = _sql($sql, $errored, $error_ary);
- $bad_style_row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
+ $db->sql_return_on_error(true);
- if ($bad_style_row)
- {
- $sql = 'SELECT MAX(imageset_id) as max_id
- FROM ' . STYLES_IMAGESET_TABLE;
- $result = _sql($sql, $errored, $error_ary);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
+ $result = $db->sql_query($sql);
+ if ($db->sql_error_triggered)
+ {
+ $errored = true;
+ $error_ary['sql'][] = $db->sql_error_sql;
+ $error_ary['error_code'][] = $db->_sql_error();
+ }
- $proper_id = $row['max_id'] + 1;
+ $db->sql_return_on_error(false);
- _sql('UPDATE ' . STYLES_TABLE . " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
- _sql('UPDATE ' . STYLES_IMAGESET_DATA_TABLE . " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
- }
+ if ($echo_dot)
+ {
+ echo ". \n";
+ flush();
+ }
- if ($map_dbms == 'mysql_40' || $map_dbms == 'mysql_41')
- {
- foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
- {
- $sql = "SELECT MAX({$auto_column_name}) as max_id
- FROM {$auto_table_name}";
- $result = _sql($sql, $errored, $error_ary);
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
+ return $result;
+}
- $max_id = ((int) $row['max_id']) + 1;
- _sql("ALTER TABLE {$auto_table_name} AUTO_INCREMENT = {$max_id}", $errored, $error_ary);
- }
- }
- else if ($map_dbms == 'postgres')
- {
- foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
- {
- $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 . '));';
- _sql($sql, $errored, $error_ary);
- }
+function _write_result($no_updates, $errored, $error_ary)
+{
+ global $lang;
- $sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE . '_seq';
- _sql($sql, $errored, $error_ary);
- }
- else if ($map_dbms == 'firebird')
- {
- $sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE;
- _sql($sql, $errored, $error_ary);
+ if ($no_updates)
+ {
+ echo ' ' . $lang['NO_UPDATES_REQUIRED'] . '</strong></p>';
+ }
+ else
+ {
+ echo ' <span class="success">' . $lang['DONE'] . '</span></strong><br />' . $lang['RESULT'] . ' :: ';
- $sql = 'DROP GENERATOR ' . STYLES_TEMPLATE_DATA_TABLE . '_gen';
- _sql($sql, $errored, $error_ary);
- }
- else if ($map_dbms == 'oracle')
- {
- $sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE;
- _sql($sql, $errored, $error_ary);
+ if ($errored)
+ {
+ echo ' <strong>' . $lang['SOME_QUERIES_FAILED'] . '</strong> <ul>';
- $sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE . '_seq';
- _sql($sql, $errored, $error_ary);
- }
- else if ($map_dbms == 'mssql')
+ for ($i = 0; $i < sizeof($error_ary['sql']); $i++)
{
- // we use transactions because we need to have a working DB at the end of all of this
- $db->sql_transaction('begin');
-
- $sql = 'SELECT *
- FROM ' . STYLES_TEMPLATE_DATA_TABLE;
- $result = _sql($sql, $errored, $error_ary);
- $old_style_rows = array();
- while ($row = $db->sql_fetchrow($result))
- {
- $old_style_rows[] = $row;
- }
- $db->sql_freeresult($result);
-
- // death to the table, it is evil!
- $sql = 'DROP TABLE ' . STYLES_TEMPLATE_DATA_TABLE;
- _sql($sql, $errored, $error_ary);
-
- // the table of awesomeness, praise be to it (or something)
- $sql = 'CREATE TABLE [' . STYLES_TEMPLATE_DATA_TABLE . "] (
- [template_id] [int] DEFAULT (0) NOT NULL ,
- [template_filename] [varchar] (100) DEFAULT ('') NOT NULL ,
- [template_included] [varchar] (8000) DEFAULT ('') NOT NULL ,
- [template_mtime] [int] DEFAULT (0) NOT NULL ,
- [template_data] [text] DEFAULT ('') NOT NULL
- ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]";
- _sql($sql, $errored, $error_ary);
-
- // index? index
- $sql = 'CREATE INDEX [tid] ON [' . STYLES_TEMPLATE_DATA_TABLE . ']([template_id]) ON [PRIMARY]';
- _sql($sql, $errored, $error_ary);
-
- // yet another index
- $sql = 'CREATE INDEX [tfn] ON [' . STYLES_TEMPLATE_DATA_TABLE . ']([template_filename]) ON [PRIMARY]';
- _sql($sql, $errored, $error_ary);
-
- foreach ($old_style_rows as $return_row)
- {
- _sql('INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $return_row), $errored, $error_ary);
- }
-
- $db->sql_transaction('commit');
+ echo '<li>' . $lang['ERROR'] . ' :: <strong>' . htmlspecialchars($error_ary['error_code'][$i]['message']) . '</strong><br />';
+ echo $lang['SQL'] . ' :: <strong>' . htmlspecialchars($error_ary['sql'][$i]) . '</strong><br /><br /></li>';
}
- // Setting this here again because new installations may not have it...
- set_config('cron_lock', '0', true);
- set_config('ldap_port', '');
- set_config('ldap_user_filter', '');
-
- $no_updates = false;
- break;
-
- case '3.0.RC5':
+ echo '</ul> <br /><br />' . $lang['SQL_FAILURE_EXPLAIN'] . '</p>';
+ }
+ else
+ {
+ echo '<strong>' . $lang['NO_ERRORS'] . '</strong></p>';
+ }
+ }
+}
- // In case the user is having the bot mediapartner google "as is", adjust it.
- $sql = 'UPDATE ' . BOTS_TABLE . "
- SET bot_agent = '" . $db->sql_escape('Mediapartners-Google') . "'
- WHERE bot_agent = '" . $db->sql_escape('Mediapartners-Google/') . "'";
- _sql($sql, $errored, $error_ary);
+/****************************************************************************
+* ADD YOUR DATABASE SCHEMA CHANGES HERE *
+*****************************************************************************/
+function database_update_info()
+{
+ return array(
+ // Changes from 3.0.0 to the next version
+ '3.0.0' => array(
+ // Add the following columns
+ 'add_columns' => array(
+ FORUMS_TABLE => array(
+ 'display_subforum_list' => array('BOOL', 1),
+ ),
+ SESSIONS_TABLE => array(
+ 'session_forum_id' => array('UINT', 0),
+ ),
+ ),
+ 'add_index' => array(
+ SESSIONS_TABLE => array(
+ 'session_forum_id' => array('session_forum_id'),
+ ),
+ GROUPS_TABLE => array(
+ 'group_legend_name' => array('group_legend', 'group_name'),
+ ),
+ ),
+ 'drop_keys' => array(
+ GROUPS_TABLE => array('group_legend'),
+ ),
+ ),
+ // No changes from 3.0.1-RC1 to 3.0.1
+ '3.0.1-RC1' => array(),
+ // No changes from 3.0.1 to 3.0.2-RC1
+ '3.0.1' => array(),
+ // Changes from 3.0.2-RC1 to 3.0.2-RC2
+ '3.0.2-RC1' => array(
+ 'change_columns' => array(
+ DRAFTS_TABLE => array(
+ 'draft_subject' => array('STEXT_UNI', ''),
+ ),
+ FORUMS_TABLE => array(
+ 'forum_last_post_subject' => array('STEXT_UNI', ''),
+ ),
+ POSTS_TABLE => array(
+ 'post_subject' => array('STEXT_UNI', '', 'true_sort'),
+ ),
+ PRIVMSGS_TABLE => array(
+ 'message_subject' => array('STEXT_UNI', ''),
+ ),
+ TOPICS_TABLE => array(
+ 'topic_title' => array('STEXT_UNI', '', 'true_sort'),
+ 'topic_last_post_subject' => array('STEXT_UNI', ''),
+ ),
+ ),
+ 'drop_keys' => array(
+ SESSIONS_TABLE => array('session_forum_id'),
+ ),
+ 'add_index' => array(
+ SESSIONS_TABLE => array(
+ 'session_fid' => array('session_forum_id'),
+ ),
+ ),
+ ),
+ // No changes from 3.0.2-RC2 to 3.0.2
+ '3.0.2-RC2' => array(),
- set_config('form_token_lifetime', '7200');
- set_config('form_token_mintime', '0');
- set_config('min_time_reg', '5');
- set_config('min_time_terms', '2');
- set_config('form_token_sid_guests', '1');
+ // Changes from 3.0.2 to 3.0.3-RC1
+ '3.0.2' => array(
+ // Add the following columns
+ 'add_columns' => array(
+ STYLES_TEMPLATE_TABLE => array(
+ 'template_inherits_id' => array('UINT:4', 0),
+ 'template_inherit_path' => array('VCHAR', ''),
+ ),
+ GROUPS_TABLE => array(
+ 'group_max_recipients' => array('UINT', 0),
+ ),
+ ),
+ ),
- $db->sql_transaction('begin');
+ // No changes from 3.0.3-RC1 to 3.0.3
+ '3.0.3-RC1' => array(),
- $sql = 'SELECT forum_id, forum_password
- FROM ' . FORUMS_TABLE;
- $result = _sql($sql, $errored, $error_ary);
+ // Changes from 3.0.3 to 3.0.4-RC1
+ '3.0.3' => array(
+ 'add_columns' => array(
+ PROFILE_FIELDS_TABLE => array(
+ 'field_show_profile' => array('BOOL', 0),
+ ),
+ ),
+ 'change_columns' => array(
+ STYLES_TABLE => array(
+ 'style_id' => array('UINT', NULL, 'auto_increment'),
+ 'template_id' => array('UINT', 0),
+ 'theme_id' => array('UINT', 0),
+ 'imageset_id' => array('UINT', 0),
+ ),
+ STYLES_IMAGESET_TABLE => array(
+ 'imageset_id' => array('UINT', NULL, 'auto_increment'),
+ ),
+ STYLES_IMAGESET_DATA_TABLE => array(
+ 'image_id' => array('UINT', NULL, 'auto_increment'),
+ 'imageset_id' => array('UINT', 0),
+ ),
+ STYLES_THEME_TABLE => array(
+ 'theme_id' => array('UINT', NULL, 'auto_increment'),
+ ),
+ STYLES_TEMPLATE_TABLE => array(
+ 'template_id' => array('UINT', NULL, 'auto_increment'),
+ ),
+ STYLES_TEMPLATE_DATA_TABLE => array(
+ 'template_id' => array('UINT', 0),
+ ),
+ FORUMS_TABLE => array(
+ 'forum_style' => array('UINT', 0),
+ ),
+ USERS_TABLE => array(
+ 'user_style' => array('UINT', 0),
+ ),
+ ),
+ ),
- while ($row = $db->sql_fetchrow($result))
- {
- if (!empty($row['forum_password']))
- {
- _sql('UPDATE ' . FORUMS_TABLE . " SET forum_password = '" . md5($row['forum_password']) . "' WHERE forum_id = {$row['forum_id']}", $errored, $error_ary);
- }
- }
- $db->sql_freeresult($result);
+ // Changes from 3.0.4-RC1 to 3.0.4
+ '3.0.4-RC1' => array(),
- $db->sql_transaction('commit');
+ // Changes from 3.0.4 to 3.0.5-RC1
+ '3.0.4' => array(
+ 'change_columns' => array(
+ FORUMS_TABLE => array(
+ 'forum_style' => array('UINT', 0),
+ ),
+ ),
+ ),
+ );
+}
- $no_updates = false;
- break;
+/****************************************************************************
+* ADD YOUR DATABASE DATA CHANGES HERE *
+* REMEMBER: You NEED to enter a schema array above and a data array here, *
+* even if both or one of them are empty. *
+*****************************************************************************/
+function change_database_data(&$no_updates, $version)
+{
+ global $db, $errored, $error_ary, $config, $phpbb_root_path, $phpEx;
+ switch ($version)
+ {
case '3.0.0':
$sql = 'UPDATE ' . TOPICS_TABLE . "
@@ -2028,1145 +885,1499 @@ function change_database_data(&$no_updates, $version)
_sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary);
}
-
$no_updates = false;
+
break;
// Changes from 3.0.4-RC1 to 3.0.4
case '3.0.4-RC1':
break;
- }
-}
-
-/**
-* Function for triggering an sql statement
-*/
-function _sql($sql, &$errored, &$error_ary, $echo_dot = true)
-{
- global $db;
-
- if (defined('DEBUG_EXTRA'))
- {
- echo "<br />\n{$sql}\n<br />";
- }
-
- $db->sql_return_on_error(true);
-
- $result = $db->sql_query($sql);
- if ($db->sql_error_triggered)
- {
- $errored = true;
- $error_ary['sql'][] = $db->sql_error_sql;
- $error_ary['error_code'][] = $db->_sql_error();
- }
-
- $db->sql_return_on_error(false);
-
- if ($echo_dot)
- {
- echo ". \n";
- flush();
- }
- return $result;
-}
+ // Changes from 3.0.4 to 3.0.5-RC1
+ case '3.0.4':
-function _write_result($no_updates, $errored, $error_ary)
-{
- global $lang;
-
- if ($no_updates)
- {
- echo ' ' . $lang['NO_UPDATES_REQUIRED'] . '</strong></p>';
- }
- else
- {
- echo ' <span class="success">' . $lang['DONE'] . '</span></strong><br />' . $lang['RESULT'] . ' :: ';
+ // Captcha config variables
+ set_config('captcha_gd_wave', 0);
+ set_config('captcha_gd_3d_noise', 1);
+ set_config('captcha_gd_fonts', 1);
- if ($errored)
- {
- echo ' <strong>' . $lang['SOME_QUERIES_FAILED'] . '</strong> <ul>';
+ set_config('confirm_refresh', 1);
- for ($i = 0; $i < sizeof($error_ary['sql']); $i++)
- {
- echo '<li>' . $lang['ERROR'] . ' :: <strong>' . htmlspecialchars($error_ary['error_code'][$i]['message']) . '</strong><br />';
- echo $lang['SQL'] . ' :: <strong>' . htmlspecialchars($error_ary['sql'][$i]) . '</strong><br /><br /></li>';
- }
+ // Maximum number of keywords
+ set_config('max_num_search_keywords', 10);
- echo '</ul> <br /><br />' . $lang['SQL_FAILURE_EXPLAIN'] . '</p>';
- }
- else
- {
- echo '<strong>' . $lang['NO_ERRORS'] . '</strong></p>';
- }
- }
-}
+ // Remove static config var and put it back as dynamic variable
+ $sql = 'UPDATE ' . CONFIG_TABLE . "
+ SET is_dynamic = 1
+ WHERE config_name = 'search_indexing_state'";
+ _sql($sql, $errored, $error_ary);
-/**
-* Check if a specified column exist
-*/
-function column_exists($dbms, $table, $column_name)
-{
- global $db;
+ // Hash old MD5 passwords
+ $sql = 'SELECT user_id, user_password
+ FROM ' . USERS_TABLE . '
+ WHERE user_pass_convert = 1';
+ $result = _sql($sql, $errored, $error_ary);
- switch ($dbms)
- {
- case 'mysql_40':
- case 'mysql_41':
- $sql = "SHOW COLUMNS
- FROM $table";
- $result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
- // lower case just in case
- if (strtolower($row['Field']) == $column_name)
+ if (strlen($row['user_password']) == 32)
{
- $db->sql_freeresult($result);
- return true;
- }
- }
- $db->sql_freeresult($result);
- return false;
- break;
+ $sql_ary = array(
+ 'user_password' => phpbb_hash($row['user_password']),
+ );
- // PostgreSQL has a way of doing this in a much simpler way but would
- // not allow us to support all versions of PostgreSQL
- case 'postgres':
- $sql = "SELECT a.attname
- FROM pg_class c, pg_attribute a
- WHERE c.relname = '{$table}'
- AND a.attnum > 0
- AND a.attrelid = c.oid";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- // lower case just in case
- if (strtolower($row['attname']) == $column_name)
- {
- $db->sql_freeresult($result);
- return true;
+ _sql('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id'], $errored, $error_ary);
}
}
$db->sql_freeresult($result);
- return false;
- break;
- // same deal with PostgreSQL, we must perform more complex operations than
- // we technically could
- case 'mssql':
- $sql = "SELECT c.name
- FROM syscolumns c
- LEFT JOIN sysobjects o ON c.id = o.id
- WHERE o.name = '{$table}'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- // lower case just in case
- if (strtolower($row['name']) == $column_name)
- {
- $db->sql_freeresult($result);
- return true;
- }
- }
- $db->sql_freeresult($result);
- return false;
- break;
+ // Adjust bot entry
+ $sql = 'UPDATE ' . BOTS_TABLE . "
+ SET bot_agent = 'ichiro/'
+ WHERE bot_agent = 'ichiro/2'";
+ _sql($sql, $errored, $error_ary);
- case 'oracle':
- $sql = "SELECT column_name
- FROM user_tab_columns
- WHERE table_name = '{$table}'";
+ // Before we are able to add a unique key to auth_option, we need to remove duplicate entries
+
+ // We get duplicate entries first
+ $sql = 'SELECT auth_option
+ FROM ' . ACL_OPTIONS_TABLE . '
+ GROUP BY auth_option
+ HAVING COUNT(*) >= 1';
$result = $db->sql_query($sql);
+
+ $auth_options = array();
while ($row = $db->sql_fetchrow($result))
{
- // lower case just in case
- if (strtolower($row['column_name']) == $column_name)
- {
- $db->sql_freeresult($result);
- return true;
- }
+ $auth_options[] = $row['auth_option'];
}
$db->sql_freeresult($result);
- return false;
- break;
- case 'firebird':
- $sql = "SELECT RDB\$FIELD_NAME as FNAME
- FROM RDB\$RELATION_FIELDS
- WHERE RDB\$RELATION_NAME = '{$table}'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
+ // Remove specific auth options
+ if (!empty($auth_options))
{
- // lower case just in case
- if (strtolower($row['fname']) == $column_name)
+ foreach ($auth_options as $option)
{
+ // Select auth_option_ids... the largest id will be preserved
+ $sql = 'SELECT auth_option_id
+ FROM ' . ACL_OPTIONS_TABLE . "
+ WHERE auth_option = '" . $db->sql_escape($option) . "'
+ ORDER BY auth_option_id DESC";
+ // sql_query_limit not possible here, due to bug in postgresql layer
+ $result = $db->sql_query($sql);
+
+ // Skip first row, this is our original auth option we want to preserve
+ $row = $db->sql_fetchrow($result);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ // Ok, remove this auth option...
+ _sql('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary);
+ _sql('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary);
+ _sql('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary);
+ _sql('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary);
+ }
$db->sql_freeresult($result);
- return true;
}
}
- $db->sql_freeresult($result);
- return false;
- break;
- // ugh, SQLite
- case 'sqlite':
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table}'";
- $result = $db->sql_query($sql);
-
- if (!$result)
- {
- return false;
- }
-
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
+ // Now make auth_option UNIQUE, by dropping the old index and adding a UNIQUE one.
+ $changes = array(
+ 'drop_keys' => array(
+ ACL_OPTIONS_TABLE => array('auth_option'),
+ ),
+ 'add_unique_index' => array(
+ ACL_OPTIONS_TABLE => array(
+ 'auth_option' => array('auth_option'),
+ ),
+ ),
+ );
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ global $db_tools;
- $cols = trim($matches[1]);
- $col_array = preg_split('/,(?![\s\w]+\))/m', $cols);
+ $statements = $db_tools->perform_schema_changes($changes);
- foreach ($col_array as $declaration)
+ foreach ($statements as $sql)
{
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY')
- {
- continue;
- }
-
- if (strtolower($entities[0]) == $column_name)
- {
- return true;
- }
+ _sql($sql, $errored, $error_ary);
}
- return false;
+
+ $no_updates = false;
+
break;
}
}
+
/**
-* Function to prepare some column information for better usage
+* Database Tools for handling cross-db actions such as altering columns, etc.
+* Currently not supported is returning SQL for creating tables.
+*
+* @package dbal
*/
-function prepare_column_data($dbms, $column_data, $table_name, $column_name)
+class updater_db_tools
{
- global $dbms_type_map, $unsigned_types;
+ /**
+ * Current sql layer
+ */
+ var $sql_layer = '';
- // Get type
- if (strpos($column_data[0], ':') !== false)
- {
- list($orig_column_type, $column_length) = explode(':', $column_data[0]);
+ /**
+ * @var object DB object
+ */
+ var $db = NULL;
- if (!is_array($dbms_type_map[$dbms][$orig_column_type . ':']))
- {
- $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'], $column_length);
- }
- else
- {
- if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['rule']))
- {
- switch ($dbms_type_map[$dbms][$orig_column_type . ':']['rule'][0])
- {
- case 'div':
- $column_length /= $dbms_type_map[$dbms][$orig_column_type . ':']['rule'][1];
- $column_length = ceil($column_length);
- $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length);
- break;
- }
- }
+ /**
+ * The Column types for every database we support
+ * @var array
+ */
+ var $dbms_type_map = array(
+ 'mysql_41' => array(
+ 'INT:' => 'int(%d)',
+ 'BINT' => 'bigint(20)',
+ 'UINT' => 'mediumint(8) UNSIGNED',
+ 'UINT:' => 'int(%d) UNSIGNED',
+ 'TINT:' => 'tinyint(%d)',
+ 'USINT' => 'smallint(4) UNSIGNED',
+ 'BOOL' => 'tinyint(1) UNSIGNED',
+ 'VCHAR' => 'varchar(255)',
+ 'VCHAR:' => 'varchar(%d)',
+ 'CHAR:' => 'char(%d)',
+ 'XSTEXT' => 'text',
+ 'XSTEXT_UNI'=> 'varchar(100)',
+ 'STEXT' => 'text',
+ 'STEXT_UNI' => 'varchar(255)',
+ 'TEXT' => 'text',
+ 'TEXT_UNI' => 'text',
+ 'MTEXT' => 'mediumtext',
+ 'MTEXT_UNI' => 'mediumtext',
+ 'TIMESTAMP' => 'int(11) UNSIGNED',
+ 'DECIMAL' => 'decimal(5,2)',
+ 'DECIMAL:' => 'decimal(%d,2)',
+ 'PDECIMAL' => 'decimal(6,3)',
+ 'PDECIMAL:' => 'decimal(%d,3)',
+ 'VCHAR_UNI' => 'varchar(255)',
+ 'VCHAR_UNI:'=> 'varchar(%d)',
+ 'VCHAR_CI' => 'varchar(255)',
+ 'VARBINARY' => 'varbinary(255)',
+ ),
- if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['limit']))
- {
- switch ($dbms_type_map[$dbms][$orig_column_type . ':']['limit'][0])
- {
- case 'mult':
- $column_length *= $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][1];
- if ($column_length > $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][2])
- {
- $column_type = $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][3];
- }
- else
- {
- $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length);
- }
- break;
- }
- }
- }
- $orig_column_type .= ':';
- }
- else
- {
- $orig_column_type = $column_data[0];
- $column_type = $dbms_type_map[$dbms][$column_data[0]];
- }
+ 'mysql_40' => array(
+ 'INT:' => 'int(%d)',
+ 'BINT' => 'bigint(20)',
+ 'UINT' => 'mediumint(8) UNSIGNED',
+ 'UINT:' => 'int(%d) UNSIGNED',
+ 'TINT:' => 'tinyint(%d)',
+ 'USINT' => 'smallint(4) UNSIGNED',
+ 'BOOL' => 'tinyint(1) UNSIGNED',
+ 'VCHAR' => 'varbinary(255)',
+ 'VCHAR:' => 'varbinary(%d)',
+ 'CHAR:' => 'binary(%d)',
+ 'XSTEXT' => 'blob',
+ 'XSTEXT_UNI'=> 'blob',
+ 'STEXT' => 'blob',
+ 'STEXT_UNI' => 'blob',
+ 'TEXT' => 'blob',
+ 'TEXT_UNI' => 'blob',
+ 'MTEXT' => 'mediumblob',
+ 'MTEXT_UNI' => 'mediumblob',
+ 'TIMESTAMP' => 'int(11) UNSIGNED',
+ 'DECIMAL' => 'decimal(5,2)',
+ 'DECIMAL:' => 'decimal(%d,2)',
+ 'PDECIMAL' => 'decimal(6,3)',
+ 'PDECIMAL:' => 'decimal(%d,3)',
+ 'VCHAR_UNI' => 'blob',
+ 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')),
+ 'VCHAR_CI' => 'blob',
+ 'VARBINARY' => 'varbinary(255)',
+ ),
- // Adjust default value if db-dependant specified
- if (is_array($column_data[1]))
- {
- $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default'];
- }
+ 'firebird' => array(
+ 'INT:' => 'INTEGER',
+ 'BINT' => 'DOUBLE PRECISION',
+ 'UINT' => 'INTEGER',
+ 'UINT:' => 'INTEGER',
+ 'TINT:' => 'INTEGER',
+ 'USINT' => 'INTEGER',
+ 'BOOL' => 'INTEGER',
+ 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE',
+ 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE',
+ 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE',
+ 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
+ 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
+ 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
+ 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
+ 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8',
+ 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
+ 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
+ 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
+ 'TIMESTAMP' => 'INTEGER',
+ 'DECIMAL' => 'DOUBLE PRECISION',
+ 'DECIMAL:' => 'DOUBLE PRECISION',
+ 'PDECIMAL' => 'DOUBLE PRECISION',
+ 'PDECIMAL:' => 'DOUBLE PRECISION',
+ 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
+ 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8',
+ 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8',
+ 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE',
+ ),
- $sql = '';
- $return_array = array();
+ 'mssql' => array(
+ 'INT:' => '[int]',
+ 'BINT' => '[float]',
+ 'UINT' => '[int]',
+ 'UINT:' => '[int]',
+ 'TINT:' => '[int]',
+ 'USINT' => '[int]',
+ 'BOOL' => '[int]',
+ 'VCHAR' => '[varchar] (255)',
+ 'VCHAR:' => '[varchar] (%d)',
+ 'CHAR:' => '[char] (%d)',
+ 'XSTEXT' => '[varchar] (1000)',
+ 'STEXT' => '[varchar] (3000)',
+ 'TEXT' => '[varchar] (8000)',
+ 'MTEXT' => '[text]',
+ 'XSTEXT_UNI'=> '[varchar] (100)',
+ 'STEXT_UNI' => '[varchar] (255)',
+ 'TEXT_UNI' => '[varchar] (4000)',
+ 'MTEXT_UNI' => '[text]',
+ 'TIMESTAMP' => '[int]',
+ 'DECIMAL' => '[float]',
+ 'DECIMAL:' => '[float]',
+ 'PDECIMAL' => '[float]',
+ 'PDECIMAL:' => '[float]',
+ 'VCHAR_UNI' => '[varchar] (255)',
+ 'VCHAR_UNI:'=> '[varchar] (%d)',
+ 'VCHAR_CI' => '[varchar] (255)',
+ 'VARBINARY' => '[varchar] (255)',
+ ),
- switch ($dbms)
- {
- case 'firebird':
- $sql .= " {$column_type} ";
+ 'oracle' => array(
+ 'INT:' => 'number(%d)',
+ 'BINT' => 'number(20)',
+ 'UINT' => 'number(8)',
+ 'UINT:' => 'number(%d)',
+ 'TINT:' => 'number(%d)',
+ 'USINT' => 'number(4)',
+ 'BOOL' => 'number(1)',
+ 'VCHAR' => 'varchar2(255)',
+ 'VCHAR:' => 'varchar2(%d)',
+ 'CHAR:' => 'char(%d)',
+ 'XSTEXT' => 'varchar2(1000)',
+ 'STEXT' => 'varchar2(3000)',
+ 'TEXT' => 'clob',
+ 'MTEXT' => 'clob',
+ 'XSTEXT_UNI'=> 'varchar2(300)',
+ 'STEXT_UNI' => 'varchar2(765)',
+ 'TEXT_UNI' => 'clob',
+ 'MTEXT_UNI' => 'clob',
+ 'TIMESTAMP' => 'number(11)',
+ 'DECIMAL' => 'number(5, 2)',
+ 'DECIMAL:' => 'number(%d, 2)',
+ 'PDECIMAL' => 'number(6, 3)',
+ 'PDECIMAL:' => 'number(%d, 3)',
+ 'VCHAR_UNI' => 'varchar2(765)',
+ 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')),
+ 'VCHAR_CI' => 'varchar2(255)',
+ 'VARBINARY' => 'raw(255)',
+ ),
- if (!is_null($column_data[1]))
- {
- $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' ';
- }
+ 'sqlite' => array(
+ 'INT:' => 'int(%d)',
+ 'BINT' => 'bigint(20)',
+ 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED',
+ 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED',
+ 'TINT:' => 'tinyint(%d)',
+ 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED',
+ 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED',
+ 'VCHAR' => 'varchar(255)',
+ 'VCHAR:' => 'varchar(%d)',
+ 'CHAR:' => 'char(%d)',
+ 'XSTEXT' => 'text(65535)',
+ 'STEXT' => 'text(65535)',
+ 'TEXT' => 'text(65535)',
+ 'MTEXT' => 'mediumtext(16777215)',
+ 'XSTEXT_UNI'=> 'text(65535)',
+ 'STEXT_UNI' => 'text(65535)',
+ 'TEXT_UNI' => 'text(65535)',
+ 'MTEXT_UNI' => 'mediumtext(16777215)',
+ 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
+ 'DECIMAL' => 'decimal(5,2)',
+ 'DECIMAL:' => 'decimal(%d,2)',
+ 'PDECIMAL' => 'decimal(6,3)',
+ 'PDECIMAL:' => 'decimal(%d,3)',
+ 'VCHAR_UNI' => 'varchar(255)',
+ 'VCHAR_UNI:'=> 'varchar(%d)',
+ 'VCHAR_CI' => 'varchar(255)',
+ 'VARBINARY' => 'blob',
+ ),
- $sql .= 'NOT NULL';
+ 'postgres' => array(
+ 'INT:' => 'INT4',
+ 'BINT' => 'INT8',
+ 'UINT' => 'INT4', // unsigned
+ 'UINT:' => 'INT4', // unsigned
+ 'USINT' => 'INT2', // unsigned
+ 'BOOL' => 'INT2', // unsigned
+ 'TINT:' => 'INT2',
+ 'VCHAR' => 'varchar(255)',
+ 'VCHAR:' => 'varchar(%d)',
+ 'CHAR:' => 'char(%d)',
+ 'XSTEXT' => 'varchar(1000)',
+ 'STEXT' => 'varchar(3000)',
+ 'TEXT' => 'varchar(8000)',
+ 'MTEXT' => 'TEXT',
+ 'XSTEXT_UNI'=> 'varchar(100)',
+ 'STEXT_UNI' => 'varchar(255)',
+ 'TEXT_UNI' => 'varchar(4000)',
+ 'MTEXT_UNI' => 'TEXT',
+ 'TIMESTAMP' => 'INT4', // unsigned
+ 'DECIMAL' => 'decimal(5,2)',
+ 'DECIMAL:' => 'decimal(%d,2)',
+ 'PDECIMAL' => 'decimal(6,3)',
+ 'PDECIMAL:' => 'decimal(%d,3)',
+ 'VCHAR_UNI' => 'varchar(255)',
+ 'VCHAR_UNI:'=> 'varchar(%d)',
+ 'VCHAR_CI' => 'varchar_ci',
+ 'VARBINARY' => 'bytea',
+ ),
+ );
- // This is a UNICODE column and thus should be given it's fair share
- if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0]))
- {
- $sql .= ' COLLATE UNICODE';
- }
+ /**
+ * A list of types being unsigned for better reference in some db's
+ * @var array
+ */
+ var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP');
- break;
+ /**
+ * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules.
+ * @var array
+ */
+ var $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
- case 'mssql':
- $sql .= " {$column_type} ";
- $sql_default = " {$column_type} ";
+ /**
+ * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
+ * This mode has no effect on some methods (inserting of data for example). This is expressed within the methods command.
+ */
+ var $return_statements = false;
- // For adding columns we need the default definition
- if (!is_null($column_data[1]))
- {
- // For hexadecimal values do not use single quotes
- if (strpos($column_data[1], '0x') === 0)
+ /**
+ * Constructor. Set DB Object and set {@link $return_statements return_statements}.
+ *
+ * @param phpbb_dbal $db DBAL object
+ * @param bool $return_statements True if only statements should be returned and no SQL being executed
+ */
+ function updater_db_tools(&$db, $return_statements = false)
+ {
+ $this->db = $db;
+ $this->return_statements = $return_statements;
+
+ // Determine mapping database type
+ switch ($this->db->sql_layer)
+ {
+ case 'mysql':
+ $this->sql_layer = 'mysql_40';
+ break;
+
+ case 'mysql4':
+ if (version_compare($this->db->sql_server_info(true), '4.1.3', '>='))
{
- $sql_default .= 'DEFAULT (' . $column_data[1] . ') ';
+ $this->sql_layer = 'mysql_41';
}
else
{
- $sql_default .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') ';
+ $this->sql_layer = 'mysql_40';
}
- }
+ break;
- $sql .= 'NOT NULL';
- $sql_default .= 'NOT NULL';
+ case 'mysqli':
+ $this->sql_layer = 'mysql_41';
+ break;
- $return_array['column_type_sql_default'] = $sql_default;
- break;
+ case 'mssql':
+ case 'mssql_odbc':
+ $this->sql_layer = 'mssql';
+ break;
- case 'mysql_40':
- case 'mysql_41':
- $sql .= " {$column_type} ";
+ default:
+ $this->sql_layer = $this->db->sql_layer;
+ break;
+ }
+ }
- // For hexadecimal values do not use single quotes
- if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob')
- {
- $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' ";
- }
- $sql .= 'NOT NULL';
+ /**
+ * Handle passed database update array.
+ * Expected structure...
+ * Key being one of the following
+ * change_columns: Column changes (only type, not name)
+ * add_columns: Add columns to a table
+ * drop_keys: Dropping keys
+ * drop_columns: Removing/Dropping columns
+ * add_primary_keys: adding primary keys
+ * add_unique_index: adding an unique index
+ * add_index: adding an index
+ *
+ * The values are in this format:
+ * {TABLE NAME} => array(
+ * {COLUMN NAME} => array({COLUMN TYPE}, {DEFAULT VALUE}, {OPTIONAL VARIABLES}),
+ * {KEY/INDEX NAME} => array({COLUMN NAMES}),
+ * )
+ *
+ * For more information have a look at /develop/create_schema_files.php (only available through SVN)
+ */
+ function perform_schema_changes($schema_changes)
+ {
+ if (empty($schema_changes))
+ {
+ return;
+ }
+
+ $statements = array();
- if (isset($column_data[2]))
+ // Change columns?
+ if (!empty($schema_changes['change_columns']))
+ {
+ foreach ($schema_changes['change_columns'] as $table => $columns)
{
- if ($column_data[2] == 'auto_increment')
- {
- $sql .= ' auto_increment';
- }
- else if ($dbms === 'mysql_41' && $column_data[2] == 'true_sort')
+ foreach ($columns as $column_name => $column_data)
{
- $sql .= ' COLLATE utf8_unicode_ci';
+ // If the column exists we change it, else we add it ;)
+ if ($this->sql_column_exists($table, $column_name))
+ {
+ $result = $this->sql_column_change($table, $column_name, $column_data);
+ }
+ else
+ {
+ $result = $this->sql_column_add($table, $column_name, $column_data);
+ }
+
+ if ($this->return_statements)
+ {
+ $statements = array_merge($statements, $result);
+ }
}
}
+ }
- break;
-
- case 'oracle':
- $sql .= " {$column_type} ";
- $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : '';
-
- // In Oracle empty strings ('') are treated as NULL.
- // Therefore in oracle we allow NULL's for all DEFAULT '' entries
- // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields)
- if (preg_match('/number/i', $column_type))
+ // Add columns?
+ if (!empty($schema_changes['add_columns']))
+ {
+ foreach ($schema_changes['add_columns'] as $table => $columns)
{
- $sql .= ($column_data[1] === '') ? '' : 'NOT NULL';
- }
- break;
-
- case 'postgres':
- $return_array['column_type'] = $column_type;
-
- $sql .= " {$column_type} ";
+ foreach ($columns as $column_name => $column_data)
+ {
+ // Only add the column if it does not exist yet, else change it (to be consistent)
+ if ($this->sql_column_exists($table, $column_name))
+ {
+ $result = $this->sql_column_change($table, $column_name, $column_data);
+ }
+ else
+ {
+ $result = $this->sql_column_add($table, $column_name, $column_data);
+ }
- if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
- {
- $default_val = "nextval('{$table_name}_seq')";
+ if ($this->return_statements)
+ {
+ $statements = array_merge($statements, $result);
+ }
+ }
}
- else if (!is_null($column_data[1]))
+ }
+
+ // Remove keys?
+ if (!empty($schema_changes['drop_keys']))
+ {
+ foreach ($schema_changes['drop_keys'] as $table => $indexes)
{
- $default_val = "'" . $column_data[1] . "'";
- $return_array['null'] = 'NOT NULL';
- $sql .= 'NOT NULL ';
+ foreach ($indexes as $index_name)
+ {
+ $result = $this->sql_index_drop($table, $index_name);
+
+ if ($this->return_statements)
+ {
+ $statements = array_merge($statements, $result);
+ }
+ }
}
+ }
- $return_array['default'] = $default_val;
+ // Drop columns?
+ if (!empty($schema_changes['drop_columns']))
+ {
+ foreach ($schema_changes['drop_columns'] as $table => $columns)
+ {
+ foreach ($columns as $column)
+ {
+ // Only remove the column if it exists...
+ if ($this->sql_column_exists($table, $column))
+ {
+ $result = $this->sql_column_remove($table, $column);
- $sql .= "DEFAULT {$default_val}";
+ if ($this->return_statements)
+ {
+ $statements = array_merge($statements, $result);
+ }
+ }
+ }
+ }
+ }
- // Unsigned? Then add a CHECK contraint
- if (in_array($orig_column_type, $unsigned_types))
+ // Add primary keys?
+ if (!empty($schema_changes['add_primary_keys']))
+ {
+ foreach ($schema_changes['add_primary_keys'] as $table => $columns)
{
- $return_array['constraint'] = "CHECK ({$column_name} >= 0)";
- $sql .= " CHECK ({$column_name} >= 0)";
+ $result = $this->sql_create_primary_key($table, $columns);
+
+ if ($this->return_statements)
+ {
+ $statements = array_merge($statements, $result);
+ }
}
- break;
+ }
- case 'sqlite':
- if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
+ // Add unqiue indexes?
+ if (!empty($schema_changes['add_unique_index']))
+ {
+ foreach ($schema_changes['add_unique_index'] as $table => $index_array)
{
- $sql .= ' INTEGER PRIMARY KEY';
+ foreach ($index_array as $index_name => $column)
+ {
+ $result = $this->sql_create_unique_index($table, $index_name, $column);
+
+ if ($this->return_statements)
+ {
+ $statements = array_merge($statements, $result);
+ }
+ }
}
- else
+ }
+
+ // Add indexes?
+ if (!empty($schema_changes['add_index']))
+ {
+ foreach ($schema_changes['add_index'] as $table => $index_array)
{
- $sql .= ' ' . $column_type;
+ foreach ($index_array as $index_name => $column)
+ {
+ $result = $this->sql_create_index($table, $index_name, $column);
+
+ if ($this->return_statements)
+ {
+ $statements = array_merge($statements, $result);
+ }
+ }
}
+ }
- $sql .= ' NOT NULL ';
- $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : '';
- break;
+ if ($this->return_statements)
+ {
+ return $statements;
+ }
}
- $return_array['column_type_sql'] = $sql;
-
- return $return_array;
-}
+ /**
+ * Check if a specified column exist
+ *
+ * @param string $table Table to check the column at
+ * @param string $column_name The column to check
+ *
+ * @return bool True if column exists, else false
+ */
+ function sql_column_exists($table, $column_name)
+ {
+ switch ($this->sql_layer)
+ {
+ case 'mysql_40':
+ case 'mysql_41':
-/**
-* Add new column
-*/
-function sql_column_add($dbms, $table_name, $column_name, $column_data)
-{
- global $errored, $error_ary;
+ $sql = "SHOW COLUMNS FROM $table";
+ $result = $this->db->sql_query($sql);
- $column_data = prepare_column_data($dbms, $column_data, $table_name, $column_name);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ // lower case just in case
+ if (strtolower($row['Field']) == $column_name)
+ {
+ $this->db->sql_freeresult($result);
+ return true;
+ }
+ }
+ $this->db->sql_freeresult($result);
+ return false;
+ break;
- switch ($dbms)
- {
- case 'firebird':
- $sql = 'ALTER TABLE "' . $table_name . '" ADD "' . $column_name . '" ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ // PostgreSQL has a way of doing this in a much simpler way but would
+ // not allow us to support all versions of PostgreSQL
+ case 'postgres':
+ $sql = "SELECT a.attname
+ FROM pg_class c, pg_attribute a
+ WHERE c.relname = '{$table}'
+ AND a.attnum > 0
+ AND a.attrelid = c.oid";
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ // lower case just in case
+ if (strtolower($row['attname']) == $column_name)
+ {
+ $this->db->sql_freeresult($result);
+ return true;
+ }
+ }
+ $this->db->sql_freeresult($result);
- case 'mssql':
- $sql = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default'];
- _sql($sql, $errored, $error_ary);
- break;
+ return false;
+ break;
- case 'mysql_40':
- case 'mysql_41':
- $sql = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ // same deal with PostgreSQL, we must perform more complex operations than
+ // we technically could
+ case 'mssql':
+ $sql = "SELECT c.name
+ FROM syscolumns c
+ LEFT JOIN sysobjects o ON c.id = o.id
+ WHERE o.name = '{$table}'";
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ // lower case just in case
+ if (strtolower($row['name']) == $column_name)
+ {
+ $this->db->sql_freeresult($result);
+ return true;
+ }
+ }
+ $this->db->sql_freeresult($result);
+ return false;
+ break;
- case 'oracle':
- $sql = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ case 'oracle':
+ $sql = "SELECT column_name
+ FROM user_tab_columns
+ WHERE table_name = '{$table}'";
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ // lower case just in case
+ if (strtolower($row['column_name']) == $column_name)
+ {
+ $this->db->sql_freeresult($result);
+ return true;
+ }
+ }
+ $this->db->sql_freeresult($result);
+ return false;
+ break;
- case 'postgres':
- $sql = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ case 'firebird':
+ $sql = "SELECT RDB\$FIELD_NAME as FNAME
+ FROM RDB\$RELATION_FIELDS
+ WHERE RDB\$RELATION_NAME = '{$table}'";
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ // lower case just in case
+ if (strtolower($row['fname']) == $column_name)
+ {
+ $this->db->sql_freeresult($result);
+ return true;
+ }
+ }
+ $this->db->sql_freeresult($result);
+ return false;
+ break;
- case 'sqlite':
- if (version_compare(sqlite_libversion(), '3.0') == -1)
- {
- global $db;
+ // ugh, SQLite
+ case 'sqlite':
$sql = "SELECT sql
FROM sqlite_master
WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $db->sql_query($sql);
+ AND name = '{$table}'";
+ $result = $this->db->sql_query($sql);
if (!$result)
{
- break;
+ return false;
}
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
-
- $db->sql_transaction('begin');
-
- // Create a backup table and populate it, destroy the existing one
- $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
- $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
- $db->sql_query('DROP TABLE ' . $table_name);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
preg_match('#\((.*)\)#s', $row['sql'], $matches);
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ $cols = trim($matches[1]);
+ $col_array = preg_split('/,(?![\s\w]+\))/m', $cols);
- foreach ($old_table_cols as $declaration)
+ foreach ($col_array as $declaration)
{
$entities = preg_split('#\s+#', trim($declaration));
if ($entities[0] == 'PRIMARY')
{
continue;
}
- $column_list[] = $entities[0];
- }
-
- $columns = implode(',', $column_list);
- $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
+ if (strtolower($entities[0]) == $column_name)
+ {
+ return true;
+ }
+ }
+ return false;
+ break;
+ }
+ }
- // create a new table and fill it up. destroy the temp one
- $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');');
- $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
- $db->sql_query('DROP TABLE ' . $table_name . '_temp');
+ /**
+ * Private method for performing sql statements (either execute them or return them)
+ * @access private
+ */
+ function _sql_run_sql($statements)
+ {
+ if ($this->return_statements)
+ {
+ return $statements;
+ }
- $db->sql_transaction('commit');
+ // We could add error handling here...
+ foreach ($statements as $sql)
+ {
+ if ($sql === 'begin')
+ {
+ $this->db->sql_transaction('begin');
+ }
+ else if ($sql === 'commit')
+ {
+ $this->db->sql_transaction('commit');
}
else
{
- $sql = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']';
- _sql($sql, $errored, $error_ary);
+ $this->db->sql_query($sql);
}
- break;
- }
-}
+ }
-/**
-* Drop column
-*/
-function sql_column_remove($dbms, $table_name, $column_name)
-{
- global $errored, $error_ary;
+ return true;
+ }
- switch ($dbms)
+ /**
+ * Function to prepare some column information for better usage
+ * @access private
+ */
+ function sql_prepare_column_data($table_name, $column_name, $column_data)
{
- case 'firebird':
- $sql = 'ALTER TABLE "' . $table_name . '" DROP "' . $column_name . '"';
- _sql($sql, $errored, $error_ary);
- break;
+ // Get type
+ if (strpos($column_data[0], ':') !== false)
+ {
+ list($orig_column_type, $column_length) = explode(':', $column_data[0]);
+ if (!is_array($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']))
+ {
+ $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'], $column_length);
+ }
+ else
+ {
+ if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule']))
+ {
+ switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][0])
+ {
+ case 'div':
+ $column_length /= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['rule'][1];
+ $column_length = ceil($column_length);
+ $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length);
+ break;
+ }
+ }
- case 'mssql':
- $sql = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
- _sql($sql, $errored, $error_ary);
- break;
+ if (isset($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit']))
+ {
+ switch ($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][0])
+ {
+ case 'mult':
+ $column_length *= $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][1];
+ if ($column_length > $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][2])
+ {
+ $column_type = $this->dbms_type_map[$this->sql_layer][$orig_column_type . ':']['limit'][3];
+ }
+ else
+ {
+ $column_type = sprintf($this->dbms_type_map[$this->sql_layer][$orig_column_type . ':'][0], $column_length);
+ }
+ break;
+ }
+ }
+ }
+ $orig_column_type .= ':';
+ }
+ else
+ {
+ $orig_column_type = $column_data[0];
+ $column_type = $this->dbms_type_map[$this->sql_layer][$column_data[0]];
+ }
- case 'mysql_40':
- case 'mysql_41':
- $sql = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`';
- _sql($sql, $errored, $error_ary);
- break;
+ // Adjust default value if db-dependant specified
+ if (is_array($column_data[1]))
+ {
+ $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default'];
+ }
- case 'oracle':
- $sql = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name;
- _sql($sql, $errored, $error_ary);
- break;
+ $sql = '';
- case 'postgres':
- $sql = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"';
- _sql($sql, $errored, $error_ary);
- break;
+ $return_array = array();
- case 'sqlite':
- if (version_compare(sqlite_libversion(), '3.0') == -1)
- {
- global $db;
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = $db->sql_query($sql);
+ switch ($this->sql_layer)
+ {
+ case 'firebird':
+ $sql .= " {$column_type} ";
- if (!$result)
+ if (!is_null($column_data[1]))
{
- break;
+ $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ' ';
}
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
+ $sql .= 'NOT NULL';
- $db->sql_transaction('begin');
+ // This is a UNICODE column and thus should be given it's fair share
+ if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0]))
+ {
+ $sql .= ' COLLATE UNICODE';
+ }
- // Create a backup table and populate it, destroy the existing one
- $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
- $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
- $db->sql_query('DROP TABLE ' . $table_name);
+ $return_array['auto_increment'] = false;
+ if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
+ {
+ $return_array['auto_increment'] = true;
+ }
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ break;
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ case 'mssql':
+ $sql .= " {$column_type} ";
+ $sql_default = " {$column_type} ";
- foreach ($old_table_cols as $declaration)
+ // For adding columns we need the default definition
+ if (!is_null($column_data[1]))
{
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
+ // For hexadecimal values do not use single quotes
+ if (strpos($column_data[1], '0x') === 0)
{
- continue;
+ $sql_default .= 'DEFAULT (' . $column_data[1] . ') ';
+ }
+ else
+ {
+ $sql_default .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') ';
}
- $column_list[] = $entities[0];
}
- $columns = implode(',', $column_list);
+ if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
+ {
+// $sql .= 'IDENTITY (1, 1) ';
+ $sql_default .= 'IDENTITY (1, 1) ';
+ }
- $new_table_cols = $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
+ $return_array['textimage'] = $column_type === '[text]';
- // create a new table and fill it up. destroy the temp one
- $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');');
- $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
- $db->sql_query('DROP TABLE ' . $table_name . '_temp');
+ $sql .= 'NOT NULL';
+ $sql_default .= 'NOT NULL';
- $db->sql_transaction('commit');
- }
- else
- {
- $sql = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
- _sql($sql, $errored, $error_ary);
- }
- break;
- }
-}
+ $return_array['column_type_sql_default'] = $sql_default;
-function sql_index_drop($dbms, $index_name, $table_name)
-{
- global $dbms_type_map, $db;
- global $errored, $error_ary;
+ break;
- switch ($dbms)
- {
- case 'mssql':
- $sql = 'DROP INDEX ' . $table_name . '.' . $index_name;
- _sql($sql, $errored, $error_ary);
- break;
+ case 'mysql_40':
+ case 'mysql_41':
+ $sql .= " {$column_type} ";
- case 'mysql_40':
- case 'mysql_41':
- $sql = 'DROP INDEX ' . $index_name . ' ON ' . $table_name;
- _sql($sql, $errored, $error_ary);
- break;
+ // For hexadecimal values do not use single quotes
+ if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob')
+ {
+ $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' ";
+ }
+ $sql .= 'NOT NULL';
- case 'firebird':
- case 'oracle':
- case 'postgres':
- case 'sqlite':
- $sql = 'DROP INDEX ' . $table_name . '_' . $index_name;
- _sql($sql, $errored, $error_ary);
- break;
- }
-}
+ if (isset($column_data[2]))
+ {
+ if ($column_data[2] == 'auto_increment')
+ {
+ $sql .= ' auto_increment';
+ }
+ else if ($this->sql_layer === 'mysql_41' && $column_data[2] == 'true_sort')
+ {
+ $sql .= ' COLLATE utf8_unicode_ci';
+ }
+ }
-function sql_create_primary_key($dbms, $table_name, $column)
-{
- global $dbms_type_map, $db;
- global $errored, $error_ary;
+ break;
- switch ($dbms)
- {
- case 'firebird':
- case 'postgres':
- $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
- _sql($sql, $errored, $error_ary);
- break;
+ case 'oracle':
+ $sql .= " {$column_type} ";
+ $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}' " : '';
- case 'mssql':
- $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD ";
- $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED (";
- $sql .= '[' . implode("],\n\t\t[", $column) . ']';
- $sql .= ') ON [PRIMARY]';
- _sql($sql, $errored, $error_ary);
- break;
+ // In Oracle empty strings ('') are treated as NULL.
+ // Therefore in oracle we allow NULL's for all DEFAULT '' entries
+ // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields)
+ if (!preg_match('/number/i', $column_type))
+ {
+ $sql .= ($column_data[1] === '') ? '' : 'NOT NULL';
+ }
- case 'mysql_40':
- case 'mysql_41':
- $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
- _sql($sql, $errored, $error_ary);
- break;
+ $return_array['auto_increment'] = false;
+ if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
+ {
+ $return_array['auto_increment'] = true;
+ }
- case 'oracle':
- $sql = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
- _sql($sql, $errored, $error_ary);
- break;
+ break;
- case 'sqlite':
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = _sql($sql, $errored, $error_ary);
+ case 'postgres':
+ $return_array['column_type'] = $column_type;
- if (!$result)
- {
- break;
- }
+ $sql .= " {$column_type} ";
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
+ $return_array['auto_increment'] = false;
+ if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
+ {
+ $default_val = "nextval('{$table_name}_seq')";
+ $return_array['auto_increment'] = true;
+ }
+ else if (!is_null($column_data[1]))
+ {
+ $default_val = "'" . $column_data[1] . "'";
+ $return_array['null'] = 'NOT NULL';
+ $sql .= 'NOT NULL ';
+ }
- $db->sql_transaction('begin');
+ $return_array['default'] = $default_val;
- // Create a backup table and populate it, destroy the existing one
- $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
- $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
- $db->sql_query('DROP TABLE ' . $table_name);
+ $sql .= "DEFAULT {$default_val}";
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ // Unsigned? Then add a CHECK contraint
+ if (in_array($orig_column_type, $this->unsigned_types))
+ {
+ $return_array['constraint'] = "CHECK ({$column_name} >= 0)";
+ $sql .= " CHECK ({$column_name} >= 0)";
+ }
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ break;
- foreach ($old_table_cols as $declaration)
- {
- $entities = preg_split('#\s+#', trim($declaration));
- if ($entities[0] == 'PRIMARY')
+ case 'sqlite':
+ $return_array['primary_key_set'] = false;
+ if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
{
- continue;
+ $sql .= ' INTEGER PRIMARY KEY';
+ $return_array['primary_key_set'] = true;
+ }
+ else
+ {
+ $sql .= ' ' . $column_type;
}
- $column_list[] = $entities[0];
- }
- $columns = implode(',', $column_list);
+ $sql .= ' NOT NULL ';
+ $sql .= (!is_null($column_data[1])) ? "DEFAULT '{$column_data[1]}'" : '';
- // create a new table and fill it up. destroy the temp one
- $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));');
- $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
- $db->sql_query('DROP TABLE ' . $table_name . '_temp');
+ break;
+ }
- $db->sql_transaction('commit');
- break;
- }
-}
+ $return_array['column_type_sql'] = $sql;
-function sql_create_unique_index($dbms, $index_name, $table_name, $column)
-{
- global $dbms_type_map, $db;
- global $errored, $error_ary;
+ return $return_array;
+ }
- switch ($dbms)
+ /**
+ * Add new column
+ */
+ function sql_column_add($table_name, $column_name, $column_data)
{
- case 'firebird':
- case 'postgres':
- case 'oracle':
- case 'sqlite':
- $sql = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
- _sql($sql, $errored, $error_ary);
- break;
+ $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
+ $statements = array();
- case 'mysql_40':
- case 'mysql_41':
- $sql = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
- _sql($sql, $errored, $error_ary);
- break;
+ switch ($this->sql_layer)
+ {
+ case 'firebird':
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ADD "' . strtoupper($column_name) . '" ' . $column_data['column_type_sql'];
+ break;
- case 'mssql':
- $sql = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
- _sql($sql, $errored, $error_ary);
- break;
- }
-}
+ case 'mssql':
+ $statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default'];
+ break;
-function sql_create_index($dbms, $index_name, $table_name, $column)
-{
- global $dbms_type_map, $db;
- global $errored, $error_ary;
+ case 'mysql_40':
+ case 'mysql_41':
+ $statements[] = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'];
+ break;
- switch ($dbms)
- {
- case 'firebird':
- case 'postgres':
- case 'oracle':
- case 'sqlite':
- $sql = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
- _sql($sql, $errored, $error_ary);
- break;
+ case 'oracle':
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql'];
+ break;
- case 'mysql_40':
- case 'mysql_41':
- $sql = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
- _sql($sql, $errored, $error_ary);
- break;
+ case 'postgres':
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql'];
+ break;
- case 'mssql':
- $sql = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
- _sql($sql, $errored, $error_ary);
- break;
- }
-}
+ case 'sqlite':
+ if (version_compare(sqlite_libversion(), '3.0') == -1)
+ {
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '{$table_name}'
+ ORDER BY type DESC, name;";
+ $result = $this->db->sql_query($sql);
+
+ if (!$result)
+ {
+ break;
+ }
-// List all of the indices that belong to a table,
-// does not count:
-// * UNIQUE indices
-// * PRIMARY keys
-function sql_list_index($dbms, $table_name)
-{
- global $dbms_type_map, $db;
- global $errored, $error_ary;
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
- $index_array = array();
+ $statements[] = 'begin';
- if ($dbms == 'mssql')
- {
- $sql = "EXEC sp_statistics '$table_name'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- if ($row['TYPE'] == 3)
- {
- $index_array[] = $row['INDEX_NAME'];
- }
+ // Create a backup table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
+
+ preg_match('#\((.*)\)#s', $row['sql'], $matches);
+
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
+
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities[0] == 'PRIMARY')
+ {
+ continue;
+ }
+ $column_list[] = $entities[0];
+ }
+
+ $columns = implode(',', $column_list);
+
+ $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
+
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+
+ $statements[] = 'commit';
+ }
+ else
+ {
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']';
+ }
+ break;
}
- $db->sql_freeresult($result);
+
+ return $this->_sql_run_sql($statements);
}
- else
+
+ /**
+ * Drop column
+ */
+ function sql_column_remove($table_name, $column_name)
{
- switch ($dbms)
+ $statements = array();
+
+ switch ($this->sql_layer)
{
case 'firebird':
- $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
- FROM RDB\$INDICES
- WHERE RDB\$RELATION_NAME = " . strtoupper($table_name) . "
- AND RDB\$UNIQUE_FLAG IS NULL
- AND RDB\$FOREIGN_KEY IS NULL";
- $col = 'index_name';
+ $statements[] = 'ALTER TABLE ' . $table_name . ' DROP "' . strtoupper($column_name) . '"';
break;
- case 'postgres':
- $sql = "SELECT ic.relname as index_name
- FROM pg_class bc, pg_class ic, pg_index i
- WHERE (bc.oid = i.indrelid)
- AND (ic.oid = i.indexrelid)
- AND (bc.relname = '" . $table_name . "')
- AND (i.indisunique != 't')
- AND (i.indisprimary != 't')";
- $col = 'index_name';
+ case 'mssql':
+ $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
break;
case 'mysql_40':
case 'mysql_41':
- $sql = 'SHOW KEYS
- FROM ' . $table_name;
- $col = 'Key_name';
+ $statements[] = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`';
break;
case 'oracle':
- $sql = "SELECT index_name
- FROM user_indexes
- WHERE table_name = '" . $table_name . "'
- AND generated = 'N'";
+ $statements[] = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name;
break;
- case 'sqlite':
- $sql = "PRAGMA index_info('" . $table_name . "');";
- $col = 'name';
+ case 'postgres':
+ $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"';
break;
- }
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- if (($dbms == 'mysql_40' || $dbms == 'mysql_41') && !$row['Non_unique'])
- {
- continue;
- }
+ case 'sqlite':
+ if (version_compare(sqlite_libversion(), '3.0') == -1)
+ {
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '{$table_name}'
+ ORDER BY type DESC, name;";
+ $result = $this->db->sql_query($sql);
+
+ if (!$result)
+ {
+ break;
+ }
- switch ($dbms)
- {
- case 'firebird':
- case 'oracle':
- case 'postgres':
- case 'sqlite':
- $row[$col] = substr($row[$col], strlen($table_name) + 1);
- break;
- }
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
- $index_array[] = $row[$col];
- }
- $db->sql_freeresult($result);
- }
+ $statements[] = 'begin';
- return array_map('strtolower', $index_array);
-}
+ // Create a backup table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
-// This is totally fake, never use it
-// it exists only to mend bad update functions introduced
-// * UNIQUE indices
-// * PRIMARY keys
-function sql_list_fake($dbms, $table_name)
-{
- global $dbms_type_map, $db;
- global $errored, $error_ary;
+ preg_match('#\((.*)\)#s', $row['sql'], $matches);
- $index_array = array();
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
- if ($dbms == 'mssql')
- {
- $sql = "EXEC sp_statistics '$table_name'";
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
- {
- if ($row['TYPE'] == 3)
- {
- $index_array[] = $row['INDEX_NAME'];
- }
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
+ {
+ continue;
+ }
+ $column_list[] = $entities[0];
+ }
+
+ $columns = implode(',', $column_list);
+
+ $new_table_cols = $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
+
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+
+ $statements[] = 'commit';
+ }
+ else
+ {
+ $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
+ }
+ break;
}
- $db->sql_freeresult($result);
+
+ return $this->_sql_run_sql($statements);
}
- else
+
+ /**
+ * Drop Index
+ */
+ function sql_index_drop($table_name, $index_name)
{
- switch ($dbms)
+ $statements = array();
+
+ switch ($this->sql_layer)
{
- case 'firebird':
- $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
- FROM RDB\$INDICES
- WHERE RDB\$RELATION_NAME = " . strtoupper($table_name) . "
- AND RDB\$UNIQUE_FLAG IS NULL
- AND RDB\$FOREIGN_KEY IS NULL";
- $col = 'index_name';
+ case 'mssql':
+ $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name;
break;
+ case 'mysql_40':
+ case 'mysql_41':
+ $statements[] = 'DROP INDEX ' . $index_name . ' ON ' . $table_name;
+ break;
+
+ case 'firebird':
+ case 'oracle':
case 'postgres':
- $sql = "SELECT ic.relname as index_name
- FROM pg_class bc, pg_class ic, pg_index i
- WHERE (bc.oid = i.indrelid)
- AND (ic.oid = i.indexrelid)
- AND (bc.relname = '" . $table_name . "')
- AND (i.indisunique != 't')
- AND (i.indisprimary != 't')";
- $col = 'index_name';
+ case 'sqlite':
+ $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name;
break;
+ }
+
+ return $this->_sql_run_sql($statements);
+ }
+ /**
+ * Add primary key
+ */
+ function sql_create_primary_key($table_name, $column)
+ {
+ $statements = array();
+
+ switch ($this->sql_layer)
+ {
+ case 'firebird':
+ case 'postgres':
case 'mysql_40':
case 'mysql_41':
- $sql = 'SHOW KEYS
- FROM ' . $table_name;
- $col = 'Key_name';
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
+ break;
+
+ case 'mssql':
+ $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD ";
+ $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED (";
+ $sql .= '[' . implode("],\n\t\t[", $column) . ']';
+ $sql .= ') ON [PRIMARY]';
+
+ $statements[] = $sql;
break;
case 'oracle':
- $sql = "SELECT index_name
- FROM user_indexes
- WHERE table_name = '" . $table_name . "'
- AND generated = 'N'";
+ $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
break;
case 'sqlite':
- $sql = "PRAGMA index_info('" . $table_name . "');";
- $col = 'name';
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '{$table_name}'
+ ORDER BY type DESC, name;";
+ $result = $this->db->sql_query($sql);
+
+ if (!$result)
+ {
+ break;
+ }
+
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ $statements[] = 'begin';
+
+ // Create a backup table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
+
+ preg_match('#\((.*)\)#s', $row['sql'], $matches);
+
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
+
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities[0] == 'PRIMARY')
+ {
+ continue;
+ }
+ $column_list[] = $entities[0];
+ }
+
+ $columns = implode(',', $column_list);
+
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));';
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
+
+ $statements[] = 'commit';
break;
}
- $result = $db->sql_query($sql);
- while ($row = $db->sql_fetchrow($result))
+ return $this->_sql_run_sql($statements);
+ }
+
+ /**
+ * Add unique index
+ */
+ function sql_create_unique_index($table_name, $index_name, $column)
+ {
+ $statements = array();
+
+ switch ($this->sql_layer)
{
- if (($dbms == 'mysql_40' || $dbms == 'mysql_41') && !$row['Non_unique'])
- {
- continue;
- }
+ case 'firebird':
+ case 'postgres':
+ case 'oracle':
+ case 'sqlite':
+ $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
+ break;
- $index_array[] = $row[$col];
+ case 'mysql_40':
+ case 'mysql_41':
+ $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
+ break;
+
+ case 'mssql':
+ $statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
+ break;
}
- $db->sql_freeresult($result);
+
+ return $this->_sql_run_sql($statements);
}
- return array_map('strtolower', $index_array);
-}
+ /**
+ * Add index
+ */
+ function sql_create_index($table_name, $index_name, $column)
+ {
+ $statements = array();
-/**
-* Change column type (not name!)
-*/
-function sql_column_change($dbms, $table_name, $column_name, $column_data)
-{
- global $dbms_type_map, $db;
- global $errored, $error_ary;
+ switch ($this->sql_layer)
+ {
+ case 'firebird':
+ case 'postgres':
+ case 'oracle':
+ case 'sqlite':
+ $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
+ break;
- $column_data = prepare_column_data($dbms, $column_data, $table_name, $column_name);
+ case 'mysql_40':
+ case 'mysql_41':
+ $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
+ break;
+
+ case 'mssql':
+ $statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
+ break;
+ }
+
+ return $this->_sql_run_sql($statements);
+ }
- switch ($dbms)
+ /**
+ * Change column type (not name!)
+ */
+ function sql_column_change($table_name, $column_name, $column_data)
{
- case 'firebird':
- // Change type...
- $sql = 'ALTER TABLE "' . $table_name . '" ALTER COLUMN "' . $column_name . '" TYPE ' . ' ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
+ $statements = array();
- case 'mssql':
- $sql = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ switch ($this->sql_layer)
+ {
+ case 'firebird':
+ // Change type...
+ $statements[] = 'ALTER TABLE ' . $table_name . ' ALTER COLUMN "' . strtoupper($column_name) . '" TYPE ' . ' ' . $column_data['column_type_sql'];
+ break;
- case 'mysql_40':
- case 'mysql_41':
- $sql = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ case 'mssql':
+ $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
+ break;
- case 'oracle':
- $sql = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql'];
- _sql($sql, $errored, $error_ary);
- break;
+ case 'mysql_40':
+ case 'mysql_41':
+ $statements[] = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql'];
+ break;
- case 'postgres':
- $sql = 'ALTER TABLE ' . $table_name . ' ';
+ case 'oracle':
+ $statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql'];
+ break;
- $sql_array = array();
- $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type'];
+ case 'postgres':
+ $sql = 'ALTER TABLE ' . $table_name . ' ';
- if (isset($column_data['null']))
- {
- if ($column_data['null'] == 'NOT NULL')
+ $sql_array = array();
+ $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type'];
+
+ if (isset($column_data['null']))
{
- $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL';
+ if ($column_data['null'] == 'NOT NULL')
+ {
+ $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL';
+ }
+ else if ($column_data['null'] == 'NULL')
+ {
+ $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL';
+ }
}
- else if ($column_data['null'] == 'NULL')
+
+ if (isset($column_data['default']))
{
- $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL';
+ $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default'];
}
- }
- if (isset($column_data['default']))
- {
- $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default'];
- }
-
- // we don't want to double up on constraints if we change different number data types
- if (isset($column_data['constraint']))
- {
- $constraint_sql = "SELECT consrc as constraint_data
- FROM pg_constraint, pg_class bc
- WHERE conrelid = bc.oid
- AND bc.relname = '{$table_name}'
- AND NOT EXISTS (
- SELECT *
- FROM pg_constraint as c, pg_inherits as i
- WHERE i.inhrelid = pg_constraint.conrelid
- AND c.conname = pg_constraint.conname
- AND c.consrc = pg_constraint.consrc
- AND c.conrelid = i.inhparent
- )";
-
- $constraint_exists = false;
-
- $result = $db->sql_query($constraint_sql);
- while ($row = $db->sql_fetchrow($result))
+ // we don't want to double up on constraints if we change different number data types
+ if (isset($column_data['constraint']))
{
- if (trim($row['constraint_data']) == trim($column_data['constraint']))
+ $constraint_sql = "SELECT consrc as constraint_data
+ FROM pg_constraint, pg_class bc
+ WHERE conrelid = bc.oid
+ AND bc.relname = '{$table_name}'
+ AND NOT EXISTS (
+ SELECT *
+ FROM pg_constraint as c, pg_inherits as i
+ WHERE i.inhrelid = pg_constraint.conrelid
+ AND c.conname = pg_constraint.conname
+ AND c.consrc = pg_constraint.consrc
+ AND c.conrelid = i.inhparent
+ )";
+
+ $constraint_exists = false;
+
+ $result = $this->db->sql_query($constraint_sql);
+ while ($row = $this->db->sql_fetchrow($result))
{
- $constraint_exists = true;
- break;
+ if (trim($row['constraint_data']) == trim($column_data['constraint']))
+ {
+ $constraint_exists = true;
+ break;
+ }
}
- }
- $db->sql_freeresult($result);
+ $this->db->sql_freeresult($result);
- if (!$constraint_exists)
- {
- $sql_array[] = 'ADD ' . $column_data['constraint'];
+ if (!$constraint_exists)
+ {
+ $sql_array[] = 'ADD ' . $column_data['constraint'];
+ }
}
- }
- $sql .= implode(', ', $sql_array);
+ $sql .= implode(', ', $sql_array);
- _sql($sql, $errored, $error_ary);
- break;
+ $statements[] = $sql;
+ break;
- case 'sqlite':
+ case 'sqlite':
- $sql = "SELECT sql
- FROM sqlite_master
- WHERE type = 'table'
- AND name = '{$table_name}'
- ORDER BY type DESC, name;";
- $result = _sql($sql, $errored, $error_ary);
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '{$table_name}'
+ ORDER BY type DESC, name;";
+ $result = $this->db->sql_query($sql);
- if (!$result)
- {
- break;
- }
+ if (!$result)
+ {
+ break;
+ }
- $row = $db->sql_fetchrow($result);
- $db->sql_freeresult($result);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
- $db->sql_transaction('begin');
+ $statements[] = 'begin';
- // Create a temp table and populate it, destroy the existing one
- $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
- $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
- $db->sql_query('DROP TABLE ' . $table_name);
+ // Create a temp table and populate it, destroy the existing one
+ $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
+ $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
+ $statements[] = 'DROP TABLE ' . $table_name;
- preg_match('#\((.*)\)#s', $row['sql'], $matches);
+ preg_match('#\((.*)\)#s', $row['sql'], $matches);
- $new_table_cols = trim($matches[1]);
- $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
- $column_list = array();
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
+ $column_list = array();
- foreach ($old_table_cols as $key => $declaration)
- {
- $entities = preg_split('#\s+#', trim($declaration));
- $column_list[] = $entities[0];
- if ($entities[0] == $column_name)
+ foreach ($old_table_cols as $key => $declaration)
{
- $old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql'];
+ $entities = preg_split('#\s+#', trim($declaration));
+ $column_list[] = $entities[0];
+ if ($entities[0] == $column_name)
+ {
+ $old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql'];
+ }
}
- }
- $columns = implode(',', $column_list);
+ $columns = implode(',', $column_list);
- // create a new table and fill it up. destroy the temp one
- $db->sql_query('CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');');
- $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
- $db->sql_query('DROP TABLE ' . $table_name . '_temp');
+ // create a new table and fill it up. destroy the temp one
+ $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');';
+ $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
+ $statements[] = 'DROP TABLE ' . $table_name . '_temp';
- $db->sql_transaction('commit');
+ $statements[] = 'commit';
- break;
- }
-}
-
-function utf8_new_clean_string($text)
-{
- static $homographs = array();
- static $utf8_case_fold_nfkc = '';
- if (empty($homographs))
- {
- global $phpbb_root_path, $phpEx;
- if (!function_exists('utf8_case_fold_nfkc') || !file_exists($phpbb_root_path . 'includes/utf/data/confusables.' . $phpEx))
- {
- if (!file_exists($phpbb_root_path . 'install/data/confusables.' . $phpEx))
- {
- global $lang;
- trigger_error(sprintf($lang['UPDATE_REQUIRES_FILE'], $phpbb_root_path . 'install/data/confusables.' . $phpEx), E_USER_ERROR);
- }
- $homographs = include($phpbb_root_path . 'install/data/confusables.' . $phpEx);
- $utf8_case_fold_nfkc = 'utf8_new_case_fold_nfkc';
- }
- else
- {
- $homographs = include($phpbb_root_path . 'includes/utf/data/confusables.' . $phpEx);
- $utf8_case_fold_nfkc = 'utf8_case_fold_nfkc';
+ break;
}
- }
-
- $text = $utf8_case_fold_nfkc($text);
- $text = strtr($text, $homographs);
- // Other control characters
- $text = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $text);
-
- $text = preg_replace('# {2,}#', ' ', $text);
- // we can use trim here as all the other space characters should have been turned
- // into normal ASCII spaces by now
- return trim($text);
+ return $this->_sql_run_sql($statements);
+ }
}
-?>
+?> \ No newline at end of file