blob: a7d0d087dc31c78dbfa47b7d8e1a90ef7b74ca64 [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
darwinel871754a2014-02-11 17:34:57 +010021 * @copyright Copyright (c) 2008 - 2014, 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 *
Andrey Andreev2e171022014-02-25 15:21:41 +020066 * @param bool $persistent
67 * @return SQLite3
Andrey Andreev8ae24c52012-01-16 13:05:23 +020068 */
Andrey Andreev2e171022014-02-25 15:21:41 +020069 public function db_connect($persistent = FALSE)
Andrey Andreev8ae24c52012-01-16 13:05:23 +020070 {
Andrey Andreev2e171022014-02-25 15:21:41 +020071 if ($persistent)
72 {
73 log_message('debug', 'SQLite3 doesn\'t support persistent connections');
74 }
75
Andrey Andreev8ae24c52012-01-16 13:05:23 +020076 try
77 {
78 return ( ! $this->password)
79 ? new SQLite3($this->database)
80 : new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password);
81 }
82 catch (Exception $e)
83 {
84 return FALSE;
85 }
86 }
87
88 // --------------------------------------------------------------------
89
90 /**
Andrey Andreev80e34f92012-03-03 03:25:23 +020091 * Database version number
Andrey Andreev8ae24c52012-01-16 13:05:23 +020092 *
93 * @return string
94 */
Andrey Andreev80e34f92012-03-03 03:25:23 +020095 public function version()
Andrey Andreev8ae24c52012-01-16 13:05:23 +020096 {
Andrey Andreev80e34f92012-03-03 03:25:23 +020097 if (isset($this->data_cache['version']))
98 {
99 return $this->data_cache['version'];
100 }
101
Andrey Andreevfc11dcc2012-06-04 16:39:19 +0300102 $version = SQLite3::version();
Andrey Andreev80e34f92012-03-03 03:25:23 +0200103 return $this->data_cache['version'] = $version['versionString'];
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200104 }
105
106 // --------------------------------------------------------------------
107
108 /**
109 * Execute the query
110 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300111 * @todo Implement use of SQLite3::querySingle(), if needed
112 * @param string $sql
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200113 * @return mixed SQLite3Result object or bool
114 */
115 protected function _execute($sql)
116 {
Andrey Andreeva92c7cd2012-03-02 13:51:22 +0200117 return $this->is_write_type($sql)
118 ? $this->conn_id->exec($sql)
119 : $this->conn_id->query($sql);
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200120 }
121
122 // --------------------------------------------------------------------
123
124 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200125 * Begin Transaction
126 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200127 * @param bool $test_mode
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200128 * @return bool
129 */
130 public function trans_begin($test_mode = FALSE)
131 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200132 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev72d7a6e2012-01-19 16:02:32 +0200133 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200134 {
135 return TRUE;
136 }
137
138 // Reset the transaction failure flag.
139 // If the $test_mode flag is set to TRUE transactions will be rolled back
140 // even if the queries produce a successful result.
141 $this->_trans_failure = ($test_mode === TRUE);
142
143 return $this->conn_id->exec('BEGIN TRANSACTION');
144 }
145
146 // --------------------------------------------------------------------
147
148 /**
149 * Commit Transaction
150 *
151 * @return bool
152 */
153 public function trans_commit()
154 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200155 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev72d7a6e2012-01-19 16:02:32 +0200156 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200157 {
158 return TRUE;
159 }
160
161 return $this->conn_id->exec('END TRANSACTION');
162 }
163
164 // --------------------------------------------------------------------
165
166 /**
167 * Rollback Transaction
168 *
169 * @return bool
170 */
171 public function trans_rollback()
172 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200173 // When transactions are nested we only begin/commit/rollback the outermost ones
Andrey Andreev72d7a6e2012-01-19 16:02:32 +0200174 if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200175 {
176 return TRUE;
177 }
178
179 return $this->conn_id->exec('ROLLBACK');
180 }
181
182 // --------------------------------------------------------------------
183
184 /**
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200185 * Platform-dependant string escape
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200186 *
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200187 * @param string
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200188 * @return string
189 */
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200190 protected function _escape_str($str)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200191 {
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200192 return $this->conn_id->escapeString(remove_invisible_characters($str));
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200193 }
194
195 // --------------------------------------------------------------------
196
197 /**
198 * Affected Rows
199 *
200 * @return int
201 */
202 public function affected_rows()
203 {
204 return $this->conn_id->changes();
205 }
206
207 // --------------------------------------------------------------------
208
209 /**
210 * Insert ID
211 *
212 * @return int
213 */
214 public function insert_id()
215 {
216 return $this->conn_id->lastInsertRowID();
217 }
218
219 // --------------------------------------------------------------------
220
221 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200222 * Show table query
223 *
224 * Generates a platform-specific query string so that the table names can be fetched
225 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200226 * @param bool $prefix_limit
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200227 * @return string
228 */
229 protected function _list_tables($prefix_limit = FALSE)
230 {
231 return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
232 .(($prefix_limit !== FALSE && $this->dbprefix != '')
233 ? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr)
234 : '');
235 }
236
237 // --------------------------------------------------------------------
238
239 /**
240 * Show column query
241 *
242 * Generates a platform-specific query string so that the column names can be fetched
243 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200244 * @param string $table
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200245 * @return string
246 */
247 protected function _list_columns($table = '')
248 {
249 // Not supported
250 return FALSE;
251 }
252
253 // --------------------------------------------------------------------
254
255 /**
Andrey Andreev822e74e2012-11-16 02:33:30 +0200256 * Returns an object with field data
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200257 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200258 * @param string $table
Andrey Andreev822e74e2012-11-16 02:33:30 +0200259 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200260 */
Andrey Andreev822e74e2012-11-16 02:33:30 +0200261 public function field_data($table = '')
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200262 {
Andrey Andreev822e74e2012-11-16 02:33:30 +0200263 if ($table === '')
264 {
265 return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
266 }
267
268 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;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200291 }
292
293 // --------------------------------------------------------------------
294
295 /**
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300296 * Error
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200297 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300298 * Returns an array containing code and message of the last
299 * database error that has occured.
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200300 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300301 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200302 */
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300303 public function error()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200304 {
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300305 return array('code' => $this->conn_id->lastErrorCode(), 'message' => $this->conn_id->lastErrorMsg());
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200306 }
307
308 // --------------------------------------------------------------------
309
310 /**
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300311 * Replace statement
312 *
313 * Generates a platform-specific replace string from the supplied data
314 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200315 * @param string $table Table name
316 * @param array $keys INSERT keys
317 * @param array $values INSERT values
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300318 * @return string
319 */
320 protected function _replace($table, $keys, $values)
321 {
322 return 'INSERT OR '.parent::_replace($table, $keys, $values);
323 }
324
325 // --------------------------------------------------------------------
326
327 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200328 * Truncate statement
329 *
330 * Generates a platform-specific truncate string from the supplied data
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300331 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200332 * If the database does not support the TRUNCATE statement,
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300333 * then this method maps to 'DELETE FROM table'
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200334 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200335 * @param string $table
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200336 * @return string
337 */
338 protected function _truncate($table)
339 {
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300340 return 'DELETE FROM '.$table;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200341 }
342
343 // --------------------------------------------------------------------
344
345 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200346 * Close DB Connection
347 *
348 * @return void
349 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300350 protected function _close()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200351 {
352 $this->conn_id->close();
353 }
354
355}
356
357/* End of file sqlite3_driver.php */
Andrey Andreevf944d3b2012-03-20 22:12:55 +0200358/* Location: ./system/database/drivers/sqlite3/sqlite3_driver.php */