blob: 4d131c31adb1fb99a5f75ac323c9068fcdbcf5bc [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Andrey Andreev8ae24c52012-01-16 13:05:23 +02002/**
3 * CodeIgniter
4 *
Andrey Andreeva6fe36e2012-04-05 16:00:32 +03005 * An open source application development framework for PHP 5.2.4 or newer
Andrey Andreev8ae24c52012-01-16 13:05:23 +02006 *
7 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * This source file is subject to the Open Software License (OSL 3.0) that is
Andrey Andreevf20fb982012-01-24 15:26:01 +020012 * bundled with this package in the files license.txt / license.rst. It is
Andrey Andreev8ae24c52012-01-16 13:05:23 +020013 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Andrey Andreev17ceeae2012-04-05 15:38:30 +030019 * @package CodeIgniter
20 * @author EllisLab Dev Team
Andrey Andreev80500af2013-01-01 08:16:53 +020021 * @copyright Copyright (c) 2008 - 2013, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreev17ceeae2012-04-05 15:38:30 +030022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
23 * @link http://codeigniter.com
24 * @since Version 1.0
Andrey Andreev8ae24c52012-01-16 13:05:23 +020025 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Andrey Andreev8ae24c52012-01-16 13:05:23 +020028
29/**
30 * SQLite3 Database Adapter Class
31 *
32 * Note: _DB is an extender class that the app controller
Jamie Rumbelowffe7a0a2012-04-26 13:48:18 +010033 * creates dynamically based on whether the query builder
Andrey Andreev8ae24c52012-01-16 13:05:23 +020034 * class is being used or not.
35 *
Andrey Andreev17ceeae2012-04-05 15:38:30 +030036 * @package CodeIgniter
Andrey Andreev8ae24c52012-01-16 13:05:23 +020037 * @subpackage Drivers
38 * @category Database
Andrey Andreev17ceeae2012-04-05 15:38:30 +030039 * @author Andrey Andreev
40 * @link http://codeigniter.com/user_guide/database/
41 * @since Version 3.0
Andrey Andreev8ae24c52012-01-16 13:05:23 +020042 */
43class CI_DB_sqlite3_driver extends CI_DB {
44
Andrey Andreeva24e52e2012-11-02 03:54:12 +020045 /**
46 * Database driver
47 *
48 * @var string
49 */
Andrey Andreev8ae24c52012-01-16 13:05:23 +020050 public $dbdriver = 'sqlite3';
51
Andrey Andreeva24e52e2012-11-02 03:54:12 +020052 // --------------------------------------------------------------------
Andrey Andreev8ae24c52012-01-16 13:05:23 +020053
Andrey Andreeva24e52e2012-11-02 03:54:12 +020054 /**
55 * ORDER BY random keyword
56 *
Andrey Andreev98e46cf2012-11-13 03:01:42 +020057 * @var array
Andrey Andreeva24e52e2012-11-02 03:54:12 +020058 */
Andrey Andreev98e46cf2012-11-13 03:01:42 +020059 protected $_random_keyword = array('RANDOM()', 'RANDOM()');
Andrey Andreev8ae24c52012-01-16 13:05:23 +020060
Andrey Andreeva24e52e2012-11-02 03:54:12 +020061 // --------------------------------------------------------------------
62
Andrey Andreev8ae24c52012-01-16 13:05:23 +020063 /**
64 * Non-persistent database connection
65 *
66 * @return object type SQLite3
67 */
68 public function db_connect()
69 {
70 try
71 {
72 return ( ! $this->password)
73 ? new SQLite3($this->database)
74 : new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password);
75 }
76 catch (Exception $e)
77 {
78 return FALSE;
79 }
80 }
81
82 // --------------------------------------------------------------------
83
84 /**
85 * Persistent database connection
86 *
87 * @return object type SQLite3
88 */
89 public function db_pconnect()
90 {
91 log_message('debug', 'SQLite3 doesn\'t support persistent connections');
Andrey Andreev9d533ae2012-06-04 15:56:56 +030092 return $this->db_connect();
Andrey Andreev8ae24c52012-01-16 13:05:23 +020093 }
94
95 // --------------------------------------------------------------------
96
97 /**
Andrey Andreev80e34f92012-03-03 03:25:23 +020098 * Database version number
Andrey Andreev8ae24c52012-01-16 13:05:23 +020099 *
100 * @return string
101 */
Andrey Andreev80e34f92012-03-03 03:25:23 +0200102 public function version()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200103 {
Andrey Andreev80e34f92012-03-03 03:25:23 +0200104 if (isset($this->data_cache['version']))
105 {
106 return $this->data_cache['version'];
107 }
108
Andrey Andreevfc11dcc2012-06-04 16:39:19 +0300109 $version = SQLite3::version();
Andrey Andreev80e34f92012-03-03 03:25:23 +0200110 return $this->data_cache['version'] = $version['versionString'];
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200111 }
112
113 // --------------------------------------------------------------------
114
115 /**
116 * Execute the query
117 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300118 * @todo Implement use of SQLite3::querySingle(), if needed
119 * @param string $sql
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200120 * @return mixed SQLite3Result object or bool
121 */
122 protected function _execute($sql)
123 {
Andrey Andreeva92c7cd2012-03-02 13:51:22 +0200124 return $this->is_write_type($sql)
125 ? $this->conn_id->exec($sql)
126 : $this->conn_id->query($sql);
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200127 }
128
129 // --------------------------------------------------------------------
130
131 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200132 * Begin Transaction
133 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200134 * @param bool $test_mode
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200135 * @return bool
136 */
137 public function trans_begin($test_mode = FALSE)
138 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200139 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev72d7a6e2012-01-19 16:02:32 +0200140 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200141 {
142 return TRUE;
143 }
144
145 // Reset the transaction failure flag.
146 // If the $test_mode flag is set to TRUE transactions will be rolled back
147 // even if the queries produce a successful result.
148 $this->_trans_failure = ($test_mode === TRUE);
149
150 return $this->conn_id->exec('BEGIN TRANSACTION');
151 }
152
153 // --------------------------------------------------------------------
154
155 /**
156 * Commit Transaction
157 *
158 * @return bool
159 */
160 public function trans_commit()
161 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200162 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev72d7a6e2012-01-19 16:02:32 +0200163 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200164 {
165 return TRUE;
166 }
167
168 return $this->conn_id->exec('END TRANSACTION');
169 }
170
171 // --------------------------------------------------------------------
172
173 /**
174 * Rollback Transaction
175 *
176 * @return bool
177 */
178 public function trans_rollback()
179 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200180 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev72d7a6e2012-01-19 16:02:32 +0200181 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200182 {
183 return TRUE;
184 }
185
186 return $this->conn_id->exec('ROLLBACK');
187 }
188
189 // --------------------------------------------------------------------
190
191 /**
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200192 * Platform-dependant string escape
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200193 *
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200194 * @param string
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200195 * @return string
196 */
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200197 protected function _escape_str($str)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200198 {
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200199 return $this->conn_id->escapeString(remove_invisible_characters($str));
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200200 }
201
202 // --------------------------------------------------------------------
203
204 /**
205 * Affected Rows
206 *
207 * @return int
208 */
209 public function affected_rows()
210 {
211 return $this->conn_id->changes();
212 }
213
214 // --------------------------------------------------------------------
215
216 /**
217 * Insert ID
218 *
219 * @return int
220 */
221 public function insert_id()
222 {
223 return $this->conn_id->lastInsertRowID();
224 }
225
226 // --------------------------------------------------------------------
227
228 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200229 * Show table query
230 *
231 * Generates a platform-specific query string so that the table names can be fetched
232 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200233 * @param bool $prefix_limit
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200234 * @return string
235 */
236 protected function _list_tables($prefix_limit = FALSE)
237 {
238 return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
239 .(($prefix_limit !== FALSE && $this->dbprefix != '')
240 ? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr)
241 : '');
242 }
243
244 // --------------------------------------------------------------------
245
246 /**
247 * Show column query
248 *
249 * Generates a platform-specific query string so that the column names can be fetched
250 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200251 * @param string $table
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200252 * @return string
253 */
254 protected function _list_columns($table = '')
255 {
256 // Not supported
257 return FALSE;
258 }
259
260 // --------------------------------------------------------------------
261
262 /**
Andrey Andreev822e74e2012-11-16 02:33:30 +0200263 * Returns an object with field data
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200264 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200265 * @param string $table
Andrey Andreev822e74e2012-11-16 02:33:30 +0200266 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200267 */
Andrey Andreev822e74e2012-11-16 02:33:30 +0200268 public function field_data($table = '')
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200269 {
Andrey Andreev822e74e2012-11-16 02:33:30 +0200270 if ($table === '')
271 {
272 return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
273 }
274
275 if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE)
276 {
277 return FALSE;
278 }
279
280 $query = $query->result_array();
281 if (empty($query))
282 {
283 return FALSE;
284 }
285
286 $retval = array();
287 for ($i = 0, $c = count($query); $i < $c; $i++)
288 {
289 $retval[$i] = new stdClass();
290 $retval[$i]->name = $query[$i]['name'];
291 $retval[$i]->type = $query[$i]['type'];
292 $retval[$i]->max_length = NULL;
293 $retval[$i]->default = $query[$i]['dflt_value'];
294 $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0;
295 }
296
297 return $retval;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200298 }
299
300 // --------------------------------------------------------------------
301
302 /**
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300303 * Error
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200304 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300305 * Returns an array containing code and message of the last
306 * database error that has occured.
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200307 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300308 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200309 */
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300310 public function error()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200311 {
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300312 return array('code' => $this->conn_id->lastErrorCode(), 'message' => $this->conn_id->lastErrorMsg());
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200313 }
314
315 // --------------------------------------------------------------------
316
317 /**
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300318 * Replace statement
319 *
320 * Generates a platform-specific replace string from the supplied data
321 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200322 * @param string $table Table name
323 * @param array $keys INSERT keys
324 * @param array $values INSERT values
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300325 * @return string
326 */
327 protected function _replace($table, $keys, $values)
328 {
329 return 'INSERT OR '.parent::_replace($table, $keys, $values);
330 }
331
332 // --------------------------------------------------------------------
333
334 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200335 * Truncate statement
336 *
337 * Generates a platform-specific truncate string from the supplied data
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300338 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200339 * If the database does not support the TRUNCATE statement,
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300340 * then this method maps to 'DELETE FROM table'
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200341 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200342 * @param string $table
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200343 * @return string
344 */
345 protected function _truncate($table)
346 {
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300347 return 'DELETE FROM '.$table;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200348 }
349
350 // --------------------------------------------------------------------
351
352 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200353 * Close DB Connection
354 *
355 * @return void
356 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300357 protected function _close()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200358 {
359 $this->conn_id->close();
360 }
361
362}
363
364/* End of file sqlite3_driver.php */
Andrey Andreevf944d3b2012-03-20 22:12:55 +0200365/* Location: ./system/database/drivers/sqlite3/sqlite3_driver.php */