blob: bf2be00d3d1b01f2c5515ba768c75da149b5cabc [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Andrey Andreev8ae24c52012-01-16 13:05:23 +02002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Andrey Andreev8ae24c52012-01-16 13:05:23 +02006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreev8ae24c52012-01-16 13:05:23 +02008 *
Andrey Andreev125ef472016-01-11 12:33:00 +02009 * Copyright (c) 2014 - 2016, British Columbia Institute of Technology
Andrey Andreev8ae24c52012-01-16 13:05:23 +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:
Andrey Andreev8ae24c52012-01-16 13:05:23 +020017 *
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 Andreev125ef472016-01-11 12:33:00 +020032 * @copyright Copyright (c) 2014 - 2016, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
Andrey Andreevbd202c92016-01-11 12:50:18 +020034 * @link https://codeigniter.com
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020035 * @since Version 3.0.0
Andrey Andreev8ae24c52012-01-16 13:05:23 +020036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Andrey Andreev8ae24c52012-01-16 13:05:23 +020039
40/**
41 * SQLite3 Database Adapter Class
42 *
43 * Note: _DB is an extender class that the app controller
Jamie Rumbelowffe7a0a2012-04-26 13:48:18 +010044 * creates dynamically based on whether the query builder
Andrey Andreev8ae24c52012-01-16 13:05:23 +020045 * class is being used or not.
46 *
Andrey Andreev17ceeae2012-04-05 15:38:30 +030047 * @package CodeIgniter
Andrey Andreev8ae24c52012-01-16 13:05:23 +020048 * @subpackage Drivers
49 * @category Database
Andrey Andreev17ceeae2012-04-05 15:38:30 +030050 * @author Andrey Andreev
Andrey Andreevbd202c92016-01-11 12:50:18 +020051 * @link https://codeigniter.com/user_guide/database/
Andrey Andreev8ae24c52012-01-16 13:05:23 +020052 */
53class CI_DB_sqlite3_driver extends CI_DB {
54
Andrey Andreeva24e52e2012-11-02 03:54:12 +020055 /**
56 * Database driver
57 *
58 * @var string
59 */
Andrey Andreev8ae24c52012-01-16 13:05:23 +020060 public $dbdriver = 'sqlite3';
61
Andrey Andreeva24e52e2012-11-02 03:54:12 +020062 // --------------------------------------------------------------------
Andrey Andreev8ae24c52012-01-16 13:05:23 +020063
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()');
Andrey Andreev8ae24c52012-01-16 13:05:23 +020070
Andrey Andreeva24e52e2012-11-02 03:54:12 +020071 // --------------------------------------------------------------------
72
Andrey Andreev8ae24c52012-01-16 13:05:23 +020073 /**
74 * Non-persistent database connection
75 *
Andrey Andreev2e171022014-02-25 15:21:41 +020076 * @param bool $persistent
77 * @return SQLite3
Andrey Andreev8ae24c52012-01-16 13:05:23 +020078 */
Andrey Andreev2e171022014-02-25 15:21:41 +020079 public function db_connect($persistent = FALSE)
Andrey Andreev8ae24c52012-01-16 13:05:23 +020080 {
Andrey Andreev2e171022014-02-25 15:21:41 +020081 if ($persistent)
82 {
83 log_message('debug', 'SQLite3 doesn\'t support persistent connections');
84 }
85
Andrey Andreev8ae24c52012-01-16 13:05:23 +020086 try
87 {
88 return ( ! $this->password)
89 ? new SQLite3($this->database)
90 : new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password);
91 }
92 catch (Exception $e)
93 {
94 return FALSE;
95 }
96 }
97
98 // --------------------------------------------------------------------
99
100 /**
Andrey Andreev80e34f92012-03-03 03:25:23 +0200101 * Database version number
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200102 *
103 * @return string
104 */
Andrey Andreev80e34f92012-03-03 03:25:23 +0200105 public function version()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200106 {
Andrey Andreev80e34f92012-03-03 03:25:23 +0200107 if (isset($this->data_cache['version']))
108 {
109 return $this->data_cache['version'];
110 }
111
Andrey Andreevfc11dcc2012-06-04 16:39:19 +0300112 $version = SQLite3::version();
Andrey Andreev80e34f92012-03-03 03:25:23 +0200113 return $this->data_cache['version'] = $version['versionString'];
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200114 }
115
116 // --------------------------------------------------------------------
117
118 /**
119 * Execute the query
120 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300121 * @todo Implement use of SQLite3::querySingle(), if needed
122 * @param string $sql
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200123 * @return mixed SQLite3Result object or bool
124 */
125 protected function _execute($sql)
126 {
Andrey Andreeva92c7cd2012-03-02 13:51:22 +0200127 return $this->is_write_type($sql)
128 ? $this->conn_id->exec($sql)
129 : $this->conn_id->query($sql);
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200130 }
131
132 // --------------------------------------------------------------------
133
134 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200135 * Begin Transaction
136 *
137 * @return bool
138 */
Andrey Andreeva7d4aba2015-10-19 14:39:44 +0300139 protected function _trans_begin()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200140 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200141 return $this->conn_id->exec('BEGIN TRANSACTION');
142 }
143
144 // --------------------------------------------------------------------
145
146 /**
147 * Commit Transaction
148 *
149 * @return bool
150 */
Andrey Andreeva7d4aba2015-10-19 14:39:44 +0300151 protected function _trans_commit()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200152 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200153 return $this->conn_id->exec('END TRANSACTION');
154 }
155
156 // --------------------------------------------------------------------
157
158 /**
159 * Rollback Transaction
160 *
161 * @return bool
162 */
Andrey Andreeva7d4aba2015-10-19 14:39:44 +0300163 protected function _trans_rollback()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200164 {
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200165 return $this->conn_id->exec('ROLLBACK');
166 }
167
168 // --------------------------------------------------------------------
169
170 /**
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200171 * Platform-dependant string escape
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200172 *
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200173 * @param string
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200174 * @return string
175 */
Andrey Andreev0b6a4922013-01-10 16:53:44 +0200176 protected function _escape_str($str)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200177 {
Andrey Andreev62fad282014-06-19 15:25:40 +0300178 return $this->conn_id->escapeString($str);
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200179 }
180
181 // --------------------------------------------------------------------
182
183 /**
184 * Affected Rows
185 *
186 * @return int
187 */
188 public function affected_rows()
189 {
190 return $this->conn_id->changes();
191 }
192
193 // --------------------------------------------------------------------
194
195 /**
196 * Insert ID
197 *
198 * @return int
199 */
200 public function insert_id()
201 {
202 return $this->conn_id->lastInsertRowID();
203 }
204
205 // --------------------------------------------------------------------
206
207 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200208 * Show table query
209 *
210 * Generates a platform-specific query string so that the table names can be fetched
211 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200212 * @param bool $prefix_limit
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200213 * @return string
214 */
215 protected function _list_tables($prefix_limit = FALSE)
216 {
217 return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
218 .(($prefix_limit !== FALSE && $this->dbprefix != '')
219 ? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr)
220 : '');
221 }
222
223 // --------------------------------------------------------------------
224
225 /**
Andrey Andreev0f850902015-04-29 12:33:11 +0300226 * Fetch Field Names
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200227 *
Andrey Andreev0f850902015-04-29 12:33:11 +0300228 * @param string $table Table name
229 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200230 */
Andrey Andreev0f850902015-04-29 12:33:11 +0300231 public function list_fields($table)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200232 {
Andrey Andreev0f850902015-04-29 12:33:11 +0300233 // Is there a cached result?
234 if (isset($this->data_cache['field_names'][$table]))
235 {
236 return $this->data_cache['field_names'][$table];
237 }
238
239 if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE)
240 {
241 return FALSE;
242 }
243
244 $this->data_cache['field_names'][$table] = array();
ftwbzhao69befa92015-07-04 17:42:31 +0800245 foreach ($result->result_array() as $row)
Andrey Andreev0f850902015-04-29 12:33:11 +0300246 {
247 $this->data_cache['field_names'][$table][] = $row['name'];
248 }
249
250 return $this->data_cache['field_names'][$table];
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200251 }
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 Andreev5350f052015-01-12 12:33:37 +0200261 public function field_data($table)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200262 {
Andrey Andreev822e74e2012-11-16 02:33:30 +0200263 if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE)
264 {
265 return FALSE;
266 }
267
268 $query = $query->result_array();
269 if (empty($query))
270 {
271 return FALSE;
272 }
273
274 $retval = array();
275 for ($i = 0, $c = count($query); $i < $c; $i++)
276 {
277 $retval[$i] = new stdClass();
278 $retval[$i]->name = $query[$i]['name'];
279 $retval[$i]->type = $query[$i]['type'];
280 $retval[$i]->max_length = NULL;
281 $retval[$i]->default = $query[$i]['dflt_value'];
282 $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0;
283 }
284
285 return $retval;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200286 }
287
288 // --------------------------------------------------------------------
289
290 /**
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300291 * Error
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200292 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300293 * Returns an array containing code and message of the last
294 * database error that has occured.
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200295 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300296 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200297 */
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300298 public function error()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200299 {
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300300 return array('code' => $this->conn_id->lastErrorCode(), 'message' => $this->conn_id->lastErrorMsg());
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200301 }
302
303 // --------------------------------------------------------------------
304
305 /**
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300306 * Replace statement
307 *
308 * Generates a platform-specific replace string from the supplied data
309 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200310 * @param string $table Table name
311 * @param array $keys INSERT keys
312 * @param array $values INSERT values
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300313 * @return string
314 */
315 protected function _replace($table, $keys, $values)
316 {
317 return 'INSERT OR '.parent::_replace($table, $keys, $values);
318 }
319
320 // --------------------------------------------------------------------
321
322 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200323 * Truncate statement
324 *
325 * Generates a platform-specific truncate string from the supplied data
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300326 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200327 * If the database does not support the TRUNCATE statement,
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300328 * then this method maps to 'DELETE FROM table'
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200329 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200330 * @param string $table
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200331 * @return string
332 */
333 protected function _truncate($table)
334 {
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300335 return 'DELETE FROM '.$table;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200336 }
337
338 // --------------------------------------------------------------------
339
340 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200341 * Close DB Connection
342 *
343 * @return void
344 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300345 protected function _close()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200346 {
347 $this->conn_id->close();
348 }
349
350}