mirror of
https://github.com/phpbb/phpbb.git
synced 2025-05-03 14:17:56 +02:00
Merge remote-tracking branch 'github-nickvergessen/feature/sqlite3' into develop-ascraeus
* github-nickvergessen/feature/sqlite3: [feature/sqlite3] Add sqlite3 database to .gitignore [feature/sqlite3] Use SQLite3 by default [feature/sqlite3] Remove invalid comment [feature/sqlite3] Remove unneeded ORDER BY type from sqlite_master queries [feature/sqlite3] Correctly recreate indexes when recreating a table [feature/sqlite3] Fix sql_index_drop() for sqlite3 [feature/sqlite3] Remove trailing comma from column list [feature/sqlite3] Update docblocks and function visibility [feature/sqlite3] Add support for SQLite 3
This commit is contained in:
commit
f0be9549ac
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,6 +12,6 @@
|
|||||||
/phpBB/images/avatars/upload/*
|
/phpBB/images/avatars/upload/*
|
||||||
/phpBB/store/*
|
/phpBB/store/*
|
||||||
/phpBB/vendor
|
/phpBB/vendor
|
||||||
/tests/phpbb_unit_tests.sqlite2
|
/tests/phpbb_unit_tests.sqlite*
|
||||||
/tests/test_config*.php
|
/tests/test_config*.php
|
||||||
/tests/tmp/*
|
/tests/tmp/*
|
||||||
|
@ -40,5 +40,7 @@ matrix:
|
|||||||
env: DB=mariadb
|
env: DB=mariadb
|
||||||
- php: 5.4
|
- php: 5.4
|
||||||
env: DB=postgres
|
env: DB=postgres
|
||||||
|
- php: 5.4
|
||||||
|
env: DB=sqlite3
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- php: hhvm
|
- php: hhvm
|
||||||
|
@ -376,6 +376,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting)
|
|||||||
|
|
||||||
case 'mssql':
|
case 'mssql':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
|
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ foreach ($supported_dbms as $dbms)
|
|||||||
case 'mysql_41':
|
case 'mysql_41':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
fwrite($fp, "# DO NOT EDIT THIS FILE, IT IS GENERATED\n");
|
fwrite($fp, "# DO NOT EDIT THIS FILE, IT IS GENERATED\n");
|
||||||
fwrite($fp, "#\n");
|
fwrite($fp, "#\n");
|
||||||
fwrite($fp, "# To change the contents of this file, edit\n");
|
fwrite($fp, "# To change the contents of this file, edit\n");
|
||||||
|
@ -134,7 +134,8 @@
|
|||||||
<li>MySQL 3.23 or above (MySQLi supported)</li>
|
<li>MySQL 3.23 or above (MySQLi supported)</li>
|
||||||
<li>MariaDB 5.1 or above</li>
|
<li>MariaDB 5.1 or above</li>
|
||||||
<li>PostgreSQL 8.3+</li>
|
<li>PostgreSQL 8.3+</li>
|
||||||
<li>SQLite 2.8.2+ (SQLite 3 is not supported)</li>
|
<li>SQLite 2.8.2+</li>
|
||||||
|
<li>SQLite 3.6.15+</li>
|
||||||
<li>Firebird 2.1+</li>
|
<li>Firebird 2.1+</li>
|
||||||
<li>MS SQL Server 2000 or above (directly or via ODBC or the native adapter)</li>
|
<li>MS SQL Server 2000 or above (directly or via ODBC or the native adapter)</li>
|
||||||
<li>Oracle</li>
|
<li>Oracle</li>
|
||||||
|
@ -101,6 +101,10 @@ class acp_database
|
|||||||
$extractor = new sqlite_extractor($format, $filename, $time, $download, $store);
|
$extractor = new sqlite_extractor($format, $filename, $time, $download, $store);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'sqlite3':
|
||||||
|
$extractor = new sqlite3_extractor($format, $filename, $time, $download, $store);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'postgres':
|
case 'postgres':
|
||||||
$extractor = new postgres_extractor($format, $filename, $time, $download, $store);
|
$extractor = new postgres_extractor($format, $filename, $time, $download, $store);
|
||||||
break;
|
break;
|
||||||
@ -135,6 +139,7 @@ class acp_database
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$extractor->flush('DELETE FROM ' . $table_name . ";\n");
|
$extractor->flush('DELETE FROM ' . $table_name . ";\n");
|
||||||
break;
|
break;
|
||||||
@ -325,6 +330,7 @@ class acp_database
|
|||||||
case 'mysql4':
|
case 'mysql4':
|
||||||
case 'mysqli':
|
case 'mysqli':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
|
while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
|
||||||
{
|
{
|
||||||
$db->sql_query($sql);
|
$db->sql_query($sql);
|
||||||
@ -1049,6 +1055,112 @@ class sqlite_extractor extends base_extractor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package acp
|
||||||
|
*/
|
||||||
|
class sqlite3_extractor extends base_extractor
|
||||||
|
{
|
||||||
|
function write_start($prefix)
|
||||||
|
{
|
||||||
|
$sql_data = "--\n";
|
||||||
|
$sql_data .= "-- phpBB Backup Script\n";
|
||||||
|
$sql_data .= "-- Dump of tables for $prefix\n";
|
||||||
|
$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
|
||||||
|
$sql_data .= "--\n";
|
||||||
|
$sql_data .= "BEGIN TRANSACTION;\n";
|
||||||
|
$this->flush($sql_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function write_table($table_name)
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
$sql_data = '-- Table: ' . $table_name . "\n";
|
||||||
|
$sql_data .= "DROP TABLE $table_name;\n";
|
||||||
|
|
||||||
|
$sql = "SELECT sql
|
||||||
|
FROM sqlite_master
|
||||||
|
WHERE type = 'table'
|
||||||
|
AND name = '" . $db->sql_escape($table_name) . "'
|
||||||
|
ORDER BY name ASC;";
|
||||||
|
$result = $db->sql_query($sql);
|
||||||
|
$row = $db->sql_fetchrow($result);
|
||||||
|
$db->sql_freeresult($result);
|
||||||
|
|
||||||
|
// Create Table
|
||||||
|
$sql_data .= $row['sql'] . ";\n";
|
||||||
|
|
||||||
|
$result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
|
||||||
|
|
||||||
|
while ($row = $db->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
if (strpos($row['name'], 'autoindex') !== false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result2 = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($row['name']) . "');");
|
||||||
|
|
||||||
|
$fields = array();
|
||||||
|
while ($row2 = $db->sql_fetchrow($result2))
|
||||||
|
{
|
||||||
|
$fields[] = $row2['name'];
|
||||||
|
}
|
||||||
|
$db->sql_freeresult($result2);
|
||||||
|
|
||||||
|
$sql_data .= 'CREATE ' . ($row['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $row['name'] . ' ON ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
|
||||||
|
}
|
||||||
|
$db->sql_freeresult($result);
|
||||||
|
|
||||||
|
$this->flush($sql_data . "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function write_data($table_name)
|
||||||
|
{
|
||||||
|
global $db;
|
||||||
|
|
||||||
|
$result = $db->sql_query("PRAGMA table_info('" . $db->sql_escape($table_name) . "');");
|
||||||
|
|
||||||
|
$col_types = array();
|
||||||
|
while ($row = $db->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
$col_types[$row['name']] = $row['type'];
|
||||||
|
}
|
||||||
|
$db->sql_freeresult($result);
|
||||||
|
|
||||||
|
$sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
|
||||||
|
|
||||||
|
$sql = "SELECT *
|
||||||
|
FROM $table_name";
|
||||||
|
$result = $db->sql_query($sql);
|
||||||
|
|
||||||
|
while ($row = $db->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
foreach ($row as $column_name => $column_data)
|
||||||
|
{
|
||||||
|
if (is_null($column_data))
|
||||||
|
{
|
||||||
|
$row[$column_name] = 'NULL';
|
||||||
|
}
|
||||||
|
else if ($column_data === '')
|
||||||
|
{
|
||||||
|
$row[$column_name] = "''";
|
||||||
|
}
|
||||||
|
else if (stripos($col_types[$column_name], 'text') !== false || stripos($col_types[$column_name], 'char') !== false || stripos($col_types[$column_name], 'blob') !== false)
|
||||||
|
{
|
||||||
|
$row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->flush($sql_insert . implode(', ', $row) . ");\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function write_end()
|
||||||
|
{
|
||||||
|
$this->flush("COMMIT;\n");
|
||||||
|
parent::write_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package acp
|
* @package acp
|
||||||
*/
|
*/
|
||||||
|
@ -538,6 +538,7 @@ class acp_icons
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$db->sql_query('DELETE FROM ' . $table);
|
$db->sql_query('DELETE FROM ' . $table);
|
||||||
break;
|
break;
|
||||||
|
@ -271,6 +271,7 @@ class acp_main
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
|
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
|
||||||
break;
|
break;
|
||||||
@ -376,6 +377,7 @@ class acp_main
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$db->sql_query("DELETE FROM $table");
|
$db->sql_query("DELETE FROM $table");
|
||||||
break;
|
break;
|
||||||
|
@ -114,6 +114,7 @@ class acp_profile
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
WHERE type = 'table'
|
WHERE type = 'table'
|
||||||
@ -1204,7 +1205,8 @@ class acp_profile
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
case 'sqlite3':
|
||||||
|
if (version_compare($db->sql_server_info(true), '3.0') == -1)
|
||||||
{
|
{
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
|
@ -253,6 +253,7 @@ class acp_reasons
|
|||||||
case 'oracle':
|
case 'oracle':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
// Change the reports using this reason to 'other'
|
// Change the reports using this reason to 'other'
|
||||||
$sql = 'UPDATE ' . REPORTS_TABLE . '
|
$sql = 'UPDATE ' . REPORTS_TABLE . '
|
||||||
SET reason_id = ' . $other_reason_id . ", report_text = '" . $db->sql_escape($reason_row['reason_description']) . "\n\n' || report_text
|
SET reason_id = ' . $other_reason_id . ", report_text = '" . $db->sql_escape($reason_row['reason_description']) . "\n\n' || report_text
|
||||||
|
@ -3989,7 +3989,7 @@ function obtain_guest_count($item_id = 0, $item = 'forum')
|
|||||||
|
|
||||||
// Get number of online guests
|
// Get number of online guests
|
||||||
|
|
||||||
if ($db->sql_layer === 'sqlite')
|
if ($db->sql_layer === 'sqlite' || $db->sql_layer === 'sqlite3')
|
||||||
{
|
{
|
||||||
$sql = 'SELECT COUNT(session_ip) as num_guests
|
$sql = 'SELECT COUNT(session_ip) as num_guests
|
||||||
FROM (
|
FROM (
|
||||||
|
@ -2440,6 +2440,7 @@ function phpbb_cache_moderators($db, $cache, $auth)
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$db->sql_query('DELETE FROM ' . MODERATOR_CACHE_TABLE);
|
$db->sql_query('DELETE FROM ' . MODERATOR_CACHE_TABLE);
|
||||||
break;
|
break;
|
||||||
@ -2907,6 +2908,7 @@ function get_database_size()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
global $dbhost;
|
global $dbhost;
|
||||||
|
|
||||||
if (file_exists($dbhost))
|
if (file_exists($dbhost))
|
||||||
|
@ -1650,6 +1650,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
|
|||||||
|
|
||||||
case 'mssql':
|
case 'mssql':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'mssqlnative':
|
case 'mssqlnative':
|
||||||
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
|
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
|
||||||
break;
|
break;
|
||||||
@ -2037,6 +2038,7 @@ function update_topics_posted()
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
|
$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
|
||||||
break;
|
break;
|
||||||
|
@ -106,6 +106,15 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
|
|||||||
'AVAILABLE' => true,
|
'AVAILABLE' => true,
|
||||||
'2.0.x' => false,
|
'2.0.x' => false,
|
||||||
),
|
),
|
||||||
|
'sqlite3' => array(
|
||||||
|
'LABEL' => 'SQLite3',
|
||||||
|
'SCHEMA' => 'sqlite',
|
||||||
|
'MODULE' => 'sqlite3',
|
||||||
|
'DELIM' => ';',
|
||||||
|
'DRIVER' => 'phpbb\db\driver\sqlite3',
|
||||||
|
'AVAILABLE' => true,
|
||||||
|
'2.0.x' => false,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($dbms)
|
if ($dbms)
|
||||||
@ -206,14 +215,14 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
|
|||||||
$db->sql_return_on_error(true);
|
$db->sql_return_on_error(true);
|
||||||
|
|
||||||
// Check that we actually have a database name before going any further.....
|
// Check that we actually have a database name before going any further.....
|
||||||
if ($dbms_details['DRIVER'] != 'phpbb\db\driver\sqlite' && $dbms_details['DRIVER'] != 'phpbb\db\driver\oracle' && $dbname === '')
|
if ($dbms_details['DRIVER'] != 'phpbb\db\driver\sqlite' && $dbms_details['DRIVER'] != 'phpbb\db\driver\sqlite3' && $dbms_details['DRIVER'] != 'phpbb\db\driver\oracle' && $dbname === '')
|
||||||
{
|
{
|
||||||
$error[] = $lang['INST_ERR_DB_NO_NAME'];
|
$error[] = $lang['INST_ERR_DB_NO_NAME'];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
|
// Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
|
||||||
if ($dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite' && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0)
|
if (($dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite' || $dbms_details['DRIVER'] == 'phpbb\db\driver\sqlite3') && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0)
|
||||||
{
|
{
|
||||||
$error[] = $lang['INST_ERR_DB_FORUM_PATH'];
|
$error[] = $lang['INST_ERR_DB_FORUM_PATH'];
|
||||||
return false;
|
return false;
|
||||||
@ -243,6 +252,7 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'phpbb\db\driver\sqlite':
|
case 'phpbb\db\driver\sqlite':
|
||||||
|
case 'phpbb\db\driver\sqlite3':
|
||||||
$prefix_length = 200;
|
$prefix_length = 200;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -299,6 +309,14 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'phpbb\db\driver\sqlite3':
|
||||||
|
$version = \SQLite3::version();
|
||||||
|
if (version_compare($version['versionString'], '3.6.15', '<'))
|
||||||
|
{
|
||||||
|
$error[] = $lang['INST_ERR_DB_NO_SQLITE3'];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'phpbb\db\driver\firebird':
|
case 'phpbb\db\driver\firebird':
|
||||||
// check the version of FB, use some hackery if we can't get access to the server info
|
// check the version of FB, use some hackery if we can't get access to the server info
|
||||||
if ($db->service_handle !== false && function_exists('ibase_server_info'))
|
if ($db->service_handle !== false && function_exists('ibase_server_info'))
|
||||||
|
@ -1843,6 +1843,7 @@ function phpbb_create_userconv_table()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
|
$create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
|
||||||
user_id INTEGER NOT NULL DEFAULT \'0\',
|
user_id INTEGER NOT NULL DEFAULT \'0\',
|
||||||
username_clean varchar(255) NOT NULL DEFAULT \'\'
|
username_clean varchar(255) NOT NULL DEFAULT \'\'
|
||||||
|
@ -249,6 +249,7 @@ class install_convert extends module
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE);
|
$db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE);
|
||||||
$db->sql_query('DELETE FROM ' . SESSIONS_TABLE);
|
$db->sql_query('DELETE FROM ' . SESSIONS_TABLE);
|
||||||
@ -696,6 +697,7 @@ class install_convert extends module
|
|||||||
switch ($src_db->sql_layer)
|
switch ($src_db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$convert->src_truncate_statement = 'DELETE FROM ';
|
$convert->src_truncate_statement = 'DELETE FROM ';
|
||||||
break;
|
break;
|
||||||
@ -728,6 +730,7 @@ class install_convert extends module
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$convert->truncate_statement = 'DELETE FROM ';
|
$convert->truncate_statement = 'DELETE FROM ';
|
||||||
break;
|
break;
|
||||||
|
@ -151,7 +151,8 @@ $lang = array_merge($lang, array(
|
|||||||
'DLL_MYSQLI' => 'MySQL with MySQLi Extension',
|
'DLL_MYSQLI' => 'MySQL with MySQLi Extension',
|
||||||
'DLL_ORACLE' => 'Oracle',
|
'DLL_ORACLE' => 'Oracle',
|
||||||
'DLL_POSTGRES' => 'PostgreSQL',
|
'DLL_POSTGRES' => 'PostgreSQL',
|
||||||
'DLL_SQLITE' => 'SQLite',
|
'DLL_SQLITE' => 'SQLite 2',
|
||||||
|
'DLL_SQLITE3' => 'SQLite 3',
|
||||||
'DLL_XML' => 'XML support [ Jabber ]',
|
'DLL_XML' => 'XML support [ Jabber ]',
|
||||||
'DLL_ZLIB' => 'zlib compression support [ gz, .tar.gz, .zip ]',
|
'DLL_ZLIB' => 'zlib compression support [ gz, .tar.gz, .zip ]',
|
||||||
'DL_CONFIG' => 'Download config',
|
'DL_CONFIG' => 'Download config',
|
||||||
@ -212,6 +213,7 @@ $lang = array_merge($lang, array(
|
|||||||
<li>MySQL 3.23 or above (MySQLi supported)</li>
|
<li>MySQL 3.23 or above (MySQLi supported)</li>
|
||||||
<li>PostgreSQL 8.3+</li>
|
<li>PostgreSQL 8.3+</li>
|
||||||
<li>SQLite 2.8.2+</li>
|
<li>SQLite 2.8.2+</li>
|
||||||
|
<li>SQLite 3.6.15+</li>
|
||||||
<li>Firebird 2.1+</li>
|
<li>Firebird 2.1+</li>
|
||||||
<li>MS SQL Server 2000 or above (directly or via ODBC)</li>
|
<li>MS SQL Server 2000 or above (directly or via ODBC)</li>
|
||||||
<li>MS SQL Server 2005 or above (native)</li>
|
<li>MS SQL Server 2005 or above (native)</li>
|
||||||
@ -235,6 +237,7 @@ $lang = array_merge($lang, array(
|
|||||||
'INST_ERR_DB_NO_ERROR' => 'No error message given.',
|
'INST_ERR_DB_NO_ERROR' => 'No error message given.',
|
||||||
'INST_ERR_DB_NO_MYSQLI' => 'The version of MySQL installed on this machine is incompatible with the “MySQL with MySQLi Extension” option you have selected. Please try the “MySQL” option instead.',
|
'INST_ERR_DB_NO_MYSQLI' => 'The version of MySQL installed on this machine is incompatible with the “MySQL with MySQLi Extension” option you have selected. Please try the “MySQL” option instead.',
|
||||||
'INST_ERR_DB_NO_SQLITE' => 'The version of the SQLite extension you have installed is too old, it must be upgraded to at least 2.8.2.',
|
'INST_ERR_DB_NO_SQLITE' => 'The version of the SQLite extension you have installed is too old, it must be upgraded to at least 2.8.2.',
|
||||||
|
'INST_ERR_DB_NO_SQLITE3' => 'The version of the SQLite extension you have installed is too old, it must be upgraded to at least 3.6.15.',
|
||||||
'INST_ERR_DB_NO_ORACLE' => 'The version of Oracle installed on this machine requires you to set the <var>NLS_CHARACTERSET</var> parameter to <var>UTF8</var>. Either upgrade your installation to 9.2+ or change the parameter.',
|
'INST_ERR_DB_NO_ORACLE' => 'The version of Oracle installed on this machine requires you to set the <var>NLS_CHARACTERSET</var> parameter to <var>UTF8</var>. Either upgrade your installation to 9.2+ or change the parameter.',
|
||||||
'INST_ERR_DB_NO_FIREBIRD' => 'The version of Firebird installed on this machine is older than 2.1, please upgrade to a newer version.',
|
'INST_ERR_DB_NO_FIREBIRD' => 'The version of Firebird installed on this machine is older than 2.1, please upgrade to a newer version.',
|
||||||
'INST_ERR_DB_NO_FIREBIRD_PS'=> 'The database you selected for Firebird has a page size less than 8192, it must be at least 8192.',
|
'INST_ERR_DB_NO_FIREBIRD_PS'=> 'The database you selected for Firebird has a page size less than 8192, it must be at least 8192.',
|
||||||
|
375
phpBB/phpbb/db/driver/sqlite3.php
Normal file
375
phpBB/phpbb/db/driver/sqlite3.php
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package dbal
|
||||||
|
* @copyright (c) 2014 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace phpbb\db\driver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQLite3 Database Abstraction Layer
|
||||||
|
* Minimum Requirement: 3.6.15+
|
||||||
|
* @package dbal
|
||||||
|
*/
|
||||||
|
class sqlite3 extends \phpbb\db\driver\driver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string Stores errors during connection setup in case the driver is not available
|
||||||
|
*/
|
||||||
|
protected $connect_error = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \SQLite3 The SQLite3 database object to operate against
|
||||||
|
*/
|
||||||
|
protected $dbo = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
|
||||||
|
{
|
||||||
|
$this->persistency = false;
|
||||||
|
$this->user = $sqluser;
|
||||||
|
$this->server = $sqlserver . (($port) ? ':' . $port : '');
|
||||||
|
$this->dbname = $database;
|
||||||
|
|
||||||
|
if (!class_exists('SQLite3', false))
|
||||||
|
{
|
||||||
|
$this->connect_error = 'SQLite3 not found, is the extension installed?';
|
||||||
|
return $this->sql_error('');
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$this->dbo = new \SQLite3($this->server, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
|
||||||
|
$this->db_connect_id = true;
|
||||||
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
|
return array('message' => $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_server_info($raw = false, $use_cache = true)
|
||||||
|
{
|
||||||
|
global $cache;
|
||||||
|
|
||||||
|
if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false)
|
||||||
|
{
|
||||||
|
$version = \SQLite3::version();
|
||||||
|
|
||||||
|
$this->sql_server_version = $version['versionString'];
|
||||||
|
|
||||||
|
if (!empty($cache) && $use_cache)
|
||||||
|
{
|
||||||
|
$cache->put('sqlite_version', $this->sql_server_version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL Transaction
|
||||||
|
*
|
||||||
|
* @param string $status Should be one of the following strings:
|
||||||
|
* begin, commit, rollback
|
||||||
|
* @return bool Success/failure of the transaction query
|
||||||
|
*/
|
||||||
|
protected function _sql_transaction($status = 'begin')
|
||||||
|
{
|
||||||
|
switch ($status)
|
||||||
|
{
|
||||||
|
case 'begin':
|
||||||
|
return $this->dbo->exec('BEGIN IMMEDIATE');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'commit':
|
||||||
|
return $this->dbo->exec('COMMIT');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'rollback':
|
||||||
|
return $this->dbo->exec('ROLLBACK');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_query($query = '', $cache_ttl = 0)
|
||||||
|
{
|
||||||
|
if ($query != '')
|
||||||
|
{
|
||||||
|
global $cache;
|
||||||
|
|
||||||
|
// EXPLAIN only in extra debug mode
|
||||||
|
if (defined('DEBUG'))
|
||||||
|
{
|
||||||
|
$this->sql_report('start', $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->last_query_text = $query;
|
||||||
|
$this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
|
||||||
|
$this->sql_add_num_queries($this->query_result);
|
||||||
|
|
||||||
|
if ($this->query_result === false)
|
||||||
|
{
|
||||||
|
if (($this->query_result = @$this->dbo->query($query)) === false)
|
||||||
|
{
|
||||||
|
$this->sql_error($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined('DEBUG'))
|
||||||
|
{
|
||||||
|
$this->sql_report('stop', $query);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cache && $cache_ttl)
|
||||||
|
{
|
||||||
|
$this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (defined('DEBUG'))
|
||||||
|
{
|
||||||
|
$this->sql_report('fromcache', $query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->query_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build LIMIT query
|
||||||
|
*
|
||||||
|
* @param string $query The SQL query to execute
|
||||||
|
* @param int $total The number of rows to select
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $cache_ttl Either 0 to avoid caching or
|
||||||
|
* the time in seconds which the result shall be kept in cache
|
||||||
|
* @return mixed Buffered, seekable result handle, false on error
|
||||||
|
*/
|
||||||
|
protected function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
|
||||||
|
{
|
||||||
|
$this->query_result = false;
|
||||||
|
|
||||||
|
// if $total is set to 0 we do not want to limit the number of rows
|
||||||
|
if ($total == 0)
|
||||||
|
{
|
||||||
|
$total = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
|
||||||
|
|
||||||
|
return $this->sql_query($query, $cache_ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_affectedrows()
|
||||||
|
{
|
||||||
|
return ($this->db_connect_id) ? $this->dbo->changes() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_fetchrow($query_id = false)
|
||||||
|
{
|
||||||
|
global $cache;
|
||||||
|
|
||||||
|
if ($query_id === false)
|
||||||
|
{
|
||||||
|
$query_id = $this->query_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
|
||||||
|
{
|
||||||
|
return $cache->sql_fetchrow($query_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_object($query_id) ? $query_id->fetchArray(SQLITE3_ASSOC) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_nextid()
|
||||||
|
{
|
||||||
|
return ($this->db_connect_id) ? $this->dbo->lastInsertRowID() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_freeresult($query_id = false)
|
||||||
|
{
|
||||||
|
global $cache;
|
||||||
|
|
||||||
|
if ($query_id === false)
|
||||||
|
{
|
||||||
|
$query_id = $this->query_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
|
||||||
|
{
|
||||||
|
return $cache->sql_freeresult($query_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($query_id)
|
||||||
|
{
|
||||||
|
return @$query_id->finalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function sql_escape($msg)
|
||||||
|
{
|
||||||
|
return \SQLite3::escapeString($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* For SQLite an underscore is a not-known character...
|
||||||
|
*/
|
||||||
|
public function sql_like_expression($expression)
|
||||||
|
{
|
||||||
|
// Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
|
||||||
|
// We only catch * and ? here, not the character map possible on file globbing.
|
||||||
|
$expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
|
||||||
|
|
||||||
|
$expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
|
||||||
|
$expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
|
||||||
|
|
||||||
|
return 'GLOB \'' . $this->sql_escape($expression) . '\'';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return sql error array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function _sql_error()
|
||||||
|
{
|
||||||
|
if (class_exists('SQLite3', false))
|
||||||
|
{
|
||||||
|
$error = array(
|
||||||
|
'message' => $this->dbo->lastErrorMsg(),
|
||||||
|
'code' => $this->dbo->lastErrorCode(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$error = array(
|
||||||
|
'message' => $this->connect_error,
|
||||||
|
'code' => '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build db-specific query data
|
||||||
|
*
|
||||||
|
* @param string $stage Available stages: FROM, WHERE
|
||||||
|
* @param mixed $data A string containing the CROSS JOIN query or an array of WHERE clauses
|
||||||
|
*
|
||||||
|
* @return string The db-specific query fragment
|
||||||
|
*/
|
||||||
|
protected function _sql_custom_build($stage, $data)
|
||||||
|
{
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close sql connection
|
||||||
|
*
|
||||||
|
* @return bool False if failure
|
||||||
|
*/
|
||||||
|
protected function _sql_close()
|
||||||
|
{
|
||||||
|
return $this->dbo->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build db-specific report
|
||||||
|
*
|
||||||
|
* @param string $mode Available modes: display, start, stop,
|
||||||
|
* add_select_row, fromcache, record_fromcache
|
||||||
|
* @param string $query The Query that should be explained
|
||||||
|
* @return mixed Either a full HTML page, boolean or null
|
||||||
|
*/
|
||||||
|
protected function _sql_report($mode, $query = '')
|
||||||
|
{
|
||||||
|
switch ($mode)
|
||||||
|
{
|
||||||
|
case 'start':
|
||||||
|
|
||||||
|
$explain_query = $query;
|
||||||
|
if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
|
||||||
|
{
|
||||||
|
$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
|
||||||
|
}
|
||||||
|
else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m))
|
||||||
|
{
|
||||||
|
$explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/^SELECT/', $explain_query))
|
||||||
|
{
|
||||||
|
$html_table = false;
|
||||||
|
|
||||||
|
if ($result = $this->dbo->query("EXPLAIN QUERY PLAN $explain_query"))
|
||||||
|
{
|
||||||
|
while ($row = $result->fetchArray(SQLITE3_ASSOC))
|
||||||
|
{
|
||||||
|
$html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($html_table)
|
||||||
|
{
|
||||||
|
$this->html_hold .= '</table>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'fromcache':
|
||||||
|
$endtime = explode(' ', microtime());
|
||||||
|
$endtime = $endtime[0] + $endtime[1];
|
||||||
|
|
||||||
|
$result = $this->dbo->query($query);
|
||||||
|
while ($void = $result->fetchArray(SQLITE3_ASSOC))
|
||||||
|
{
|
||||||
|
// Take the time spent on parsing rows into account
|
||||||
|
}
|
||||||
|
|
||||||
|
$splittime = explode(' ', microtime());
|
||||||
|
$splittime = $splittime[0] + $splittime[1];
|
||||||
|
|
||||||
|
$this->sql_report('record_fromcache', $query, $endtime, $splittime);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -257,6 +257,36 @@ class tools
|
|||||||
'VARBINARY' => 'blob',
|
'VARBINARY' => 'blob',
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'sqlite3' => array(
|
||||||
|
'INT:' => 'INT(%d)',
|
||||||
|
'BINT' => 'BIGINT(20)',
|
||||||
|
'UINT' => 'INTEGER UNSIGNED',
|
||||||
|
'UINT:' => 'INTEGER UNSIGNED',
|
||||||
|
'TINT:' => 'TINYINT(%d)',
|
||||||
|
'USINT' => 'INTEGER UNSIGNED',
|
||||||
|
'BOOL' => 'INTEGER 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',
|
||||||
|
),
|
||||||
|
|
||||||
'postgres' => array(
|
'postgres' => array(
|
||||||
'INT:' => 'INT4',
|
'INT:' => 'INT4',
|
||||||
'BINT' => 'INT8',
|
'BINT' => 'INT8',
|
||||||
@ -299,7 +329,7 @@ class tools
|
|||||||
* A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules.
|
* 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 array
|
||||||
*/
|
*/
|
||||||
var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
|
var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
|
* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
|
||||||
@ -389,6 +419,13 @@ class tools
|
|||||||
WHERE type = "table"';
|
WHERE type = "table"';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'sqlite3':
|
||||||
|
$sql = 'SELECT name
|
||||||
|
FROM sqlite_master
|
||||||
|
WHERE type = "table"
|
||||||
|
AND name <> "sqlite_sequence"';
|
||||||
|
break;
|
||||||
|
|
||||||
case 'mssql':
|
case 'mssql':
|
||||||
case 'mssql_odbc':
|
case 'mssql_odbc':
|
||||||
case 'mssqlnative':
|
case 'mssqlnative':
|
||||||
@ -567,6 +604,7 @@ class tools
|
|||||||
case 'mysql_41':
|
case 'mysql_41':
|
||||||
case 'postgres':
|
case 'postgres':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')';
|
$table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -604,6 +642,7 @@ class tools
|
|||||||
|
|
||||||
case 'mysql_40':
|
case 'mysql_40':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$table_sql .= "\n);";
|
$table_sql .= "\n);";
|
||||||
$statements[] = $table_sql;
|
$statements[] = $table_sql;
|
||||||
break;
|
break;
|
||||||
@ -722,7 +761,7 @@ class tools
|
|||||||
$sqlite = false;
|
$sqlite = false;
|
||||||
|
|
||||||
// For SQLite we need to perform the schema changes in a much more different way
|
// For SQLite we need to perform the schema changes in a much more different way
|
||||||
if ($this->db->sql_layer == 'sqlite' && $this->return_statements)
|
if (($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3') && $this->return_statements)
|
||||||
{
|
{
|
||||||
$sqlite_data = array();
|
$sqlite_data = array();
|
||||||
$sqlite = true;
|
$sqlite = true;
|
||||||
@ -1140,6 +1179,7 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql = "SELECT sql
|
$sql = "SELECT sql
|
||||||
FROM sqlite_master
|
FROM sqlite_master
|
||||||
WHERE type = 'table'
|
WHERE type = 'table'
|
||||||
@ -1273,6 +1313,7 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql = "PRAGMA index_list('" . $table_name . "');";
|
$sql = "PRAGMA index_list('" . $table_name . "');";
|
||||||
$col = 'name';
|
$col = 'name';
|
||||||
break;
|
break;
|
||||||
@ -1293,6 +1334,7 @@ class tools
|
|||||||
case 'oracle':
|
case 'oracle':
|
||||||
case 'postgres':
|
case 'postgres':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$row[$col] = substr($row[$col], strlen($table_name) + 1);
|
$row[$col] = substr($row[$col], strlen($table_name) + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1377,6 +1419,7 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql = "PRAGMA index_list('" . $table_name . "');";
|
$sql = "PRAGMA index_list('" . $table_name . "');";
|
||||||
$col = 'name';
|
$col = 'name';
|
||||||
break;
|
break;
|
||||||
@ -1390,7 +1433,7 @@ class tools
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->sql_layer == 'sqlite' && !$row['unique'])
|
if (($this->sql_layer == 'sqlite' || $this->sql_layer == 'sqlite3') && !$row['unique'])
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1418,6 +1461,7 @@ class tools
|
|||||||
case 'firebird':
|
case 'firebird':
|
||||||
case 'postgres':
|
case 'postgres':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$row[$col] = substr($row[$col], strlen($table_name) + 1);
|
$row[$col] = substr($row[$col], strlen($table_name) + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1629,11 +1673,17 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$return_array['primary_key_set'] = false;
|
$return_array['primary_key_set'] = false;
|
||||||
if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
|
if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
|
||||||
{
|
{
|
||||||
$sql .= ' INTEGER PRIMARY KEY';
|
$sql .= ' INTEGER PRIMARY KEY';
|
||||||
$return_array['primary_key_set'] = true;
|
$return_array['primary_key_set'] = true;
|
||||||
|
|
||||||
|
if ($this->sql_layer === 'sqlite3')
|
||||||
|
{
|
||||||
|
$sql .= ' AUTOINCREMENT';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1770,67 +1820,63 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
|
||||||
if ($inline && $this->return_statements)
|
if ($inline && $this->return_statements)
|
||||||
{
|
{
|
||||||
return $column_name . ' ' . $column_data['column_type_sql'];
|
return $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
$recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
|
||||||
|
if (empty($recreate_queries))
|
||||||
{
|
{
|
||||||
$sql = "SELECT sql
|
break;
|
||||||
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);
|
|
||||||
|
|
||||||
$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[] = 'begin';
|
||||||
|
|
||||||
|
$sql_create_table = array_shift($recreate_queries);
|
||||||
|
|
||||||
|
// 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', $sql_create_table);
|
||||||
|
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
|
||||||
|
$statements[] = 'DROP TABLE ' . $table_name;
|
||||||
|
|
||||||
|
preg_match('#\((.*)\)#s', $sql_create_table, $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)
|
||||||
{
|
{
|
||||||
$statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']';
|
$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 = array_merge($statements, $recreate_queries);
|
||||||
|
|
||||||
|
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
||||||
|
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
||||||
|
|
||||||
|
$statements[] = 'commit';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'sqlite3':
|
||||||
|
if ($inline && $this->return_statements)
|
||||||
|
{
|
||||||
|
return $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1908,67 +1954,61 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
|
|
||||||
if ($inline && $this->return_statements)
|
if ($inline && $this->return_statements)
|
||||||
{
|
{
|
||||||
return $column_name;
|
return $column_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version_compare(sqlite_libversion(), '3.0') == -1)
|
$recreate_queries = $this->sqlite_get_recreate_table_queries($table_name, $column_name);
|
||||||
|
if (empty($recreate_queries))
|
||||||
{
|
{
|
||||||
$sql = "SELECT sql
|
break;
|
||||||
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' || $entities[0] === $column_name)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$column_list[] = $entities[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
$columns = implode(',', $column_list);
|
|
||||||
|
|
||||||
$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[] = 'begin';
|
||||||
|
|
||||||
|
$sql_create_table = array_shift($recreate_queries);
|
||||||
|
|
||||||
|
// 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', $sql_create_table);
|
||||||
|
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
|
||||||
|
$statements[] = 'DROP TABLE ' . $table_name;
|
||||||
|
|
||||||
|
preg_match('#\((.*)\)#s', $sql_create_table, $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)
|
||||||
{
|
{
|
||||||
$statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
|
$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 = trim(preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols));
|
||||||
|
if (substr($new_table_cols, -1) === ',')
|
||||||
|
{
|
||||||
|
// Remove the comma from the last entry again
|
||||||
|
$new_table_cols = substr($new_table_cols, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new table and fill it up. destroy the temp one
|
||||||
|
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
|
||||||
|
$statements = array_merge($statements, $recreate_queries);
|
||||||
|
|
||||||
|
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
||||||
|
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
||||||
|
|
||||||
|
$statements[] = 'commit';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1998,6 +2038,7 @@ class tools
|
|||||||
case 'oracle':
|
case 'oracle':
|
||||||
case 'postgres':
|
case 'postgres':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name;
|
$statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2104,35 +2145,29 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
|
|
||||||
if ($inline && $this->return_statements)
|
if ($inline && $this->return_statements)
|
||||||
{
|
{
|
||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = "SELECT sql
|
$recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
|
||||||
FROM sqlite_master
|
if (empty($recreate_queries))
|
||||||
WHERE type = 'table'
|
|
||||||
AND name = '{$table_name}'
|
|
||||||
ORDER BY type DESC, name;";
|
|
||||||
$result = $this->db->sql_query($sql);
|
|
||||||
|
|
||||||
if (!$result)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = $this->db->sql_fetchrow($result);
|
|
||||||
$this->db->sql_freeresult($result);
|
|
||||||
|
|
||||||
$statements[] = 'begin';
|
$statements[] = 'begin';
|
||||||
|
|
||||||
|
$sql_create_table = array_shift($recreate_queries);
|
||||||
|
|
||||||
// Create a backup table and populate it, destroy the existing one
|
// 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[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
|
||||||
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
|
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
|
||||||
$statements[] = 'DROP TABLE ' . $table_name;
|
$statements[] = 'DROP TABLE ' . $table_name;
|
||||||
|
|
||||||
preg_match('#\((.*)\)#s', $row['sql'], $matches);
|
preg_match('#\((.*)\)#s', $sql_create_table, $matches);
|
||||||
|
|
||||||
$new_table_cols = trim($matches[1]);
|
$new_table_cols = trim($matches[1]);
|
||||||
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
|
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
|
||||||
@ -2152,6 +2187,8 @@ class tools
|
|||||||
|
|
||||||
// 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 . ', PRIMARY KEY (' . implode(', ', $column) . '));';
|
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));';
|
||||||
|
$statements = array_merge($statements, $recreate_queries);
|
||||||
|
|
||||||
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
||||||
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
||||||
|
|
||||||
@ -2182,6 +2219,7 @@ class tools
|
|||||||
case 'postgres':
|
case 'postgres':
|
||||||
case 'oracle':
|
case 'oracle':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
|
$statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2225,6 +2263,7 @@ class tools
|
|||||||
case 'postgres':
|
case 'postgres':
|
||||||
case 'oracle':
|
case 'oracle':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
|
$statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2316,6 +2355,7 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql = "PRAGMA index_info('" . $table_name . "');";
|
$sql = "PRAGMA index_info('" . $table_name . "');";
|
||||||
$col = 'name';
|
$col = 'name';
|
||||||
break;
|
break;
|
||||||
@ -2335,6 +2375,7 @@ class tools
|
|||||||
case 'oracle':
|
case 'oracle':
|
||||||
case 'postgres':
|
case 'postgres':
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$row[$col] = substr($row[$col], strlen($table_name) + 1);
|
$row[$col] = substr($row[$col], strlen($table_name) + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2488,35 +2529,29 @@ class tools
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
|
|
||||||
if ($inline && $this->return_statements)
|
if ($inline && $this->return_statements)
|
||||||
{
|
{
|
||||||
return $column_name . ' ' . $column_data['column_type_sql'];
|
return $column_name . ' ' . $column_data['column_type_sql'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = "SELECT sql
|
$recreate_queries = $this->sqlite_get_recreate_table_queries($table_name);
|
||||||
FROM sqlite_master
|
if (empty($recreate_queries))
|
||||||
WHERE type = 'table'
|
|
||||||
AND name = '{$table_name}'
|
|
||||||
ORDER BY type DESC, name;";
|
|
||||||
$result = $this->db->sql_query($sql);
|
|
||||||
|
|
||||||
if (!$result)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$row = $this->db->sql_fetchrow($result);
|
|
||||||
$this->db->sql_freeresult($result);
|
|
||||||
|
|
||||||
$statements[] = 'begin';
|
$statements[] = 'begin';
|
||||||
|
|
||||||
|
$sql_create_table = array_shift($recreate_queries);
|
||||||
|
|
||||||
// Create a temp table and populate it, destroy the existing one
|
// 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[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table);
|
||||||
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
|
$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
|
||||||
$statements[] = 'DROP TABLE ' . $table_name;
|
$statements[] = 'DROP TABLE ' . $table_name;
|
||||||
|
|
||||||
preg_match('#\((.*)\)#s', $row['sql'], $matches);
|
preg_match('#\((.*)\)#s', $sql_create_table, $matches);
|
||||||
|
|
||||||
$new_table_cols = trim($matches[1]);
|
$new_table_cols = trim($matches[1]);
|
||||||
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
|
$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
|
||||||
@ -2534,8 +2569,10 @@ class tools
|
|||||||
|
|
||||||
$columns = implode(',', $column_list);
|
$columns = implode(',', $column_list);
|
||||||
|
|
||||||
// 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 . ' (' . implode(',', $old_table_cols) . ');';
|
$statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');';
|
||||||
|
$statements = array_merge($statements, $recreate_queries);
|
||||||
|
|
||||||
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
|
||||||
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
$statements[] = 'DROP TABLE ' . $table_name . '_temp';
|
||||||
|
|
||||||
@ -2701,4 +2738,75 @@ class tools
|
|||||||
|
|
||||||
return $this->is_sql_server_2000;
|
return $this->is_sql_server_2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Queries which are required to recreate a table including indexes
|
||||||
|
*
|
||||||
|
* @param string $table_name
|
||||||
|
* @param string $remove_column When we drop a column, we remove the column
|
||||||
|
* from all indexes. If the index has no other
|
||||||
|
* column, we drop it completly.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function sqlite_get_recreate_table_queries($table_name, $remove_column = '')
|
||||||
|
{
|
||||||
|
$queries = array();
|
||||||
|
|
||||||
|
$sql = "SELECT sql
|
||||||
|
FROM sqlite_master
|
||||||
|
WHERE type = 'table'
|
||||||
|
AND name = '{$table_name}'";
|
||||||
|
$result = $this->db->sql_query($sql);
|
||||||
|
$sql_create_table = $this->db->sql_fetchfield('sql');
|
||||||
|
$this->db->sql_freeresult($result);
|
||||||
|
|
||||||
|
if (!$sql_create_table)
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
$queries[] = $sql_create_table;
|
||||||
|
|
||||||
|
$sql = "SELECT sql
|
||||||
|
FROM sqlite_master
|
||||||
|
WHERE type = 'index'
|
||||||
|
AND tbl_name = '{$table_name}'";
|
||||||
|
$result = $this->db->sql_query($sql);
|
||||||
|
while ($sql_create_index = $this->db->sql_fetchfield('sql'))
|
||||||
|
{
|
||||||
|
if ($remove_column)
|
||||||
|
{
|
||||||
|
$match = array();
|
||||||
|
preg_match('#(?:[\w ]+)\((.*)\)#', $sql_create_index, $match);
|
||||||
|
if (!isset($match[1]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find and remove $remove_column from the index
|
||||||
|
$columns = explode(', ', $match[1]);
|
||||||
|
$found_column = array_search($remove_column, $columns);
|
||||||
|
if ($found_column !== false)
|
||||||
|
{
|
||||||
|
unset($columns[$found_column]);
|
||||||
|
|
||||||
|
// If the column list is not empty add the index to the list
|
||||||
|
if (!empty($columns))
|
||||||
|
{
|
||||||
|
$queries[] = str_replace($match[1], implode(', ', $columns), $sql_create_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$queries[] = $sql_create_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$queries[] = $sql_create_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->db->sql_freeresult($result);
|
||||||
|
|
||||||
|
return $queries;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,6 +768,7 @@ class fulltext_native extends \phpbb\search\base
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql_array_count['SELECT'] = ($type == 'posts') ? 'DISTINCT p.post_id' : 'DISTINCT p.topic_id';
|
$sql_array_count['SELECT'] = ($type == 'posts') ? 'DISTINCT p.post_id' : 'DISTINCT p.topic_id';
|
||||||
$sql = 'SELECT COUNT(' . (($type == 'posts') ? 'post_id' : 'topic_id') . ') as total_results
|
$sql = 'SELECT COUNT(' . (($type == 'posts') ? 'post_id' : 'topic_id') . ') as total_results
|
||||||
FROM (' . $this->db->sql_build_query('SELECT', $sql_array_count) . ')';
|
FROM (' . $this->db->sql_build_query('SELECT', $sql_array_count) . ')';
|
||||||
@ -997,7 +998,7 @@ class fulltext_native extends \phpbb\search\base
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ($this->db->sql_layer == 'sqlite')
|
if ($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3')
|
||||||
{
|
{
|
||||||
$sql = 'SELECT COUNT(topic_id) as total_results
|
$sql = 'SELECT COUNT(topic_id) as total_results
|
||||||
FROM (SELECT DISTINCT t.topic_id';
|
FROM (SELECT DISTINCT t.topic_id';
|
||||||
@ -1014,7 +1015,7 @@ class fulltext_native extends \phpbb\search\base
|
|||||||
$post_visibility
|
$post_visibility
|
||||||
$sql_fora
|
$sql_fora
|
||||||
AND t.topic_id = p.topic_id
|
AND t.topic_id = p.topic_id
|
||||||
$sql_time" . (($this->db->sql_layer == 'sqlite') ? ')' : '');
|
$sql_time" . (($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3') ? ')' : '');
|
||||||
}
|
}
|
||||||
$result = $this->db->sql_query($sql);
|
$result = $this->db->sql_query($sql);
|
||||||
|
|
||||||
@ -1481,6 +1482,7 @@ class fulltext_native extends \phpbb\search\base
|
|||||||
switch ($this->db->sql_layer)
|
switch ($this->db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
case 'firebird':
|
case 'firebird':
|
||||||
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDLIST_TABLE);
|
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDLIST_TABLE);
|
||||||
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDMATCH_TABLE);
|
$this->db->sql_query('DELETE FROM ' . SEARCH_WORDMATCH_TABLE);
|
||||||
|
@ -101,6 +101,7 @@ if (!$show_guests)
|
|||||||
switch ($db->sql_layer)
|
switch ($db->sql_layer)
|
||||||
{
|
{
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
|
case 'sqlite3':
|
||||||
$sql = 'SELECT COUNT(session_ip) as num_guests
|
$sql = 'SELECT COUNT(session_ip) as num_guests
|
||||||
FROM (
|
FROM (
|
||||||
SELECT DISTINCT session_ip
|
SELECT DISTINCT session_ip
|
||||||
|
@ -53,6 +53,7 @@ class phpbb_database_test_connection_manager
|
|||||||
switch ($this->dbms['PDO'])
|
switch ($this->dbms['PDO'])
|
||||||
{
|
{
|
||||||
case 'sqlite2':
|
case 'sqlite2':
|
||||||
|
case 'sqlite': // SQLite3 driver
|
||||||
$dsn .= $this->config['dbhost'];
|
$dsn .= $this->config['dbhost'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -191,6 +192,7 @@ class phpbb_database_test_connection_manager
|
|||||||
switch ($this->config['dbms'])
|
switch ($this->config['dbms'])
|
||||||
{
|
{
|
||||||
case 'phpbb\db\driver\sqlite':
|
case 'phpbb\db\driver\sqlite':
|
||||||
|
case 'phpbb\db\driver\sqlite3':
|
||||||
case 'phpbb\db\driver\firebird':
|
case 'phpbb\db\driver\firebird':
|
||||||
$this->connect();
|
$this->connect();
|
||||||
// Drop all of the tables
|
// Drop all of the tables
|
||||||
@ -272,6 +274,13 @@ class phpbb_database_test_connection_manager
|
|||||||
WHERE type = "table"';
|
WHERE type = "table"';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'phpbb\db\driver\sqlite3':
|
||||||
|
$sql = 'SELECT name
|
||||||
|
FROM sqlite_master
|
||||||
|
WHERE type = "table"
|
||||||
|
AND name <> "sqlite_sequence"';
|
||||||
|
break;
|
||||||
|
|
||||||
case 'phpbb\db\driver\mssql':
|
case 'phpbb\db\driver\mssql':
|
||||||
case 'phpbb\db\driver\mssql_odbc':
|
case 'phpbb\db\driver\mssql_odbc':
|
||||||
case 'phpbb\db\driver\mssqlnative':
|
case 'phpbb\db\driver\mssqlnative':
|
||||||
@ -436,6 +445,11 @@ class phpbb_database_test_connection_manager
|
|||||||
'DELIM' => ';',
|
'DELIM' => ';',
|
||||||
'PDO' => 'sqlite2',
|
'PDO' => 'sqlite2',
|
||||||
),
|
),
|
||||||
|
'phpbb\db\driver\sqlite3' => array(
|
||||||
|
'SCHEMA' => 'sqlite',
|
||||||
|
'DELIM' => ';',
|
||||||
|
'PDO' => 'sqlite',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isset($available_dbms[$dbms]))
|
if (isset($available_dbms[$dbms]))
|
||||||
@ -623,6 +637,14 @@ class phpbb_database_test_connection_manager
|
|||||||
$queries[] = 'SELECT ' . implode(', ', $setval_queries);
|
$queries[] = 'SELECT ' . implode(', ', $setval_queries);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'phpbb\db\driver\sqlite3':
|
||||||
|
/**
|
||||||
|
* Just delete all of the sequences. When an insertion occurs, the sequence will be automatically
|
||||||
|
* re-created from the key with the AUTOINCREMENT attribute
|
||||||
|
*/
|
||||||
|
$queries[] = 'DELETE FROM sqlite_sequence';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($queries as $query)
|
foreach ($queries as $query)
|
||||||
|
@ -104,7 +104,19 @@ class phpbb_test_case_helpers
|
|||||||
{
|
{
|
||||||
$config = array();
|
$config = array();
|
||||||
|
|
||||||
if (extension_loaded('sqlite') && version_compare(PHPUnit_Runner_Version::id(), '3.4.15', '>='))
|
|
||||||
|
if (extension_loaded('sqlite3'))
|
||||||
|
{
|
||||||
|
$config = array_merge($config, array(
|
||||||
|
'dbms' => 'phpbb\db\driver\sqlite3',
|
||||||
|
'dbhost' => dirname(__FILE__) . '/../phpbb_unit_tests.sqlite3', // filename
|
||||||
|
'dbport' => '',
|
||||||
|
'dbname' => '',
|
||||||
|
'dbuser' => '',
|
||||||
|
'dbpasswd' => '',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else if (extension_loaded('sqlite'))
|
||||||
{
|
{
|
||||||
$config = array_merge($config, array(
|
$config = array_merge($config, array(
|
||||||
'dbms' => 'phpbb\db\driver\sqlite',
|
'dbms' => 'phpbb\db\driver\sqlite',
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
</groups>
|
</groups>
|
||||||
|
|
||||||
<php>
|
<php>
|
||||||
<!-- "Real" test database -->
|
|
||||||
<!-- uncomment, otherwise sqlite memory runs -->
|
|
||||||
<server name="PHPBB_TEST_DBMS" value="phpbb\db\driver\postgres"/>
|
<server name="PHPBB_TEST_DBMS" value="phpbb\db\driver\postgres"/>
|
||||||
<server name="PHPBB_TEST_DBHOST" value="localhost" />
|
<server name="PHPBB_TEST_DBHOST" value="localhost" />
|
||||||
<server name="PHPBB_TEST_DBPORT" value="5432" />
|
<server name="PHPBB_TEST_DBPORT" value="5432" />
|
||||||
|
42
travis/phpunit-sqlite3-travis.xml
Normal file
42
travis/phpunit-sqlite3-travis.xml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit backupGlobals="true"
|
||||||
|
backupStaticAttributes="true"
|
||||||
|
colors="true"
|
||||||
|
convertErrorsToExceptions="true"
|
||||||
|
convertNoticesToExceptions="true"
|
||||||
|
convertWarningsToExceptions="true"
|
||||||
|
processIsolation="false"
|
||||||
|
stopOnFailure="false"
|
||||||
|
syntaxCheck="true"
|
||||||
|
strict="true"
|
||||||
|
verbose="true"
|
||||||
|
bootstrap="../tests/bootstrap.php">
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="phpBB Test Suite">
|
||||||
|
<directory suffix="_test.php">../tests/</directory>
|
||||||
|
<exclude>tests/functional</exclude>
|
||||||
|
<exclude>tests/lint_test.php</exclude>
|
||||||
|
</testsuite>
|
||||||
|
<testsuite name="phpBB Functional Tests">
|
||||||
|
<directory suffix="_test.php" phpVersion="5.3.19" phpVersionOperator=">=">../tests/functional</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<groups>
|
||||||
|
<exclude>
|
||||||
|
<group>slow</group>
|
||||||
|
</exclude>
|
||||||
|
</groups>
|
||||||
|
|
||||||
|
<php>
|
||||||
|
<!--server name="PHPBB_TEST_DBMS" value="phpbb\db\driver\sqlite3" /-->
|
||||||
|
<!--server name="PHPBB_TEST_DBHOST" value="../phpbb_unit_tests.sqlite3" /-->
|
||||||
|
<!--server name="PHPBB_TEST_DBPORT" value="" /-->
|
||||||
|
<!--server name="PHPBB_TEST_DBNAME" value="" /-->
|
||||||
|
<!--server name="PHPBB_TEST_DBUSER" value="" /-->
|
||||||
|
<!--server name="PHPBB_TEST_DBPASSWD" value="" /-->
|
||||||
|
<server name="PHPBB_TEST_REDIS_HOST" value="localhost" />
|
||||||
|
<server name="PHPBB_TEST_TABLE_PREFIX" value="phpbb_"/>
|
||||||
|
<server name="PHPBB_FUNCTIONAL_URL" value="http://localhost/" />
|
||||||
|
</php>
|
||||||
|
</phpunit>
|
Loading…
x
Reference in New Issue
Block a user