sqlite_driver.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 5.1.6 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * SQLite Database Adapter Class
  18. *
  19. * Note: _DB is an extender class that the app controller
  20. * creates dynamically based on whether the active record
  21. * class is being used or not.
  22. *
  23. * @package CodeIgniter
  24. * @subpackage Drivers
  25. * @category Database
  26. * @author ExpressionEngine Dev Team
  27. * @link http://codeigniter.com/user_guide/database/
  28. */
  29. class CI_DB_sqlite_driver extends CI_DB {
  30. var $dbdriver = 'sqlite';
  31. // The character used to escape with - not needed for SQLite
  32. var $_escape_char = '';
  33. // clause and character used for LIKE escape sequences
  34. var $_like_escape_str = " ESCAPE '%s' ";
  35. var $_like_escape_chr = '!';
  36. /**
  37. * The syntax to count rows is slightly different across different
  38. * database engines, so this string appears in each driver and is
  39. * used for the count_all() and count_all_results() functions.
  40. */
  41. var $_count_string = "SELECT COUNT(*) AS ";
  42. var $_random_keyword = ' Random()'; // database specific random keyword
  43. /**
  44. * Non-persistent database connection
  45. *
  46. * @access private called by the base class
  47. * @return resource
  48. */
  49. function db_connect()
  50. {
  51. if ( ! $conn_id = @sqlite_open($this->database, FILE_WRITE_MODE, $error))
  52. {
  53. log_message('error', $error);
  54. if ($this->db_debug)
  55. {
  56. $this->display_error($error, '', TRUE);
  57. }
  58. return FALSE;
  59. }
  60. return $conn_id;
  61. }
  62. // --------------------------------------------------------------------
  63. /**
  64. * Persistent database connection
  65. *
  66. * @access private called by the base class
  67. * @return resource
  68. */
  69. function db_pconnect()
  70. {
  71. if ( ! $conn_id = @sqlite_popen($this->database, FILE_WRITE_MODE, $error))
  72. {
  73. log_message('error', $error);
  74. if ($this->db_debug)
  75. {
  76. $this->display_error($error, '', TRUE);
  77. }
  78. return FALSE;
  79. }
  80. return $conn_id;
  81. }
  82. // --------------------------------------------------------------------
  83. /**
  84. * Reconnect
  85. *
  86. * Keep / reestablish the db connection if no queries have been
  87. * sent for a length of time exceeding the server's idle timeout
  88. *
  89. * @access public
  90. * @return void
  91. */
  92. function reconnect()
  93. {
  94. // not implemented in SQLite
  95. }
  96. // --------------------------------------------------------------------
  97. /**
  98. * Select the database
  99. *
  100. * @access private called by the base class
  101. * @return resource
  102. */
  103. function db_select()
  104. {
  105. return TRUE;
  106. }
  107. // --------------------------------------------------------------------
  108. /**
  109. * Set client character set
  110. *
  111. * @access public
  112. * @param string
  113. * @param string
  114. * @return resource
  115. */
  116. function db_set_charset($charset, $collation)
  117. {
  118. // @todo - add support if needed
  119. return TRUE;
  120. }
  121. // --------------------------------------------------------------------
  122. /**
  123. * Version number query string
  124. *
  125. * @access public
  126. * @return string
  127. */
  128. function _version()
  129. {
  130. return sqlite_libversion();
  131. }
  132. // --------------------------------------------------------------------
  133. /**
  134. * Execute the query
  135. *
  136. * @access private called by the base class
  137. * @param string an SQL query
  138. * @return resource
  139. */
  140. function _execute($sql)
  141. {
  142. $sql = $this->_prep_query($sql);
  143. return @sqlite_query($this->conn_id, $sql);
  144. }
  145. // --------------------------------------------------------------------
  146. /**
  147. * Prep the query
  148. *
  149. * If needed, each database adapter can prep the query string
  150. *
  151. * @access private called by execute()
  152. * @param string an SQL query
  153. * @return string
  154. */
  155. function _prep_query($sql)
  156. {
  157. return $sql;
  158. }
  159. // --------------------------------------------------------------------
  160. /**
  161. * Begin Transaction
  162. *
  163. * @access public
  164. * @return bool
  165. */
  166. function trans_begin($test_mode = FALSE)
  167. {
  168. if ( ! $this->trans_enabled)
  169. {
  170. return TRUE;
  171. }
  172. // When transactions are nested we only begin/commit/rollback the outermost ones
  173. if ($this->_trans_depth > 0)
  174. {
  175. return TRUE;
  176. }
  177. // Reset the transaction failure flag.
  178. // If the $test_mode flag is set to TRUE transactions will be rolled back
  179. // even if the queries produce a successful result.
  180. $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
  181. $this->simple_query('BEGIN TRANSACTION');
  182. return TRUE;
  183. }
  184. // --------------------------------------------------------------------
  185. /**
  186. * Commit Transaction
  187. *
  188. * @access public
  189. * @return bool
  190. */
  191. function trans_commit()
  192. {
  193. if ( ! $this->trans_enabled)
  194. {
  195. return TRUE;
  196. }
  197. // When transactions are nested we only begin/commit/rollback the outermost ones
  198. if ($this->_trans_depth > 0)
  199. {
  200. return TRUE;
  201. }
  202. $this->simple_query('COMMIT');
  203. return TRUE;
  204. }
  205. // --------------------------------------------------------------------
  206. /**
  207. * Rollback Transaction
  208. *
  209. * @access public
  210. * @return bool
  211. */
  212. function trans_rollback()
  213. {
  214. if ( ! $this->trans_enabled)
  215. {
  216. return TRUE;
  217. }
  218. // When transactions are nested we only begin/commit/rollback the outermost ones
  219. if ($this->_trans_depth > 0)
  220. {
  221. return TRUE;
  222. }
  223. $this->simple_query('ROLLBACK');
  224. return TRUE;
  225. }
  226. // --------------------------------------------------------------------
  227. /**
  228. * Escape String
  229. *
  230. * @access public
  231. * @param string
  232. * @param bool whether or not the string will be used in a LIKE condition
  233. * @return string
  234. */
  235. function escape_str($str, $like = FALSE)
  236. {
  237. if (is_array($str))
  238. {
  239. foreach ($str as $key => $val)
  240. {
  241. $str[$key] = $this->escape_str($val, $like);
  242. }
  243. return $str;
  244. }
  245. $str = sqlite_escape_string($str);
  246. // escape LIKE condition wildcards
  247. if ($like === TRUE)
  248. {
  249. $str = str_replace( array('%', '_', $this->_like_escape_chr),
  250. array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
  251. $str);
  252. }
  253. return $str;
  254. }
  255. // --------------------------------------------------------------------
  256. /**
  257. * Affected Rows
  258. *
  259. * @access public
  260. * @return integer
  261. */
  262. function affected_rows()
  263. {
  264. return sqlite_changes($this->conn_id);
  265. }
  266. // --------------------------------------------------------------------
  267. /**
  268. * Insert ID
  269. *
  270. * @access public
  271. * @return integer
  272. */
  273. function insert_id()
  274. {
  275. return @sqlite_last_insert_rowid($this->conn_id);
  276. }
  277. // --------------------------------------------------------------------
  278. /**
  279. * "Count All" query
  280. *
  281. * Generates a platform-specific query string that counts all records in
  282. * the specified database
  283. *
  284. * @access public
  285. * @param string
  286. * @return string
  287. */
  288. function count_all($table = '')
  289. {
  290. if ($table == '')
  291. {
  292. return 0;
  293. }
  294. $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
  295. if ($query->num_rows() == 0)
  296. {
  297. return 0;
  298. }
  299. $row = $query->row();
  300. $this->_reset_select();
  301. return (int) $row->numrows;
  302. }
  303. // --------------------------------------------------------------------
  304. /**
  305. * List table query
  306. *
  307. * Generates a platform-specific query string so that the table names can be fetched
  308. *
  309. * @access private
  310. * @param boolean
  311. * @return string
  312. */
  313. function _list_tables($prefix_limit = FALSE)
  314. {
  315. $sql = "SELECT name from sqlite_master WHERE type='table'";
  316. if ($prefix_limit !== FALSE AND $this->dbprefix != '')
  317. {
  318. $sql .= " AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
  319. }
  320. return $sql;
  321. }
  322. // --------------------------------------------------------------------
  323. /**
  324. * Show column query
  325. *
  326. * Generates a platform-specific query string so that the column names can be fetched
  327. *
  328. * @access public
  329. * @param string the table name
  330. * @return string
  331. */
  332. function _list_columns($table = '')
  333. {
  334. // Not supported
  335. return FALSE;
  336. }
  337. // --------------------------------------------------------------------
  338. /**
  339. * Field data query
  340. *
  341. * Generates a platform-specific query so that the column data can be retrieved
  342. *
  343. * @access public
  344. * @param string the table name
  345. * @return object
  346. */
  347. function _field_data($table)
  348. {
  349. return "SELECT * FROM ".$table." LIMIT 1";
  350. }
  351. // --------------------------------------------------------------------
  352. /**
  353. * The error message string
  354. *
  355. * @access private
  356. * @return string
  357. */
  358. function _error_message()
  359. {
  360. return sqlite_error_string(sqlite_last_error($this->conn_id));
  361. }
  362. // --------------------------------------------------------------------
  363. /**
  364. * The error message number
  365. *
  366. * @access private
  367. * @return integer
  368. */
  369. function _error_number()
  370. {
  371. return sqlite_last_error($this->conn_id);
  372. }
  373. // --------------------------------------------------------------------
  374. /**
  375. * Escape the SQL Identifiers
  376. *
  377. * This function escapes column and table names
  378. *
  379. * @access private
  380. * @param string
  381. * @return string
  382. */
  383. function _escape_identifiers($item)
  384. {
  385. if ($this->_escape_char == '')
  386. {
  387. return $item;
  388. }
  389. foreach ($this->_reserved_identifiers as $id)
  390. {
  391. if (strpos($item, '.'.$id) !== FALSE)
  392. {
  393. $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
  394. // remove duplicates if the user already included the escape
  395. return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  396. }
  397. }
  398. if (strpos($item, '.') !== FALSE)
  399. {
  400. $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
  401. }
  402. else
  403. {
  404. $str = $this->_escape_char.$item.$this->_escape_char;
  405. }
  406. // remove duplicates if the user already included the escape
  407. return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
  408. }
  409. // --------------------------------------------------------------------
  410. /**
  411. * From Tables
  412. *
  413. * This function implicitly groups FROM tables so there is no confusion
  414. * about operator precedence in harmony with SQL standards
  415. *
  416. * @access public
  417. * @param type
  418. * @return type
  419. */
  420. function _from_tables($tables)
  421. {
  422. if ( ! is_array($tables))
  423. {
  424. $tables = array($tables);
  425. }
  426. return '('.implode(', ', $tables).')';
  427. }
  428. // --------------------------------------------------------------------
  429. /**
  430. * Insert statement
  431. *
  432. * Generates a platform-specific insert string from the supplied data
  433. *
  434. * @access public
  435. * @param string the table name
  436. * @param array the insert keys
  437. * @param array the insert values
  438. * @return string
  439. */
  440. function _insert($table, $keys, $values)
  441. {
  442. return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
  443. }
  444. // --------------------------------------------------------------------
  445. /**
  446. * Update statement
  447. *
  448. * Generates a platform-specific update string from the supplied data
  449. *
  450. * @access public
  451. * @param string the table name
  452. * @param array the update data
  453. * @param array the where clause
  454. * @param array the orderby clause
  455. * @param array the limit clause
  456. * @return string
  457. */
  458. function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
  459. {
  460. foreach ($values as $key => $val)
  461. {
  462. $valstr[] = $key." = ".$val;
  463. }
  464. $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  465. $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
  466. $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
  467. $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
  468. $sql .= $orderby.$limit;
  469. return $sql;
  470. }
  471. // --------------------------------------------------------------------
  472. /**
  473. * Truncate statement
  474. *
  475. * Generates a platform-specific truncate string from the supplied data
  476. * If the database does not support the truncate() command
  477. * This function maps to "DELETE FROM table"
  478. *
  479. * @access public
  480. * @param string the table name
  481. * @return string
  482. */
  483. function _truncate($table)
  484. {
  485. return $this->_delete($table);
  486. }
  487. // --------------------------------------------------------------------
  488. /**
  489. * Delete statement
  490. *
  491. * Generates a platform-specific delete string from the supplied data
  492. *
  493. * @access public
  494. * @param string the table name
  495. * @param array the where clause
  496. * @param string the limit clause
  497. * @return string
  498. */
  499. function _delete($table, $where = array(), $like = array(), $limit = FALSE)
  500. {
  501. $conditions = '';
  502. if (count($where) > 0 OR count($like) > 0)
  503. {
  504. $conditions = "\nWHERE ";
  505. $conditions .= implode("\n", $this->ar_where);
  506. if (count($where) > 0 && count($like) > 0)
  507. {
  508. $conditions .= " AND ";
  509. }
  510. $conditions .= implode("\n", $like);
  511. }
  512. $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
  513. return "DELETE FROM ".$table.$conditions.$limit;
  514. }
  515. // --------------------------------------------------------------------
  516. /**
  517. * Limit string
  518. *
  519. * Generates a platform-specific LIMIT clause
  520. *
  521. * @access public
  522. * @param string the sql query string
  523. * @param integer the number of rows to limit the query to
  524. * @param integer the offset value
  525. * @return string
  526. */
  527. function _limit($sql, $limit, $offset)
  528. {
  529. if ($offset == 0)
  530. {
  531. $offset = '';
  532. }
  533. else
  534. {
  535. $offset .= ", ";
  536. }
  537. return $sql."LIMIT ".$offset.$limit;
  538. }
  539. // --------------------------------------------------------------------
  540. /**
  541. * Close DB Connection
  542. *
  543. * @access public
  544. * @param resource
  545. * @return void
  546. */
  547. function _close($conn_id)
  548. {
  549. @sqlite_close($conn_id);
  550. }
  551. }
  552. /* End of file sqlite_driver.php */
  553. /* Location: ./system/database/drivers/sqlite/sqlite_driver.php */