mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 06:08:52 +00:00
Fix database updater and db tools to support multiple column changes/additions/removals with SQLite
git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@9735 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
parent
51885a2734
commit
55e15b4c8e
3 changed files with 450 additions and 35 deletions
|
@ -148,6 +148,7 @@
|
||||||
<li>[Fix] View end of ban in MCP and ACP when user is banned by duration (Bug #47815 - Patch by Pyramide)</li>
|
<li>[Fix] View end of ban in MCP and ACP when user is banned by duration (Bug #47815 - Patch by Pyramide)</li>
|
||||||
<li>[Fix] Display user's posts count in private message when it is equal to 0 (prosilver). (Bug #40155 - Patch by rxu)</li>
|
<li>[Fix] Display user's posts count in private message when it is equal to 0 (prosilver). (Bug #40155 - Patch by rxu)</li>
|
||||||
<li>[Fix] Disable word-censor option in UCP lacks the config-setting (Bug #47575 - Patch by 00mohgta7)</li>
|
<li>[Fix] Disable word-censor option in UCP lacks the config-setting (Bug #47575 - Patch by 00mohgta7)</li>
|
||||||
|
<li>[Fix] Fix database updater and db tools to support multiple column changes/additions/removals with SQLite</li>
|
||||||
<li>[Change] Change the data format of the default file ACM to be more secure from tampering and have better performance.</li>
|
<li>[Change] Change the data format of the default file ACM to be more secure from tampering and have better performance.</li>
|
||||||
<li>[Change] Add index on log_time to the log table to prevent slowdown on boards with many log entries. (Bug #44665 - Patch by bantu)</li>
|
<li>[Change] Add index on log_time to the log table to prevent slowdown on boards with many log entries. (Bug #44665 - Patch by bantu)</li>
|
||||||
<li>[Change] Template engine now permits to a limited extent variable includes.</li>
|
<li>[Change] Template engine now permits to a limited extent variable includes.</li>
|
||||||
|
|
|
@ -347,6 +347,11 @@ class phpbb_db_tools
|
||||||
// holds the DDL for a column
|
// holds the DDL for a column
|
||||||
$columns = $statements = array();
|
$columns = $statements = array();
|
||||||
|
|
||||||
|
if ($this->sql_table_exists($table_name))
|
||||||
|
{
|
||||||
|
return $this->_sql_run_sql($statements);
|
||||||
|
}
|
||||||
|
|
||||||
// Begin transaction
|
// Begin transaction
|
||||||
$statements[] = 'begin';
|
$statements[] = 'begin';
|
||||||
|
|
||||||
|
@ -580,6 +585,14 @@ class phpbb_db_tools
|
||||||
}
|
}
|
||||||
|
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
$sqlite = false;
|
||||||
|
|
||||||
|
// For SQLite we need to perform the schema changes in a much more different way
|
||||||
|
if ($this->db->sql_layer == 'sqlite' && $this->return_statements)
|
||||||
|
{
|
||||||
|
$sqlite_data = array();
|
||||||
|
$sqlite = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Change columns?
|
// Change columns?
|
||||||
if (!empty($schema_changes['change_columns']))
|
if (!empty($schema_changes['change_columns']))
|
||||||
|
@ -589,16 +602,27 @@ class phpbb_db_tools
|
||||||
foreach ($columns as $column_name => $column_data)
|
foreach ($columns as $column_name => $column_data)
|
||||||
{
|
{
|
||||||
// If the column exists we change it, else we add it ;)
|
// If the column exists we change it, else we add it ;)
|
||||||
if ($this->sql_column_exists($table, $column_name))
|
if ($column_exists = $this->sql_column_exists($table, $column_name))
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_change($table, $column_name, $column_data);
|
$result = $this->sql_column_change($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_add($table, $column_name, $column_data);
|
$result = $this->sql_column_add($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
if ($column_exists)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['change_columns'][] = $result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['add_columns'][] = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -614,16 +638,27 @@ class phpbb_db_tools
|
||||||
foreach ($columns as $column_name => $column_data)
|
foreach ($columns as $column_name => $column_data)
|
||||||
{
|
{
|
||||||
// Only add the column if it does not exist yet, else change it (to be consistent)
|
// Only add the column if it does not exist yet, else change it (to be consistent)
|
||||||
if ($this->sql_column_exists($table, $column_name))
|
if ($column_exists = $this->sql_column_exists($table, $column_name))
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_change($table, $column_name, $column_data);
|
$result = $this->sql_column_change($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_add($table, $column_name, $column_data);
|
$result = $this->sql_column_add($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
if ($column_exists)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['change_columns'][] = $result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['add_columns'][] = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -658,9 +693,13 @@ class phpbb_db_tools
|
||||||
// Only remove the column if it exists...
|
// Only remove the column if it exists...
|
||||||
if ($this->sql_column_exists($table, $column))
|
if ($this->sql_column_exists($table, $column))
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_remove($table, $column);
|
$result = $this->sql_column_remove($table, $column, true);
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['drop_columns'][] = $result;
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -674,9 +713,13 @@ class phpbb_db_tools
|
||||||
{
|
{
|
||||||
foreach ($schema_changes['add_primary_keys'] as $table => $columns)
|
foreach ($schema_changes['add_primary_keys'] as $table => $columns)
|
||||||
{
|
{
|
||||||
$result = $this->sql_create_primary_key($table, $columns);
|
$result = $this->sql_create_primary_key($table, $columns, true);
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['primary_key'] = $result;
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -717,6 +760,147 @@ class phpbb_db_tools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
foreach ($sqlite_data as $table_name => $sql_schema_changes)
|
||||||
|
{
|
||||||
|
// Create temporary table with original data
|
||||||
|
$statements[] = 'begin';
|
||||||
|
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $this->db->sql_fetchrow($result);
|
||||||
|
$this->db->sql_freeresult($result);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// Get the columns...
|
||||||
|
preg_match('#\((.*)\)#s', $row['sql'], $matches);
|
||||||
|
|
||||||
|
$plain_table_cols = trim($matches[1]);
|
||||||
|
$new_table_cols = preg_split('/,(?![\s\w]+\))/m', $plain_table_cols);
|
||||||
|
$column_list = array();
|
||||||
|
|
||||||
|
foreach ($new_table_cols as $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if ($entities[0] == 'PRIMARY')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$column_list[] = $entities[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// note down the primary key notation because sqlite only supports adding it to the end for the new table
|
||||||
|
$primary_key = false;
|
||||||
|
$_new_cols = array();
|
||||||
|
|
||||||
|
foreach ($new_table_cols as $key => $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if ($entities[0] == 'PRIMARY')
|
||||||
|
{
|
||||||
|
$primary_key = $declaration;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$_new_cols[] = $declaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_table_cols = $_new_cols;
|
||||||
|
|
||||||
|
// First of all... change columns
|
||||||
|
if (!empty($sql_schema_changes['change_columns']))
|
||||||
|
{
|
||||||
|
foreach ($sql_schema_changes['change_columns'] as $column_sql)
|
||||||
|
{
|
||||||
|
foreach ($new_table_cols as $key => $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if (strpos($column_sql, $entities[0] . ' ') === 0)
|
||||||
|
{
|
||||||
|
$new_table_cols[$key] = $column_sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($sql_schema_changes['add_columns']))
|
||||||
|
{
|
||||||
|
foreach ($sql_schema_changes['add_columns'] as $column_sql)
|
||||||
|
{
|
||||||
|
$new_table_cols[] = $column_sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now drop them...
|
||||||
|
if (!empty($sql_schema_changes['drop_columns']))
|
||||||
|
{
|
||||||
|
foreach ($sql_schema_changes['drop_columns'] as $column_name)
|
||||||
|
{
|
||||||
|
// Remove from column list...
|
||||||
|
$new_column_list = array();
|
||||||
|
foreach ($column_list as $key => $value)
|
||||||
|
{
|
||||||
|
if ($value === $column_name)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_column_list[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$column_list = $new_column_list;
|
||||||
|
|
||||||
|
// Remove from table...
|
||||||
|
$_new_cols = array();
|
||||||
|
foreach ($new_table_cols as $key => $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if (strpos($column_name . ' ', $entities[0] . ' ') === 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$_new_cols[] = $declaration;
|
||||||
|
}
|
||||||
|
$new_table_cols = $_new_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primary key...
|
||||||
|
if (!empty($sql_schema_changes['primary_key']))
|
||||||
|
{
|
||||||
|
$new_table_cols[] = 'PRIMARY KEY (' . implode(', ', $sql_schema_changes['primary_key']) . ')';
|
||||||
|
}
|
||||||
|
// Add a new one or the old primary key
|
||||||
|
else if ($primary_key !== false)
|
||||||
|
{
|
||||||
|
$new_table_cols[] = $primary_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = implode(',', $column_list);
|
||||||
|
|
||||||
|
// create a new table and fill it up. destroy the temp one
|
||||||
|
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $new_table_cols) . ');';
|
||||||
|
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
||||||
|
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
||||||
|
|
||||||
|
$statements[] = 'commit';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($this->return_statements)
|
||||||
{
|
{
|
||||||
return $statements;
|
return $statements;
|
||||||
|
@ -1131,7 +1315,7 @@ class phpbb_db_tools
|
||||||
/**
|
/**
|
||||||
* Add new column
|
* Add new column
|
||||||
*/
|
*/
|
||||||
function sql_column_add($table_name, $column_name, $column_data)
|
function sql_column_add($table_name, $column_name, $column_data, $inline = false)
|
||||||
{
|
{
|
||||||
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
@ -1160,6 +1344,12 @@ class phpbb_db_tools
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
||||||
{
|
{
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
|
@ -1224,7 +1414,7 @@ class phpbb_db_tools
|
||||||
/**
|
/**
|
||||||
* Drop column
|
* Drop column
|
||||||
*/
|
*/
|
||||||
function sql_column_remove($table_name, $column_name)
|
function sql_column_remove($table_name, $column_name, $inline = false)
|
||||||
{
|
{
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
|
||||||
|
@ -1252,6 +1442,12 @@ class phpbb_db_tools
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column_name;
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
||||||
{
|
{
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
|
@ -1294,7 +1490,7 @@ class phpbb_db_tools
|
||||||
|
|
||||||
$columns = implode(',', $column_list);
|
$columns = implode(',', $column_list);
|
||||||
|
|
||||||
$new_table_cols = $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $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
|
// create a new table and fill it up. destroy the temp one
|
||||||
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
|
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
|
||||||
|
@ -1349,6 +1545,11 @@ class phpbb_db_tools
|
||||||
{
|
{
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
|
||||||
|
if (!$this->sql_table_exists($table_name))
|
||||||
|
{
|
||||||
|
return $this->_sql_run_sql($statements);
|
||||||
|
}
|
||||||
|
|
||||||
// the most basic operation, get rid of the table
|
// the most basic operation, get rid of the table
|
||||||
$statements[] = 'DROP TABLE ' . $table_name;
|
$statements[] = 'DROP TABLE ' . $table_name;
|
||||||
|
|
||||||
|
@ -1407,7 +1608,7 @@ class phpbb_db_tools
|
||||||
/**
|
/**
|
||||||
* Add primary key
|
* Add primary key
|
||||||
*/
|
*/
|
||||||
function sql_create_primary_key($table_name, $column)
|
function sql_create_primary_key($table_name, $column, $inline = false)
|
||||||
{
|
{
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
|
||||||
|
@ -1434,6 +1635,12 @@ class phpbb_db_tools
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column;
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
WHERE type = 'table'
|
WHERE type = 'table'
|
||||||
|
@ -1641,7 +1848,7 @@ class phpbb_db_tools
|
||||||
/**
|
/**
|
||||||
* Change column type (not name!)
|
* Change column type (not name!)
|
||||||
*/
|
*/
|
||||||
function sql_column_change($table_name, $column_name, $column_data)
|
function sql_column_change($table_name, $column_name, $column_data, $inline = false)
|
||||||
{
|
{
|
||||||
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
@ -1739,6 +1946,11 @@ class phpbb_db_tools
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
WHERE type = 'table'
|
WHERE type = 'table'
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
$updates_to_version = '3.0.6-dev';
|
$updates_to_version = '3.0.6-dev';
|
||||||
|
|
||||||
// Enter any version to update from to test updates. The version within the db will not be updated.
|
// Enter any version to update from to test updates. The version within the db will not be updated.
|
||||||
$debug_from_version = false;
|
$debug_from_version = '3.0.5';
|
||||||
|
|
||||||
// Which oldest version does this updater supports?
|
// Which oldest version does this updater supports?
|
||||||
$oldest_from_version = '3.0.0';
|
$oldest_from_version = '3.0.0';
|
||||||
|
@ -1292,7 +1292,7 @@ function change_database_data(&$no_updates, $version)
|
||||||
$result = $db->sql_query_limit($sql, 1);
|
$result = $db->sql_query_limit($sql, 1);
|
||||||
$user_option = (int) $db->sql_fetchfield('user_options');
|
$user_option = (int) $db->sql_fetchfield('user_options');
|
||||||
$db->sql_freeresult($result);
|
$db->sql_freeresult($result);
|
||||||
|
|
||||||
// Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option
|
// Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option
|
||||||
if (!($user_option & 1 << 15))
|
if (!($user_option & 1 << 15))
|
||||||
{
|
{
|
||||||
|
@ -1631,6 +1631,14 @@ class updater_db_tools
|
||||||
}
|
}
|
||||||
|
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
$sqlite = false;
|
||||||
|
|
||||||
|
// For SQLite we need to perform the schema changes in a much more different way
|
||||||
|
if ($this->db->sql_layer == 'sqlite' && $this->return_statements)
|
||||||
|
{
|
||||||
|
$sqlite_data = array();
|
||||||
|
$sqlite = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Change columns?
|
// Change columns?
|
||||||
if (!empty($schema_changes['change_columns']))
|
if (!empty($schema_changes['change_columns']))
|
||||||
|
@ -1640,16 +1648,27 @@ class updater_db_tools
|
||||||
foreach ($columns as $column_name => $column_data)
|
foreach ($columns as $column_name => $column_data)
|
||||||
{
|
{
|
||||||
// If the column exists we change it, else we add it ;)
|
// If the column exists we change it, else we add it ;)
|
||||||
if ($this->sql_column_exists($table, $column_name))
|
if ($column_exists = $this->sql_column_exists($table, $column_name))
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_change($table, $column_name, $column_data);
|
$result = $this->sql_column_change($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_add($table, $column_name, $column_data);
|
$result = $this->sql_column_add($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
if ($column_exists)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['change_columns'][] = $result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['add_columns'][] = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -1665,16 +1684,27 @@ class updater_db_tools
|
||||||
foreach ($columns as $column_name => $column_data)
|
foreach ($columns as $column_name => $column_data)
|
||||||
{
|
{
|
||||||
// Only add the column if it does not exist yet, else change it (to be consistent)
|
// Only add the column if it does not exist yet, else change it (to be consistent)
|
||||||
if ($this->sql_column_exists($table, $column_name))
|
if ($column_exists = $this->sql_column_exists($table, $column_name))
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_change($table, $column_name, $column_data);
|
$result = $this->sql_column_change($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_add($table, $column_name, $column_data);
|
$result = $this->sql_column_add($table, $column_name, $column_data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
if ($column_exists)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['change_columns'][] = $result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['add_columns'][] = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -1709,9 +1739,13 @@ class updater_db_tools
|
||||||
// Only remove the column if it exists...
|
// Only remove the column if it exists...
|
||||||
if ($this->sql_column_exists($table, $column))
|
if ($this->sql_column_exists($table, $column))
|
||||||
{
|
{
|
||||||
$result = $this->sql_column_remove($table, $column);
|
$result = $this->sql_column_remove($table, $column, true);
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['drop_columns'][] = $result;
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -1725,9 +1759,13 @@ class updater_db_tools
|
||||||
{
|
{
|
||||||
foreach ($schema_changes['add_primary_keys'] as $table => $columns)
|
foreach ($schema_changes['add_primary_keys'] as $table => $columns)
|
||||||
{
|
{
|
||||||
$result = $this->sql_create_primary_key($table, $columns);
|
$result = $this->sql_create_primary_key($table, $columns, true);
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
$sqlite_data[$table]['primary_key'] = $result;
|
||||||
|
}
|
||||||
|
else if ($this->return_statements)
|
||||||
{
|
{
|
||||||
$statements = array_merge($statements, $result);
|
$statements = array_merge($statements, $result);
|
||||||
}
|
}
|
||||||
|
@ -1768,6 +1806,147 @@ class updater_db_tools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($sqlite)
|
||||||
|
{
|
||||||
|
foreach ($sqlite_data as $table_name => $sql_schema_changes)
|
||||||
|
{
|
||||||
|
// Create temporary table with original data
|
||||||
|
$statements[] = 'begin';
|
||||||
|
|
||||||
|
$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)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $this->db->sql_fetchrow($result);
|
||||||
|
$this->db->sql_freeresult($result);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// Get the columns...
|
||||||
|
preg_match('#\((.*)\)#s', $row['sql'], $matches);
|
||||||
|
|
||||||
|
$plain_table_cols = trim($matches[1]);
|
||||||
|
$new_table_cols = preg_split('/,(?![\s\w]+\))/m', $plain_table_cols);
|
||||||
|
$column_list = array();
|
||||||
|
|
||||||
|
foreach ($new_table_cols as $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if ($entities[0] == 'PRIMARY')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$column_list[] = $entities[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// note down the primary key notation because sqlite only supports adding it to the end for the new table
|
||||||
|
$primary_key = false;
|
||||||
|
$_new_cols = array();
|
||||||
|
|
||||||
|
foreach ($new_table_cols as $key => $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if ($entities[0] == 'PRIMARY')
|
||||||
|
{
|
||||||
|
$primary_key = $declaration;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$_new_cols[] = $declaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_table_cols = $_new_cols;
|
||||||
|
|
||||||
|
// First of all... change columns
|
||||||
|
if (!empty($sql_schema_changes['change_columns']))
|
||||||
|
{
|
||||||
|
foreach ($sql_schema_changes['change_columns'] as $column_sql)
|
||||||
|
{
|
||||||
|
foreach ($new_table_cols as $key => $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if (strpos($column_sql, $entities[0] . ' ') === 0)
|
||||||
|
{
|
||||||
|
$new_table_cols[$key] = $column_sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($sql_schema_changes['add_columns']))
|
||||||
|
{
|
||||||
|
foreach ($sql_schema_changes['add_columns'] as $column_sql)
|
||||||
|
{
|
||||||
|
$new_table_cols[] = $column_sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now drop them...
|
||||||
|
if (!empty($sql_schema_changes['drop_columns']))
|
||||||
|
{
|
||||||
|
foreach ($sql_schema_changes['drop_columns'] as $column_name)
|
||||||
|
{
|
||||||
|
// Remove from column list...
|
||||||
|
$new_column_list = array();
|
||||||
|
foreach ($column_list as $key => $value)
|
||||||
|
{
|
||||||
|
if ($value === $column_name)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_column_list[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$column_list = $new_column_list;
|
||||||
|
|
||||||
|
// Remove from table...
|
||||||
|
$_new_cols = array();
|
||||||
|
foreach ($new_table_cols as $key => $declaration)
|
||||||
|
{
|
||||||
|
$entities = preg_split('#\s+#', trim($declaration));
|
||||||
|
if (strpos($column_name . ' ', $entities[0] . ' ') === 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$_new_cols[] = $declaration;
|
||||||
|
}
|
||||||
|
$new_table_cols = $_new_cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primary key...
|
||||||
|
if (!empty($sql_schema_changes['primary_key']))
|
||||||
|
{
|
||||||
|
$new_table_cols[] = 'PRIMARY KEY (' . implode(', ', $sql_schema_changes['primary_key']) . ')';
|
||||||
|
}
|
||||||
|
// Add a new one or the old primary key
|
||||||
|
else if ($primary_key !== false)
|
||||||
|
{
|
||||||
|
$new_table_cols[] = $primary_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
$columns = implode(',', $column_list);
|
||||||
|
|
||||||
|
// create a new table and fill it up. destroy the temp one
|
||||||
|
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $new_table_cols) . ');';
|
||||||
|
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
||||||
|
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
||||||
|
|
||||||
|
$statements[] = 'commit';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->return_statements)
|
if ($this->return_statements)
|
||||||
{
|
{
|
||||||
return $statements;
|
return $statements;
|
||||||
|
@ -2182,7 +2361,7 @@ class updater_db_tools
|
||||||
/**
|
/**
|
||||||
* Add new column
|
* Add new column
|
||||||
*/
|
*/
|
||||||
function sql_column_add($table_name, $column_name, $column_data)
|
function sql_column_add($table_name, $column_name, $column_data, $inline = false)
|
||||||
{
|
{
|
||||||
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
@ -2216,6 +2395,12 @@ class updater_db_tools
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
||||||
{
|
{
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
|
@ -2280,7 +2465,7 @@ class updater_db_tools
|
||||||
/**
|
/**
|
||||||
* Drop column
|
* Drop column
|
||||||
*/
|
*/
|
||||||
function sql_column_remove($table_name, $column_name)
|
function sql_column_remove($table_name, $column_name, $inline = false)
|
||||||
{
|
{
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
|
||||||
|
@ -2308,6 +2493,12 @@ class updater_db_tools
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column_name;
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
||||||
{
|
{
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
|
@ -2401,7 +2592,7 @@ class updater_db_tools
|
||||||
/**
|
/**
|
||||||
* Add primary key
|
* Add primary key
|
||||||
*/
|
*/
|
||||||
function sql_create_primary_key($table_name, $column)
|
function sql_create_primary_key($table_name, $column, $inline = false)
|
||||||
{
|
{
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
|
||||||
|
@ -2428,6 +2619,12 @@ class updater_db_tools
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column;
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
WHERE type = 'table'
|
WHERE type = 'table'
|
||||||
|
@ -2541,7 +2738,7 @@ class updater_db_tools
|
||||||
/**
|
/**
|
||||||
* Change column type (not name!)
|
* Change column type (not name!)
|
||||||
*/
|
*/
|
||||||
function sql_column_change($table_name, $column_name, $column_data)
|
function sql_column_change($table_name, $column_name, $column_data, $inline = false)
|
||||||
{
|
{
|
||||||
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
|
||||||
$statements = array();
|
$statements = array();
|
||||||
|
@ -2639,6 +2836,11 @@ class updater_db_tools
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
|
}
|
||||||
|
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
WHERE type = 'table'
|
WHERE type = 'table'
|
||||||
|
|
Loading…
Add table
Reference in a new issue