sqlite_driver.php 14 KB

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