Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 7 commits
  • 19 files changed
  • 0 comments
  • 2 contributors
Sep 21, 2011
[feature/sqlite3] Initial import of SQLite 3 database driver.
- Changed name from 'sqlite_3' to 'sqlite3'
- Fixed code formatting for our coding standards
- Added some comments where items need to be addressed
- Resolved a few minor issues

PHPBB3-9728
fe6268a
Chris Smith [feature/sqlite3] Add changes required for SQLite 3 support.
PHPBB3-9728
a7c2888
Chris Smith [feature/sqlite3] Add support for SQLite3 to unit test framework.
PHPBB3-9728
b3f5a96
Chris Smith [feature/sqlite3] Remove uesless extra code.
Not sure what the point of all the extra stuff is but removing it
makes things work properly. 8 unit tests fail currently down from
a lot more with errors.

PHPBB3-9728
21484a1
Chris Smith [feature/sqlite3] Fix condition so it can be true.
PHPBB3-9728
f7722b6
Sep 22, 2011
Chris Smith [feature/sqlite3] Fix sql_affectedrows() method.
PHPBB3-9728
f5c465f
Sep 24, 2011
Chris Smith [feature/sqlite3] Dubious fix to SQLite3 issue.
PHPBB3-9728
e3d51f7
1  phpBB/develop/add_permissions.php
@@ -380,6 +380,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting)
380 380
 
381 381
 					case 'mssql':
382 382
 					case 'sqlite':
  383
+					case 'sqlite3':
383 384
 						$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
384 385
 						break;
385 386
 
1  phpBB/docs/INSTALL.html
@@ -133,6 +133,7 @@
133 133
 			<li>MySQL 3.23 or above (MySQLi supported)</li>
134 134
 			<li>PostgreSQL 7.3+</li>
135 135
 			<li>SQLite 2.8.2+</li>
  136
+			<li>SQLite 3+</li>
136 137
 			<li>Firebird 2.1+</li>
137 138
 			<li>MS SQL Server 2000 or above (directly or via ODBC)</li>
138 139
 			<li>Oracle</li>
7  phpBB/includes/acp/acp_database.php
@@ -99,6 +99,11 @@ function main($id, $mode)
99 99
 								$extractor = new sqlite_extractor($download, $store, $format, $filename, $time);
100 100
 							break;
101 101
 
  102
+							case 'sqlite3':
  103
+								// @todo Syntax is identical, methods are not.
  104
+								throw new Exception('Somebody forgot to fix this hrm');
  105
+							break;
  106
+
102 107
 							case 'postgres':
103 108
 								$extractor = new postgres_extractor($download, $store, $format, $filename, $time);
104 109
 							break;
@@ -133,6 +138,7 @@ function main($id, $mode)
133 138
 								switch ($db->sql_layer)
134 139
 								{
135 140
 									case 'sqlite':
  141
+									case 'sqlite3':
136 142
 									case 'firebird':
137 143
 										$extractor->flush('DELETE FROM ' . $table_name . ";\n");
138 144
 									break;
@@ -325,6 +331,7 @@ function main($id, $mode)
325 331
 								case 'mysql4':
326 332
 								case 'mysqli':
327 333
 								case 'sqlite':
  334
+								case 'sqlite3':
328 335
 									while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
329 336
 									{
330 337
 										$db->sql_query($sql);
1  phpBB/includes/acp/acp_icons.php
@@ -555,6 +555,7 @@ function main($id, $mode)
555 555
 						switch ($db->sql_layer)
556 556
 						{
557 557
 							case 'sqlite':
  558
+							case 'sqlite3':
558 559
 							case 'firebird':
559 560
 								$db->sql_query('DELETE FROM ' . $table);
560 561
 							break;
2  phpBB/includes/acp/acp_main.php
@@ -259,6 +259,7 @@ function main($id, $mode)
259 259
 						switch ($db->sql_layer)
260 260
 						{
261 261
 							case 'sqlite':
  262
+							case 'sqlite3':
262 263
 							case 'firebird':
263 264
 								$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
264 265
 							break;
@@ -359,6 +360,7 @@ function main($id, $mode)
359 360
 							switch ($db->sql_layer)
360 361
 							{
361 362
 								case 'sqlite':
  363
+								case 'sqlite3':
362 364
 								case 'firebird':
363 365
 									$db->sql_query("DELETE FROM $table");
364 366
 								break;
6  phpBB/includes/acp/acp_profile.php
@@ -124,6 +124,7 @@ function main($id, $mode)
124 124
 					switch ($db->sql_layer)
125 125
 					{
126 126
 						case 'sqlite':
  127
+						case 'sqlite3':
127 128
 							$sql = "SELECT sql
128 129
 								FROM sqlite_master
129 130
 								WHERE type = 'table'
@@ -1406,6 +1407,7 @@ function add_field_ident($field_ident, $field_type)
1406 1407
 			break;
1407 1408
 
1408 1409
 			case 'sqlite':
  1410
+			case 'sqlite3':
1409 1411
 
1410 1412
 				switch ($field_type)
1411 1413
 				{
@@ -1437,7 +1439,9 @@ function add_field_ident($field_ident, $field_type)
1437 1439
 				}
1438 1440
 
1439 1441
 				// We are defining the biggest common value, because of the possibility to edit the min/max values of each field.
1440  
-				if (version_compare(sqlite_libversion(), '3.0') == -1)
  1442
+				// SQLite2 always has to do this mess, or SQLite3 <= 3.1.3 per the following:
  1443
+				// "After ADD COLUMN has been run on a database, that database will not be readable by SQLite version 3.1.3 and earlier." -- http://www.sqlite.org/lang_altertable.html
  1444
+				if ($db->sql_layer == 'sqlite' || version_compare($db->sql_server_info(true), '3.1.3', '<='))
1441 1445
 				{
1442 1446
 					$sql = "SELECT sql
1443 1447
 						FROM sqlite_master
1  phpBB/includes/acp/acp_reasons.php
@@ -253,6 +253,7 @@ function main($id, $mode)
253 253
 						case 'oracle':
254 254
 						case 'firebird':
255 255
 						case 'sqlite':
  256
+						case 'sqlite3':
256 257
 							// Change the reports using this reason to 'other'
257 258
 							$sql = 'UPDATE ' . REPORTS_TABLE . '
258 259
 								SET reason_id = ' . $other_reason_id . ", report_text = '" . $db->sql_escape($reason_row['reason_description']) . "\n\n' || report_text
128  phpBB/includes/db/db_tools.php
@@ -250,6 +250,36 @@ class phpbb_db_tools
250 250
 			'VARBINARY'	=> 'blob',
251 251
 		),
252 252
 
  253
+		'sqlite3'	=> array(
  254
+			'INT:'		=> 'int(%d)',
  255
+			'BINT'		=> 'bigint(20)',
  256
+			'UINT'		=> 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED',
  257
+			'UINT:'		=> 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED',
  258
+			'TINT:'		=> 'tinyint(%d)',
  259
+			'USINT'		=> 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED',
  260
+			'BOOL'		=> 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED',
  261
+			'VCHAR'		=> 'varchar(255)',
  262
+			'VCHAR:'	=> 'varchar(%d)',
  263
+			'CHAR:'		=> 'char(%d)',
  264
+			'XSTEXT'	=> 'text(65535)',
  265
+			'STEXT'		=> 'text(65535)',
  266
+			'TEXT'		=> 'text(65535)',
  267
+			'MTEXT'		=> 'mediumtext(16777215)',
  268
+			'XSTEXT_UNI'=> 'text(65535)',
  269
+			'STEXT_UNI'	=> 'text(65535)',
  270
+			'TEXT_UNI'	=> 'text(65535)',
  271
+			'MTEXT_UNI'	=> 'mediumtext(16777215)',
  272
+			'TIMESTAMP'	=> 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
  273
+			'DECIMAL'	=> 'decimal(5,2)',
  274
+			'DECIMAL:'	=> 'decimal(%d,2)',
  275
+			'PDECIMAL'	=> 'decimal(6,3)',
  276
+			'PDECIMAL:'	=> 'decimal(%d,3)',
  277
+			'VCHAR_UNI'	=> 'varchar(255)',
  278
+			'VCHAR_UNI:'=> 'varchar(%d)',
  279
+			'VCHAR_CI'	=> 'varchar(255)',
  280
+			'VARBINARY'	=> 'blob',
  281
+		),
  282
+
253 283
 		'postgres'	=> array(
254 284
 			'INT:'		=> 'INT4',
255 285
 			'BINT'		=> 'INT8',
@@ -291,7 +321,7 @@ class phpbb_db_tools
291 321
 	* A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules.
292 322
 	* @var array
293 323
 	*/
294  
-	var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
  324
+	var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3');
295 325
 
296 326
 	/**
297 327
 	* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
@@ -490,6 +520,7 @@ function sql_create_table($table_name, $table_data)
490 520
 					case 'mysql_41':
491 521
 					case 'postgres':
492 522
 					case 'sqlite':
  523
+					case 'sqlite3':
493 524
 						$table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')';
494 525
 					break;
495 526
 
@@ -527,6 +558,7 @@ function sql_create_table($table_name, $table_data)
527 558
 
528 559
 			case 'mysql_40':
529 560
 			case 'sqlite':
  561
+			case 'sqlite3':
530 562
 				$table_sql .= "\n);";
531 563
 				$statements[] = $table_sql;
532 564
 			break;
@@ -643,7 +675,7 @@ function perform_schema_changes($schema_changes)
643 675
 		$sqlite = false;
644 676
 
645 677
 		// For SQLite we need to perform the schema changes in a much more different way
646  
-		if ($this->db->sql_layer == 'sqlite' && $this->return_statements)
  678
+		if (strpos($this->db->sql_layer, 'sqlite') === 0 && $this->return_statements)
647 679
 		{
648 680
 			$sqlite_data = array();
649 681
 			$sqlite = true;
@@ -1124,6 +1156,7 @@ function sql_column_exists($table, $column_name)
1124 1156
 
1125 1157
 			// ugh, SQLite
1126 1158
 			case 'sqlite':
  1159
+			case 'sqlite3':
1127 1160
 				$sql = "SELECT sql
1128 1161
 					FROM sqlite_master
1129 1162
 					WHERE type = 'table'
@@ -1632,6 +1665,7 @@ function sql_prepare_column_data($table_name, $column_name, $column_data)
1632 1665
 			break;
1633 1666
 
1634 1667
 			case 'sqlite':
  1668
+			case 'sqlite3':
1635 1669
 				$return_array['primary_key_set'] = false;
1636 1670
 				if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
1637 1671
 				{
@@ -1714,13 +1748,16 @@ function sql_column_add($table_name, $column_name, $column_data, $inline = false
1714 1748
 			break;
1715 1749
 
1716 1750
 			case 'sqlite':
  1751
+			case 'sqlite3':
1717 1752
 
1718 1753
 				if ($inline && $this->return_statements)
1719 1754
 				{
1720 1755
 					return $column_name . ' ' . $column_data['column_type_sql'];
1721 1756
 				}
1722 1757
 
1723  
-				if (version_compare(sqlite_libversion(), '3.0') == -1)
  1758
+				// SQLite2 always has to do this mess, or SQLite3 <= 3.1.3 per the following:
  1759
+				// "After ADD COLUMN has been run on a database, that database will not be readable by SQLite version 3.1.3 and earlier." -- http://www.sqlite.org/lang_altertable.html
  1760
+				if ($db->sql_layer == 'sqlite' || version_compare($db->sql_server_info(true), '3.1.3', '<='))
1724 1761
 				{
1725 1762
 					$sql = "SELECT sql
1726 1763
 						FROM sqlite_master
@@ -1813,67 +1850,61 @@ function sql_column_remove($table_name, $column_name, $inline = false)
1813 1850
 			break;
1814 1851
 
1815 1852
 			case 'sqlite':
  1853
+			case 'sqlite3':
1816 1854
 
1817 1855
 				if ($inline && $this->return_statements)
1818 1856
 				{
1819 1857
 					return $column_name;
1820 1858
 				}
1821 1859
 
1822  
-				if (version_compare(sqlite_libversion(), '3.0') == -1)
1823  
-				{
1824  
-					$sql = "SELECT sql
1825  
-						FROM sqlite_master
1826  
-						WHERE type = 'table'
1827  
-							AND name = '{$table_name}'
1828  
-						ORDER BY type DESC, name;";
1829  
-					$result = $this->db->sql_query($sql);
  1860
+				$sql = "SELECT sql
  1861
+					FROM sqlite_master
  1862
+					WHERE type = 'table'
  1863
+						AND name = '{$table_name}'
  1864
+					ORDER BY type DESC, name;";
  1865
+				$result = $this->db->sql_query($sql);
1830 1866
 
1831  
-					if (!$result)
1832  
-					{
1833  
-						break;
1834  
-					}
  1867
+				if (!$result)
  1868
+				{
  1869
+					break;
  1870
+				}
1835 1871
 
1836  
-					$row = $this->db->sql_fetchrow($result);
1837  
-					$this->db->sql_freeresult($result);
  1872
+				$row = $this->db->sql_fetchrow($result);
  1873
+				$this->db->sql_freeresult($result);
1838 1874
 
1839  
-					$statements[] = 'begin';
  1875
+				$statements[] = 'begin';
1840 1876
 
1841  
-					// Create a backup table and populate it, destroy the existing one
1842  
-					$statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
1843  
-					$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
1844  
-					$statements[] = 'DROP TABLE ' . $table_name;
  1877
+				// Create a backup table and populate it, destroy the existing one
  1878
+				$statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']);
  1879
+				$statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name;
  1880
+				$statements[] = 'DROP TABLE ' . $table_name;
1845 1881
 
1846  
-					preg_match('#\((.*)\)#s', $row['sql'], $matches);
  1882
+				preg_match('#\((.*)\)#s', $row['sql'], $matches);
1847 1883
 
1848  
-					$new_table_cols = trim($matches[1]);
1849  
-					$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
1850  
-					$column_list = array();
  1884
+				$new_table_cols = trim($matches[1]);
  1885
+				$old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
  1886
+				$column_list = array();
1851 1887
 
1852  
-					foreach ($old_table_cols as $declaration)
  1888
+				foreach ($old_table_cols as $declaration)
  1889
+				{
  1890
+					$entities = preg_split('#\s+#', trim($declaration));
  1891
+					if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
1853 1892
 					{
1854  
-						$entities = preg_split('#\s+#', trim($declaration));
1855  
-						if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name)
1856  
-						{
1857  
-							continue;
1858  
-						}
1859  
-						$column_list[] = $entities[0];
  1893
+						continue;
1860 1894
 					}
  1895
+					$column_list[] = $entities[0];
  1896
+				}
1861 1897
 
1862  
-					$columns = implode(',', $column_list);
  1898
+				$columns = implode(',', $column_list);
1863 1899
 
1864  
-					$new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
  1900
+				$new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
1865 1901
 
1866  
-					// create a new table and fill it up. destroy the temp one
1867  
-					$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
1868  
-					$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
1869  
-					$statements[] = 'DROP TABLE ' . $table_name . '_temp';
  1902
+				// create a new table and fill it up. destroy the temp one
  1903
+				$statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');';
  1904
+				$statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;';
  1905
+				$statements[] = 'DROP TABLE ' . $table_name . '_temp';
1870 1906
 
1871  
-					$statements[] = 'commit';
1872  
-				}
1873  
-				else
1874  
-				{
1875  
-					$statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
1876  
-				}
  1907
+				$statements[] = 'commit';
1877 1908
 			break;
1878 1909
 		}
1879 1910
 
@@ -1903,6 +1934,7 @@ function sql_index_drop($table_name, $index_name)
1903 1934
 			case 'oracle':
1904 1935
 			case 'postgres':
1905 1936
 			case 'sqlite':
  1937
+			case 'sqlite3':
1906 1938
 				$statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name;
1907 1939
 			break;
1908 1940
 		}
@@ -2009,6 +2041,7 @@ function sql_create_primary_key($table_name, $column, $inline = false)
2009 2041
 			break;
2010 2042
 
2011 2043
 			case 'sqlite':
  2044
+			case 'sqlite3':
2012 2045
 
2013 2046
 				if ($inline && $this->return_statements)
2014 2047
 				{
@@ -2087,6 +2120,7 @@ function sql_create_unique_index($table_name, $index_name, $column)
2087 2120
 			case 'postgres':
2088 2121
 			case 'oracle':
2089 2122
 			case 'sqlite':
  2123
+			case 'sqlite3':
2090 2124
 				$statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
2091 2125
 			break;
2092 2126
 
@@ -2130,6 +2164,7 @@ function sql_create_index($table_name, $index_name, $column)
2130 2164
 			case 'postgres':
2131 2165
 			case 'oracle':
2132 2166
 			case 'sqlite':
  2167
+			case 'sqlite3':
2133 2168
 				$statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
2134 2169
 			break;
2135 2170
 
@@ -2221,6 +2256,7 @@ function sql_list_index($table_name)
2221 2256
 				break;
2222 2257
 
2223 2258
 				case 'sqlite':
  2259
+				case 'sqlite3':
2224 2260
 					$sql = "PRAGMA index_info('" . $table_name . "');";
2225 2261
 					$col = 'name';
2226 2262
 				break;
@@ -2240,6 +2276,7 @@ function sql_list_index($table_name)
2240 2276
 					case 'oracle':
2241 2277
 					case 'postgres':
2242 2278
 					case 'sqlite':
  2279
+					case 'sqlite3':
2243 2280
 						$row[$col] = substr($row[$col], strlen($table_name) + 1);
2244 2281
 					break;
2245 2282
 				}
@@ -2375,6 +2412,7 @@ function sql_column_change($table_name, $column_name, $column_data, $inline = fa
2375 2412
 			break;
2376 2413
 
2377 2414
 			case 'sqlite':
  2415
+			case 'sqlite3':
2378 2416
 
2379 2417
 				if ($inline && $this->return_statements)
2380 2418
 				{
373  phpBB/includes/db/sqlite3.php
... ...
@@ -0,0 +1,373 @@
  1
+<?php
  2
+/**
  3
+*
  4
+* @package dbal
  5
+* @copyright (c) 2005, 2011 phpBB Group
  6
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
  7
+*
  8
+*/
  9
+
  10
+/**
  11
+* @ignore
  12
+*/
  13
+if (!defined('IN_PHPBB'))
  14
+{
  15
+	exit;
  16
+}
  17
+
  18
+include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx);
  19
+
  20
+/**
  21
+* SQLite3 database abstraction layer
  22
+*
  23
+* This file is largely based upon
  24
+* <http://www.phpbb.com/community/viewtopic.php?f=70&t=1059695>
  25
+*
  26
+* @package dbal
  27
+* @author Boris Berdichevski <borisba@borisba.com>
  28
+*/
  29
+class dbal_sqlite3 extends dbal
  30
+{
  31
+	var $db;
  32
+
  33
+	/**
  34
+	* Connect to server
  35
+	*/
  36
+	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
  37
+	{
  38
+		$this->server		= $sqlserver;
  39
+		$this->persistency	= $persistency;
  40
+
  41
+		try
  42
+		{
  43
+			$this->db = new SQLite3($this->server);
  44
+			$this->db->exec('PRAGMA short_column_names = 1');
  45
+		}
  46
+		catch (Exception $error)
  47
+		{
  48
+			return array(
  49
+				'code'		=> $error->getCode(),
  50
+				'message' => $error->getMessage(),
  51
+			);
  52
+		}
  53
+
  54
+		return true;
  55
+	}
  56
+
  57
+	/**
  58
+	* Version information about used database
  59
+	*
  60
+	* @param bool $raw if true, only return the fetched sql_server_version
  61
+	* @param bool $use_cache if true, it is safe to retrieve the stored value from the cache
  62
+	* @return string sql server version
  63
+	*/
  64
+	function sql_server_info($raw = false, $use_cache = true)
  65
+	{
  66
+		global $cache;
  67
+
  68
+		if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite3_version')) === false)
  69
+		{
  70
+			$vers = SQLite3::version();
  71
+
  72
+			$this->sql_server_version = $vers['versionString'];
  73
+
  74
+			if (!empty($cache) && $use_cache)
  75
+			{
  76
+				$cache->put('sqlite3_version', $this->sql_server_version);
  77
+			}
  78
+		}
  79
+
  80
+		return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version;
  81
+	}
  82
+
  83
+	/**
  84
+	* SQL Transaction
  85
+	*/
  86
+	function _sql_transaction($status = 'begin')
  87
+	{
  88
+		switch ($status)
  89
+		{
  90
+			case 'begin':
  91
+				return $this->db->query('BEGIN');
  92
+			break;
  93
+
  94
+			case 'commit':
  95
+				return $this->db->query('COMMIT');
  96
+			break;
  97
+
  98
+			case 'rollback':
  99
+				return $this->db->query('ROLLBACK');
  100
+			break;
  101
+		}
  102
+
  103
+		return true;
  104
+	}
  105
+
  106
+	/**
  107
+	* Base query method
  108
+	*
  109
+	* @param	string	$query		Contains the SQL query which shall be executed
  110
+	* @param	int		$cache_ttl	Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
  111
+	* @return	mixed				When casted to bool the returned value returns true on success and false on failure
  112
+	*
  113
+	*/
  114
+	function sql_query($query = '', $cache_ttl = 0)
  115
+	{
  116
+		global $cache;
  117
+
  118
+		if ($query != '')
  119
+		{
  120
+			// EXPLAIN only in extra debug mode
  121
+			if (defined('DEBUG_EXTRA'))
  122
+			{
  123
+				$this->sql_report('start', $query);
  124
+			}
  125
+
  126
+			$this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
  127
+
  128
+			$this->sql_add_num_queries($this->query_result);
  129
+
  130
+			if ($this->query_result === false)
  131
+			{
  132
+				$this->query_result = @$this->db->query($query);
  133
+
  134
+				if ($this->query_result === false)
  135
+				{
  136
+					$this->sql_error($query);
  137
+				}
  138
+
  139
+				if (defined('DEBUG_EXTRA'))
  140
+				{
  141
+					$this->sql_report('stop', $query);
  142
+				}
  143
+
  144
+				if ($cache_ttl && method_exists($cache, 'sql_save'))
  145
+				{
  146
+					$this->open_queries[(int) $this->query_result] = $this->query_result;
  147
+
  148
+					$cache->sql_save($query, $this->query_result, $cache_ttl);
  149
+				}
  150
+				else if (is_object($this->query_result))
  151
+				{
  152
+					$this->open_queries[spl_object_hash($this->query_result)] = $this->query_result;
  153
+				}
  154
+			}
  155
+			else if (defined('DEBUG_EXTRA'))
  156
+			{
  157
+				$this->sql_report('fromcache', $query);
  158
+			}
  159
+		}
  160
+		else
  161
+		{
  162
+			return false;
  163
+		}
  164
+
  165
+		return ($this->query_result) ? $this->query_result : false;
  166
+	}
  167
+
  168
+	/**
  169
+	* Build LIMIT query
  170
+	*/
  171
+	function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
  172
+	{
  173
+		$this->query_result = false;
  174
+
  175
+		// if $total is set to 0 we do not want to limit the number of rows
  176
+		if ($total == 0)
  177
+		{
  178
+			$total = -1;
  179
+		}
  180
+
  181
+		$query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
  182
+
  183
+		return $this->sql_query($query, $cache_ttl);
  184
+	}
  185
+
  186
+	/**
  187
+	* Return number of affected rows
  188
+	*/
  189
+	function sql_affectedrows()
  190
+	{
  191
+		return ($this->db instanceof SQLite3) ? $this->db->changes() : false;
  192
+	}
  193
+
  194
+	/**
  195
+	* Fetch current row
  196
+	*/
  197
+	function sql_fetchrow($query_id = false)
  198
+	{
  199
+		global $cache;
  200
+
  201
+		if ($query_id === false)
  202
+		{
  203
+			$query_id = $this->query_result;
  204
+		}
  205
+
  206
+		if (!is_object($query_id) && isset($cache->sql_rowset[$query_id]))
  207
+		{
  208
+			return $cache->sql_fetchrow($query_id);
  209
+		}
  210
+
  211
+		if (!is_object($query_id))
  212
+		{
  213
+			return false;
  214
+		}
  215
+
  216
+		return $query_id->fetchArray(SQLITE3_ASSOC);
  217
+	}
  218
+
  219
+	/**
  220
+	* Seek to given row number
  221
+	* rownum is zero-based
  222
+	*/
  223
+	function sql_rowseek($rownum, &$query_id)
  224
+	{
  225
+		global $cache;
  226
+
  227
+		if ($query_id === false)
  228
+		{
  229
+			$query_id = $this->query_result;
  230
+		}
  231
+
  232
+		if (!is_object($query_id) && isset($cache->sql_rowset[$query_id]))
  233
+		{
  234
+			return $cache->sql_rowseek($rownum, $query_id);
  235
+		}
  236
+
  237
+		// @todo Implement seeking the hard way.
  238
+		throw new BadMethodCallException('sqlite3 does not support row seeking.');
  239
+	}
  240
+
  241
+	/**
  242
+	* Get last inserted id after insert statement
  243
+	*/
  244
+	function sql_nextid()
  245
+	{
  246
+		return $this->db->lastInsertRowID();
  247
+	}
  248
+
  249
+	/**
  250
+	* Free sql result
  251
+	*/
  252
+	function sql_freeresult($query_id = false)
  253
+	{
  254
+		global $cache;
  255
+
  256
+		if ($query_id === false)
  257
+		{
  258
+			$query_id = $this->query_result;
  259
+		 }
  260
+
  261
+		if (isset($cache->sql_rowset[$query_id]))
  262
+		{
  263
+			return $cache->sql_freeresult($query_id);
  264
+		}
  265
+
  266
+		if (is_object($query_id) && isset($this->open_queries[spl_object_hash($query_id)]))
  267
+		{
  268
+			unset($this->open_queries[spl_object_hash($query_id)]);
  269
+			$query_id->finalize();
  270
+		}
  271
+
  272
+		return true;
  273
+	}
  274
+
  275
+	function _sql_validate_value($var)
  276
+	{
  277
+		if (is_string($var) && strpos($var, "\x00") !== false)
  278
+		{
  279
+			$var = current(unpack('H*', $var));
  280
+
  281
+			$var = SQLite3::escapeString($var);
  282
+
  283
+			return "x'$var'";
  284
+		}
  285
+		else
  286
+		{
  287
+			return parent::_sql_validate_value($var);
  288
+		}
  289
+	}
  290
+
  291
+	/**
  292
+	* Escape string used in sql query
  293
+	*/
  294
+	function sql_escape($msg)
  295
+	{
  296
+		return SQLite3::escapeString($msg);
  297
+	}
  298
+
  299
+	/**
  300
+	* Correctly adjust LIKE expression for special characters
  301
+	* For SQLite an underscore is a not-known character... this may change with SQLite3
  302
+	*
  303
+	* @todo Does this still stand for SQLite3?
  304
+	*/
  305
+	function sql_like_expression($expression)
  306
+	{
  307
+		// Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
  308
+		// We only catch * and ? here, not the character map possible on file globbing.
  309
+		$expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
  310
+
  311
+		$expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
  312
+		$expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
  313
+
  314
+		return 'GLOB \'' . $this->sql_escape($expression) . '\'';
  315
+	}
  316
+
  317
+	/**
  318
+	* return sql error array
  319
+	*/
  320
+	function _sql_error()
  321
+	{
  322
+		return array(
  323
+			'message'	=> $this->db->lastErrorMsg(),
  324
+			'code'		=> $this->db->lastErrorCode()
  325
+		);
  326
+	}
  327
+
  328
+	/**
  329
+	* Build db-specific query data
  330
+	*/
  331
+	function _sql_custom_build($stage, $data)
  332
+	{
  333
+		return $data;
  334
+	}
  335
+
  336
+	/**
  337
+	* Close sql connection
  338
+	*/
  339
+	function _sql_close()
  340
+	{
  341
+		return $this->db->close();
  342
+	}
  343
+
  344
+	/**
  345
+	* Build db-specific report
  346
+	*/
  347
+	function _sql_report($mode, $query = '')
  348
+	{
  349
+		switch ($mode)
  350
+		{
  351
+			case 'start':
  352
+			break;
  353
+
  354
+			case 'fromcache':
  355
+				$endtime = microtime(true);
  356
+
  357
+				$results = $this->db->query( $query);
  358
+
  359
+				while ($result= $results->fetchArray(SQLITE3_ASSOC))
  360
+				{
  361
+					// Take the time spent on parsing rows into account
  362
+				}
  363
+
  364
+				$splittime = explode(' ', microtime());
  365
+				$splittime = $splittime[0] + $splittime[1];
  366
+
  367
+				$this->sql_report('record_fromcache', $query, $endtime, $splittime);
  368
+
  369
+				$results->finalize();
  370
+			break;
  371
+		}
  372
+	}
  373
+}
2  phpBB/includes/functions.php
@@ -3966,7 +3966,7 @@ function obtain_guest_count($item_id = 0, $item = 'forum')
3966 3966
 
3967 3967
 	// Get number of online guests
3968 3968
 
3969  
-	if ($db->sql_layer === 'sqlite')
  3969
+	if ($db->sql_layer === 'sqlite' || $db->sql_layer === 'sqlite3')
3970 3970
 	{
3971 3971
 		$sql = 'SELECT COUNT(session_ip) as num_guests
3972 3972
 			FROM (
2  phpBB/includes/functions_admin.php
@@ -2344,6 +2344,7 @@ function cache_moderators()
2344 2344
 	switch ($db->sql_layer)
2345 2345
 	{
2346 2346
 		case 'sqlite':
  2347
+		case 'sqlite3':
2347 2348
 		case 'firebird':
2348 2349
 			$db->sql_query('DELETE FROM ' . MODERATOR_CACHE_TABLE);
2349 2350
 		break;
@@ -3041,6 +3042,7 @@ function get_database_size()
3041 3042
 		break;
3042 3043
 
3043 3044
 		case 'sqlite':
  3045
+		case 'sqlite3':
3044 3046
 			global $dbhost;
3045 3047
 
3046 3048
 			if (file_exists($dbhost))
2  phpBB/includes/functions_convert.php
@@ -1648,6 +1648,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
1648 1648
 
1649 1649
 					case 'mssql':
1650 1650
 					case 'sqlite':
  1651
+					case 'sqlite3':
1651 1652
 					case 'mssqlnative':
1652 1653
 						$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
1653 1654
 					break;
@@ -2003,6 +2004,7 @@ function update_topics_posted()
2003 2004
 	switch ($db->sql_layer)
2004 2005
 	{
2005 2006
 		case 'sqlite':
  2007
+		case 'sqlite3':
2006 2008
 		case 'firebird':
2007 2009
 			$db->sql_query('DELETE FROM ' . TOPICS_POSTED_TABLE);
2008 2010
 		break;
18  phpBB/includes/functions_install.php
@@ -135,6 +135,16 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
135 135
 			'AVAILABLE'		=> true,
136 136
 			'2.0.x'			=> false,
137 137
 		),
  138
+		'sqlite3'		=> array(
  139
+			'LABEL'			=> 'SQLite3',
  140
+			'SCHEMA'		=> 'sqlite',
  141
+			'MODULE'		=> 'sqlite3',
  142
+			'DELIM'			=> ';',
  143
+			'COMMENTS'		=> 'remove_remarks',
  144
+			'DRIVER'		=> 'sqlite3',
  145
+			'AVAILABLE'		=> true,
  146
+			'2.0.x'			=> false,
  147
+		),
138 148
 	);
139 149
 
140 150
 	if ($dbms)
@@ -223,6 +233,7 @@ function get_tables($db)
223 233
 		break;
224 234
 
225 235
 		case 'sqlite':
  236
+		case 'sqlite3':
226 237
 			$sql = 'SELECT name
227 238
 				FROM sqlite_master
228 239
 				WHERE type = "table"';
@@ -292,14 +303,14 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
292 303
 	$db->sql_return_on_error(true);
293 304
 
294 305
 	// Check that we actually have a database name before going any further.....
295  
-	if ($dbms_details['DRIVER'] != 'sqlite' && $dbms_details['DRIVER'] != 'oracle' && $dbname === '')
  306
+	if ($dbms_details['DRIVER'] != 'sqlite' && $dbms_details['DRIVER'] != 'sqlite3' && $dbms_details['DRIVER'] != 'oracle' && $dbname === '')
296 307
 	{
297 308
 		$error[] = $lang['INST_ERR_DB_NO_NAME'];
298 309
 		return false;
299 310
 	}
300 311
 
301 312
 	// Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
302  
-	if ($dbms_details['DRIVER'] == 'sqlite' && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0)
  313
+	if (strpos($dbms_details['DRIVER'], 'sqlite') === 0 && stripos(phpbb_realpath($dbhost), phpbb_realpath('../')) === 0)
303 314
 	{
304 315
 		$error[] = $lang['INST_ERR_DB_FORUM_PATH'];
305 316
 		return false;
@@ -329,6 +340,7 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
329 340
 		break;
330 341
 
331 342
 		case 'sqlite':
  343
+		case 'sqlite3':
332 344
 			$prefix_length = 200;
333 345
 		break;
334 346
 
@@ -385,6 +397,8 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
385 397
 				}
386 398
 			break;
387 399
 
  400
+			// @todo Do we need something here for sqlite3?
  401
+
388 402
 			case 'firebird':
389 403
 				// check the version of FB, use some hackery if we can't get access to the server info
390 404
 				if ($db->service_handle !== false && function_exists('ibase_server_info'))
1  phpBB/includes/functions_profile_fields.php
@@ -376,6 +376,7 @@ function update_profile_field_data($user_id, &$cp_data)
376 376
 			break;
377 377
 
378 378
 			case 'sqlite':
  379
+			case 'sqlite3':
379 380
 			case 'mssql':
380 381
 			case 'mssql_odbc':
381 382
 			case 'mssqlnative':
1  phpBB/install/convertors/functions_phpbb20.php
@@ -1785,6 +1785,7 @@ function phpbb_create_userconv_table()
1785 1785
 		break;
1786 1786
 
1787 1787
 		case 'sqlite':
  1788
+		case 'sqlite3':
1788 1789
 			$create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' (
1789 1790
 				user_id INTEGER NOT NULL DEFAULT \'0\',
1790 1791
 				username_clean varchar(255) NOT NULL DEFAULT \'\'
3  phpBB/install/install_convert.php
@@ -234,6 +234,7 @@ function main($mode, $sub)
234 234
 				switch ($db->sql_layer)
235 235
 				{
236 236
 					case 'sqlite':
  237
+					case 'sqlite3':
237 238
 					case 'firebird':
238 239
 						$db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE);
239 240
 						$db->sql_query('DELETE FROM ' . SESSIONS_TABLE);
@@ -659,6 +660,7 @@ function convert_data($sub)
659 660
 		switch ($src_db->sql_layer)
660 661
 		{
661 662
 			case 'sqlite':
  663
+			case 'sqlite3':
662 664
 			case 'firebird':
663 665
 				$convert->src_truncate_statement = 'DELETE FROM ';
664 666
 			break;
@@ -691,6 +693,7 @@ function convert_data($sub)
691 693
 		switch ($db->sql_layer)
692 694
 		{
693 695
 			case 'sqlite':
  696
+			case 'sqlite3':
694 697
 			case 'firebird':
695 698
 				$convert->truncate_statement = 'DELETE FROM ';
696 699
 			break;
2  phpBB/language/en/install.php
@@ -153,6 +153,7 @@
153 153
 	'DLL_ORACLE'				=> 'Oracle',
154 154
 	'DLL_POSTGRES'				=> 'PostgreSQL 7.x/8.x',
155 155
 	'DLL_SQLITE'				=> 'SQLite',
  156
+	'DLL_SQLITE3'				=> 'SQLite 3',
156 157
 	'DLL_XML'					=> 'XML support [ Jabber ]',
157 158
 	'DLL_ZLIB'					=> 'zlib compression support [ gz, .tar.gz, .zip ]',
158 159
 	'DL_CONFIG'					=> 'Download config',
@@ -213,6 +214,7 @@
213 214
 		<li>MySQL 3.23 or above (MySQLi supported)</li>
214 215
 		<li>PostgreSQL 7.3+</li>
215 216
 		<li>SQLite 2.8.2+</li>
  217
+		<li>SQLite 3+</li>
216 218
 		<li>Firebird 2.1+</li>
217 219
 		<li>MS SQL Server 2000 or above (directly or via ODBC)</li>
218 220
 		<li>MS SQL Server 2005 or above (native)</li>
1  phpBB/viewonline.php
@@ -100,6 +100,7 @@
100 100
 	switch ($db->sql_layer)
101 101
 	{
102 102
 		case 'sqlite':
  103
+		case 'sqlite3':
103 104
 			$sql = 'SELECT COUNT(session_ip) as num_guests
104 105
 				FROM (
105 106
 					SELECT DISTINCT session_ip
10  tests/test_framework/phpbb_database_test_connection_manager.php
@@ -47,6 +47,7 @@ public function connect($use_db = true)
47 47
 		switch ($this->dbms['PDO'])
48 48
 		{
49 49
 			case 'sqlite2':
  50
+			case 'sqlite':
50 51
 				$dsn .= $this->config['dbhost'];
51 52
 			break;
52 53
 
@@ -112,6 +113,7 @@ public function recreate_db()
112 113
 		switch ($this->config['dbms'])
113 114
 		{
114 115
 			case 'sqlite':
  116
+			case 'sqlite3':
115 117
 				if (file_exists($this->config['dbhost']))
116 118
 				{
117 119
 					unlink($this->config['dbhost']);
@@ -157,6 +159,7 @@ public function get_tables()
157 159
 			break;
158 160
 
159 161
 			case 'sqlite':
  162
+			case 'sqlite3':
160 163
 				$sql = 'SELECT name
161 164
 					FROM sqlite_master
162 165
 					WHERE type = "table"';
@@ -266,7 +269,7 @@ protected function split_sql($sql)
266 269
 			unset($data[key($data)]);
267 270
 		}
268 271
 
269  
-		if ($this->config['dbms'] == 'sqlite')
  272
+		if (strpos($this->config['dbms'], 'sqlite') === 0)
270 273
 		{
271 274
 			// remove comment lines starting with # - they are not proper sqlite
272 275
 			// syntax and break sqlite2
@@ -330,6 +333,11 @@ protected function get_dbms_data($dbms)
330 333
 				'DELIM'			=> ';',
331 334
 				'PDO'			=> 'sqlite2',
332 335
 			),
  336
+			'sqlite3'		=> array(
  337
+				'SCHEMA'		=> 'sqlite',
  338
+				'DELIM'			=> ';',
  339
+				'PDO'			=> 'sqlite',
  340
+			),
333 341
 		);
334 342
 
335 343
 		if (isset($available_dbms[$dbms]))

No commit comments for this range

Something went wrong with that request. Please try again.