PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/phpBB/includes/db/sqlite.php

http://github.com/phpbb/phpbb3
PHP | 336 lines | 198 code | 53 blank | 85 comment | 32 complexity | 7e50ad3a21f976fb81eea9e163553b69 MD5 | raw file
Possible License(s): AGPL-1.0
  1. <?php
  2. /**
  3. *
  4. * @package dbal
  5. * @copyright (c) 2005 phpBB Group
  6. * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
  7. *
  8. */
  9. /**
  10. * @ignore
  11. */
  12. if (!defined('IN_PHPBB'))
  13. {
  14. exit;
  15. }
  16. include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx);
  17. /**
  18. * Sqlite Database Abstraction Layer
  19. * Minimum Requirement: 2.8.2+
  20. * @package dbal
  21. */
  22. class dbal_sqlite extends dbal
  23. {
  24. /**
  25. * Connect to server
  26. */
  27. function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
  28. {
  29. $this->persistency = $persistency;
  30. $this->user = $sqluser;
  31. $this->server = $sqlserver . (($port) ? ':' . $port : '');
  32. $this->dbname = $database;
  33. $error = '';
  34. $this->db_connect_id = ($this->persistency) ? @sqlite_popen($this->server, 0666, $error) : @sqlite_open($this->server, 0666, $error);
  35. if ($this->db_connect_id)
  36. {
  37. @sqlite_query('PRAGMA short_column_names = 1', $this->db_connect_id);
  38. // @sqlite_query('PRAGMA encoding = "UTF-8"', $this->db_connect_id);
  39. }
  40. return ($this->db_connect_id) ? true : array('message' => $error);
  41. }
  42. /**
  43. * Version information about used database
  44. * @param bool $raw if true, only return the fetched sql_server_version
  45. * @param bool $use_cache if true, it is safe to retrieve the stored value from the cache
  46. * @return string sql server version
  47. */
  48. function sql_server_info($raw = false, $use_cache = true)
  49. {
  50. global $cache;
  51. if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false)
  52. {
  53. $result = @sqlite_query('SELECT sqlite_version() AS version', $this->db_connect_id);
  54. $row = @sqlite_fetch_array($result, SQLITE_ASSOC);
  55. $this->sql_server_version = (!empty($row['version'])) ? $row['version'] : 0;
  56. if (!empty($cache) && $use_cache)
  57. {
  58. $cache->put('sqlite_version', $this->sql_server_version);
  59. }
  60. }
  61. return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version;
  62. }
  63. /**
  64. * SQL Transaction
  65. * @access private
  66. */
  67. function _sql_transaction($status = 'begin')
  68. {
  69. switch ($status)
  70. {
  71. case 'begin':
  72. return @sqlite_query('BEGIN', $this->db_connect_id);
  73. break;
  74. case 'commit':
  75. return @sqlite_query('COMMIT', $this->db_connect_id);
  76. break;
  77. case 'rollback':
  78. return @sqlite_query('ROLLBACK', $this->db_connect_id);
  79. break;
  80. }
  81. return true;
  82. }
  83. /**
  84. * Base query method
  85. *
  86. * @param string $query Contains the SQL query which shall be executed
  87. * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
  88. * @return mixed When casted to bool the returned value returns true on success and false on failure
  89. *
  90. * @access public
  91. */
  92. function sql_query($query = '', $cache_ttl = 0)
  93. {
  94. if ($query != '')
  95. {
  96. global $cache;
  97. // EXPLAIN only in extra debug mode
  98. if (defined('DEBUG_EXTRA'))
  99. {
  100. $this->sql_report('start', $query);
  101. }
  102. $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
  103. $this->sql_add_num_queries($this->query_result);
  104. if ($this->query_result === false)
  105. {
  106. if (($this->query_result = @sqlite_query($query, $this->db_connect_id)) === false)
  107. {
  108. $this->sql_error($query);
  109. }
  110. if (defined('DEBUG_EXTRA'))
  111. {
  112. $this->sql_report('stop', $query);
  113. }
  114. if ($cache_ttl && method_exists($cache, 'sql_save'))
  115. {
  116. $this->open_queries[(int) $this->query_result] = $this->query_result;
  117. $cache->sql_save($query, $this->query_result, $cache_ttl);
  118. }
  119. else if (strpos($query, 'SELECT') === 0 && $this->query_result)
  120. {
  121. $this->open_queries[(int) $this->query_result] = $this->query_result;
  122. }
  123. }
  124. else if (defined('DEBUG_EXTRA'))
  125. {
  126. $this->sql_report('fromcache', $query);
  127. }
  128. }
  129. else
  130. {
  131. return false;
  132. }
  133. return $this->query_result;
  134. }
  135. /**
  136. * Build LIMIT query
  137. */
  138. function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
  139. {
  140. $this->query_result = false;
  141. // if $total is set to 0 we do not want to limit the number of rows
  142. if ($total == 0)
  143. {
  144. $total = -1;
  145. }
  146. $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total);
  147. return $this->sql_query($query, $cache_ttl);
  148. }
  149. /**
  150. * Return number of affected rows
  151. */
  152. function sql_affectedrows()
  153. {
  154. return ($this->db_connect_id) ? @sqlite_changes($this->db_connect_id) : false;
  155. }
  156. /**
  157. * Fetch current row
  158. */
  159. function sql_fetchrow($query_id = false)
  160. {
  161. global $cache;
  162. if ($query_id === false)
  163. {
  164. $query_id = $this->query_result;
  165. }
  166. if (isset($cache->sql_rowset[$query_id]))
  167. {
  168. return $cache->sql_fetchrow($query_id);
  169. }
  170. return ($query_id !== false) ? @sqlite_fetch_array($query_id, SQLITE_ASSOC) : false;
  171. }
  172. /**
  173. * Seek to given row number
  174. * rownum is zero-based
  175. */
  176. function sql_rowseek($rownum, &$query_id)
  177. {
  178. global $cache;
  179. if ($query_id === false)
  180. {
  181. $query_id = $this->query_result;
  182. }
  183. if (isset($cache->sql_rowset[$query_id]))
  184. {
  185. return $cache->sql_rowseek($rownum, $query_id);
  186. }
  187. return ($query_id !== false) ? @sqlite_seek($query_id, $rownum) : false;
  188. }
  189. /**
  190. * Get last inserted id after insert statement
  191. */
  192. function sql_nextid()
  193. {
  194. return ($this->db_connect_id) ? @sqlite_last_insert_rowid($this->db_connect_id) : false;
  195. }
  196. /**
  197. * Free sql result
  198. */
  199. function sql_freeresult($query_id = false)
  200. {
  201. global $cache;
  202. if ($query_id === false)
  203. {
  204. $query_id = $this->query_result;
  205. }
  206. if (isset($cache->sql_rowset[$query_id]))
  207. {
  208. return $cache->sql_freeresult($query_id);
  209. }
  210. return true;
  211. }
  212. /**
  213. * Escape string used in sql query
  214. */
  215. function sql_escape($msg)
  216. {
  217. return @sqlite_escape_string($msg);
  218. }
  219. /**
  220. * Correctly adjust LIKE expression for special characters
  221. * For SQLite an underscore is a not-known character... this may change with SQLite3
  222. */
  223. function sql_like_expression($expression)
  224. {
  225. // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
  226. // We only catch * and ? here, not the character map possible on file globbing.
  227. $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
  228. $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
  229. $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
  230. return 'GLOB \'' . $this->sql_escape($expression) . '\'';
  231. }
  232. /**
  233. * return sql error array
  234. * @access private
  235. */
  236. function _sql_error()
  237. {
  238. return array(
  239. 'message' => @sqlite_error_string(@sqlite_last_error($this->db_connect_id)),
  240. 'code' => @sqlite_last_error($this->db_connect_id)
  241. );
  242. }
  243. /**
  244. * Build db-specific query data
  245. * @access private
  246. */
  247. function _sql_custom_build($stage, $data)
  248. {
  249. return $data;
  250. }
  251. /**
  252. * Close sql connection
  253. * @access private
  254. */
  255. function _sql_close()
  256. {
  257. return @sqlite_close($this->db_connect_id);
  258. }
  259. /**
  260. * Build db-specific report
  261. * @access private
  262. */
  263. function _sql_report($mode, $query = '')
  264. {
  265. switch ($mode)
  266. {
  267. case 'start':
  268. break;
  269. case 'fromcache':
  270. $endtime = explode(' ', microtime());
  271. $endtime = $endtime[0] + $endtime[1];
  272. $result = @sqlite_query($query, $this->db_connect_id);
  273. while ($void = @sqlite_fetch_array($result, SQLITE_ASSOC))
  274. {
  275. // Take the time spent on parsing rows into account
  276. }
  277. $splittime = explode(' ', microtime());
  278. $splittime = $splittime[0] + $splittime[1];
  279. $this->sql_report('record_fromcache', $query, $endtime, $splittime);
  280. break;
  281. }
  282. }
  283. }