blob: 2137bade04a3da2e0856108bf7be3224eafcdd72 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreevd9038782012-01-26 12:38:49 +02008 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02009 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
Andrey Andreevd9038782012-01-26 12:38:49 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
darwinel871754a2014-02-11 17:34:57 +010031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreevfe9309d2015-01-09 17:48:58 +020032 * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
34 * @link http://codeigniter.com
35 * @since Version 1.3.0
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000039
Derek Allard2067d1a2008-11-13 22:59:24 +000040/**
41 * SQLite Database Adapter Class
42 *
43 * Note: _DB is an extender class that the app controller
Jamie Rumbelow7efad202012-02-19 12:37:00 +000044 * creates dynamically based on whether the query builder
Derek Allard2067d1a2008-11-13 22:59:24 +000045 * class is being used or not.
46 *
47 * @package CodeIgniter
48 * @subpackage Drivers
49 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050050 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000051 * @link http://codeigniter.com/user_guide/database/
52 */
53class CI_DB_sqlite_driver extends CI_DB {
54
Andrey Andreeva24e52e2012-11-02 03:54:12 +020055 /**
56 * Database driver
57 *
58 * @var string
59 */
Andrey Andreevd9038782012-01-26 12:38:49 +020060 public $dbdriver = 'sqlite';
Barry Mienydd671972010-10-04 16:33:58 +020061
Andrey Andreeva24e52e2012-11-02 03:54:12 +020062 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +000063
Andrey Andreeva24e52e2012-11-02 03:54:12 +020064 /**
65 * ORDER BY random keyword
66 *
Andrey Andreev98e46cf2012-11-13 03:01:42 +020067 * @var array
Andrey Andreeva24e52e2012-11-02 03:54:12 +020068 */
Andrey Andreev98e46cf2012-11-13 03:01:42 +020069 protected $_random_keyword = array('RANDOM()', 'RANDOM()');
Derek Allard2067d1a2008-11-13 22:59:24 +000070
Andrey Andreeva24e52e2012-11-02 03:54:12 +020071 // --------------------------------------------------------------------
72
Derek Allard2067d1a2008-11-13 22:59:24 +000073 /**
74 * Non-persistent database connection
75 *
Andrey Andreev2e171022014-02-25 15:21:41 +020076 * @param bool $persistent
Derek Allard2067d1a2008-11-13 22:59:24 +000077 * @return resource
Barry Mienydd671972010-10-04 16:33:58 +020078 */
Andrey Andreev2e171022014-02-25 15:21:41 +020079 public function db_connect($persistent = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +000080 {
Andrey Andreev2e171022014-02-25 15:21:41 +020081 $error = NULL;
82 $conn_id = ($persistent === TRUE)
83 ? sqlite_popen($this->database, 0666, $error)
84 : sqlite_open($this->database, 0666, $error);
Barry Mienydd671972010-10-04 16:33:58 +020085
Andrey Andreev2e171022014-02-25 15:21:41 +020086 isset($error) && log_message('error', $error);
Barry Mienydd671972010-10-04 16:33:58 +020087
Derek Allard2067d1a2008-11-13 22:59:24 +000088 return $conn_id;
89 }
Barry Mienydd671972010-10-04 16:33:58 +020090
Derek Allard2067d1a2008-11-13 22:59:24 +000091 // --------------------------------------------------------------------
92
93 /**
Andrey Andreev08856b82012-03-03 03:19:28 +020094 * Database version number
Derek Allard2067d1a2008-11-13 22:59:24 +000095 *
Derek Allard2067d1a2008-11-13 22:59:24 +000096 * @return string
97 */
Andrey Andreev08856b82012-03-03 03:19:28 +020098 public function version()
Derek Allard2067d1a2008-11-13 22:59:24 +000099 {
Andrey Andreev08856b82012-03-03 03:19:28 +0200100 return isset($this->data_cache['version'])
101 ? $this->data_cache['version']
102 : $this->data_cache['version'] = sqlite_libversion();
Derek Allard2067d1a2008-11-13 22:59:24 +0000103 }
Barry Mienydd671972010-10-04 16:33:58 +0200104
Derek Allard2067d1a2008-11-13 22:59:24 +0000105 // --------------------------------------------------------------------
106
107 /**
108 * Execute the query
109 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200110 * @param string $sql an SQL query
Derek Allard2067d1a2008-11-13 22:59:24 +0000111 * @return resource
Barry Mienydd671972010-10-04 16:33:58 +0200112 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200113 protected function _execute($sql)
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 {
Andrey Andreeva0c27852012-03-02 13:49:28 +0200115 return $this->is_write_type($sql)
Andrey Andreev2bbbd1a2014-05-09 10:24:14 +0300116 ? sqlite_exec($this->conn_id, $sql)
117 : sqlite_query($this->conn_id, $sql);
Derek Allard2067d1a2008-11-13 22:59:24 +0000118 }
Barry Mienydd671972010-10-04 16:33:58 +0200119
Derek Allard2067d1a2008-11-13 22:59:24 +0000120 // --------------------------------------------------------------------
121
122 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000123 * Begin Transaction
124 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200125 * @param bool $test_mode
Barry Mienydd671972010-10-04 16:33:58 +0200126 * @return bool
127 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200128 public function trans_begin($test_mode = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000129 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000130 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreevd9038782012-01-26 12:38:49 +0200131 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000132 {
133 return TRUE;
134 }
135
136 // Reset the transaction failure flag.
137 // If the $test_mode flag is set to TRUE transactions will be rolled back
138 // even if the queries produce a successful result.
Andrey Andreevd9038782012-01-26 12:38:49 +0200139 $this->_trans_failure = ($test_mode === TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000140
141 $this->simple_query('BEGIN TRANSACTION');
142 return TRUE;
143 }
144
145 // --------------------------------------------------------------------
146
147 /**
148 * Commit Transaction
149 *
Barry Mienydd671972010-10-04 16:33:58 +0200150 * @return bool
151 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200152 public function trans_commit()
Derek Allard2067d1a2008-11-13 22:59:24 +0000153 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000154 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreevd9038782012-01-26 12:38:49 +0200155 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000156 {
157 return TRUE;
158 }
159
160 $this->simple_query('COMMIT');
161 return TRUE;
162 }
163
164 // --------------------------------------------------------------------
165
166 /**
167 * Rollback Transaction
168 *
Barry Mienydd671972010-10-04 16:33:58 +0200169 * @return bool
170 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200171 public function trans_rollback()
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000173 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreevd9038782012-01-26 12:38:49 +0200174 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 {
176 return TRUE;
177 }
178
179 $this->simple_query('ROLLBACK');
180 return TRUE;
181 }
Barry Mienydd671972010-10-04 16:33:58 +0200182
Derek Allard2067d1a2008-11-13 22:59:24 +0000183 // --------------------------------------------------------------------
184
185 /**
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200186 * Platform-dependant string escape
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 *
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200188 * @param string
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 * @return string
190 */
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200191 protected function _escape_str($str)
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 {
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200193 return sqlite_escape_string($str);
Derek Allard2067d1a2008-11-13 22:59:24 +0000194 }
Barry Mienydd671972010-10-04 16:33:58 +0200195
Derek Allard2067d1a2008-11-13 22:59:24 +0000196 // --------------------------------------------------------------------
197
198 /**
199 * Affected Rows
200 *
Andrey Andreevd9038782012-01-26 12:38:49 +0200201 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000202 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200203 public function affected_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +0000204 {
205 return sqlite_changes($this->conn_id);
206 }
Barry Mienydd671972010-10-04 16:33:58 +0200207
Derek Allard2067d1a2008-11-13 22:59:24 +0000208 // --------------------------------------------------------------------
209
210 /**
211 * Insert ID
212 *
Andrey Andreevd9038782012-01-26 12:38:49 +0200213 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200215 public function insert_id()
Derek Allard2067d1a2008-11-13 22:59:24 +0000216 {
Andrey Andreev2bbbd1a2014-05-09 10:24:14 +0300217 return sqlite_last_insert_rowid($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000218 }
219
220 // --------------------------------------------------------------------
221
222 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000223 * List table query
224 *
225 * Generates a platform-specific query string so that the table names can be fetched
226 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200227 * @param bool $prefix_limit
Derek Allard2067d1a2008-11-13 22:59:24 +0000228 * @return string
229 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200230 protected function _list_tables($prefix_limit = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 {
Andrey Andreevd9038782012-01-26 12:38:49 +0200232 $sql = "SELECT name FROM sqlite_master WHERE type='table'";
Derek Allard2067d1a2008-11-13 22:59:24 +0000233
Andrey Andreevd9038782012-01-26 12:38:49 +0200234 if ($prefix_limit !== FALSE && $this->dbprefix != '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000235 {
Andrey Andreevd9038782012-01-26 12:38:49 +0200236 return $sql." AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
Derek Allard2067d1a2008-11-13 22:59:24 +0000237 }
Andrey Andreevd9038782012-01-26 12:38:49 +0200238
Derek Allard2067d1a2008-11-13 22:59:24 +0000239 return $sql;
240 }
241
242 // --------------------------------------------------------------------
243
244 /**
245 * Show column query
246 *
247 * Generates a platform-specific query string so that the column names can be fetched
248 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200249 * @param string $table
Andrey Andreevd9038782012-01-26 12:38:49 +0200250 * @return bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000251 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200252 protected function _list_columns($table = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000253 {
254 // Not supported
255 return FALSE;
256 }
257
258 // --------------------------------------------------------------------
259
260 /**
Andrey Andreev822e74e2012-11-16 02:33:30 +0200261 * Returns an object with field data
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200263 * @param string $table
Andrey Andreev822e74e2012-11-16 02:33:30 +0200264 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000265 */
Andrey Andreev5350f052015-01-12 12:33:37 +0200266 public function field_data($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000267 {
Andrey Andreev822e74e2012-11-16 02:33:30 +0200268 if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE)
269 {
270 return FALSE;
271 }
272
273 $query = $query->result_array();
274 if (empty($query))
275 {
276 return FALSE;
277 }
278
279 $retval = array();
280 for ($i = 0, $c = count($query); $i < $c; $i++)
281 {
282 $retval[$i] = new stdClass();
283 $retval[$i]->name = $query[$i]['name'];
284 $retval[$i]->type = $query[$i]['type'];
285 $retval[$i]->max_length = NULL;
286 $retval[$i]->default = $query[$i]['dflt_value'];
287 $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0;
288 }
289
290 return $retval;
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 }
292
293 // --------------------------------------------------------------------
294
295 /**
Andrey Andreev4be5de12012-03-02 15:45:41 +0200296 * Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000297 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200298 * Returns an array containing code and message of the last
299 * database error that has occured.
Derek Allard2067d1a2008-11-13 22:59:24 +0000300 *
Andrey Andreev4be5de12012-03-02 15:45:41 +0200301 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 */
Andrey Andreev4be5de12012-03-02 15:45:41 +0200303 public function error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 {
Andrey Andreev4be5de12012-03-02 15:45:41 +0200305 $error = array('code' => sqlite_last_error($this->conn_id));
306 $error['message'] = sqlite_error_string($error['code']);
307 return $error;
Derek Allard2067d1a2008-11-13 22:59:24 +0000308 }
309
310 // --------------------------------------------------------------------
311
312 /**
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300313 * Replace statement
Derek Allard2067d1a2008-11-13 22:59:24 +0000314 *
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300315 * Generates a platform-specific replace string from the supplied data
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200317 * @param string $table Table name
318 * @param array $keys INSERT keys
319 * @param array $values INSERT values
Derek Allard2067d1a2008-11-13 22:59:24 +0000320 * @return string
321 */
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300322 protected function _replace($table, $keys, $values)
Barry Mienydd671972010-10-04 16:33:58 +0200323 {
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300324 return 'INSERT OR '.parent::_replace($table, $keys, $values);
Derek Allard2067d1a2008-11-13 22:59:24 +0000325 }
Barry Mienydd671972010-10-04 16:33:58 +0200326
Derek Allard2067d1a2008-11-13 22:59:24 +0000327 // --------------------------------------------------------------------
328
329 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000330 * Truncate statement
331 *
332 * Generates a platform-specific truncate string from the supplied data
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300333 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200334 * If the database does not support the TRUNCATE statement,
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300335 * then this function maps to 'DELETE FROM table'
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200337 * @param string $table
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200339 */
Andrey Andreevd9038782012-01-26 12:38:49 +0200340 protected function _truncate($table)
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 {
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300342 return 'DELETE FROM '.$table;
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 }
Barry Mienydd671972010-10-04 16:33:58 +0200344
Derek Allard2067d1a2008-11-13 22:59:24 +0000345 // --------------------------------------------------------------------
346
347 /**
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 * Close DB Connection
349 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 * @return void
351 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300352 protected function _close()
Derek Allard2067d1a2008-11-13 22:59:24 +0000353 {
Andrey Andreev2bbbd1a2014-05-09 10:24:14 +0300354 sqlite_close($this->conn_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000355 }
356
Derek Allard2067d1a2008-11-13 22:59:24 +0000357}
358
Derek Allard2067d1a2008-11-13 22:59:24 +0000359/* End of file sqlite_driver.php */
Timothy Warren215890b2012-03-20 09:38:16 -0400360/* Location: ./system/database/drivers/sqlite/sqlite_driver.php */