blob: 5d057ba5a38af1632280adcbd619d4b8a416a150 [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 *
Instructor, BCIT0e59db62019-01-01 08:34:36 -08009 * Copyright (c) 2014 - 2019, 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
Andrey Andreev1924e872016-01-11 12:55:34 +020031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
Instructor, BCIT0e59db62019-01-01 08:34:36 -080032 * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
33 * @license https://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 Andreev71d8f722017-01-17 12:01:00 +0200171 * Platform-dependent 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 if (($result = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE)
234 {
235 return FALSE;
236 }
237
Andrey Andreevda5cf992018-11-16 16:01:34 +0200238 $fields = array();
ftwbzhao69befa92015-07-04 17:42:31 +0800239 foreach ($result->result_array() as $row)
Andrey Andreev0f850902015-04-29 12:33:11 +0300240 {
Andrey Andreevda5cf992018-11-16 16:01:34 +0200241 $fields[] = $row['name'];
Andrey Andreev0f850902015-04-29 12:33:11 +0300242 }
243
Andrey Andreevda5cf992018-11-16 16:01:34 +0200244 return $fields;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200245 }
246
247 // --------------------------------------------------------------------
248
249 /**
Andrey Andreev822e74e2012-11-16 02:33:30 +0200250 * Returns an object with field data
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200251 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200252 * @param string $table
Andrey Andreev822e74e2012-11-16 02:33:30 +0200253 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200254 */
Andrey Andreev5350f052015-01-12 12:33:37 +0200255 public function field_data($table)
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200256 {
Andrey Andreev822e74e2012-11-16 02:33:30 +0200257 if (($query = $this->query('PRAGMA TABLE_INFO('.$this->protect_identifiers($table, TRUE, NULL, FALSE).')')) === FALSE)
258 {
259 return FALSE;
260 }
261
262 $query = $query->result_array();
263 if (empty($query))
264 {
265 return FALSE;
266 }
267
268 $retval = array();
269 for ($i = 0, $c = count($query); $i < $c; $i++)
270 {
271 $retval[$i] = new stdClass();
272 $retval[$i]->name = $query[$i]['name'];
273 $retval[$i]->type = $query[$i]['type'];
274 $retval[$i]->max_length = NULL;
275 $retval[$i]->default = $query[$i]['dflt_value'];
276 $retval[$i]->primary_key = isset($query[$i]['pk']) ? (int) $query[$i]['pk'] : 0;
277 }
278
279 return $retval;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200280 }
281
282 // --------------------------------------------------------------------
283
284 /**
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300285 * Error
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200286 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300287 * Returns an array containing code and message of the last
Andrey Andreev71d8f722017-01-17 12:01:00 +0200288 * database error that has occurred.
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200289 *
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300290 * @return array
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200291 */
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300292 public function error()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200293 {
Andrey Andreevebbfefa2012-10-05 17:46:47 +0300294 return array('code' => $this->conn_id->lastErrorCode(), 'message' => $this->conn_id->lastErrorMsg());
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200295 }
296
297 // --------------------------------------------------------------------
298
299 /**
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300300 * Replace statement
301 *
302 * Generates a platform-specific replace string from the supplied data
303 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200304 * @param string $table Table name
305 * @param array $keys INSERT keys
306 * @param array $values INSERT values
Andrey Andreev17ceeae2012-04-05 15:38:30 +0300307 * @return string
308 */
309 protected function _replace($table, $keys, $values)
310 {
311 return 'INSERT OR '.parent::_replace($table, $keys, $values);
312 }
313
314 // --------------------------------------------------------------------
315
316 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200317 * Truncate statement
318 *
319 * Generates a platform-specific truncate string from the supplied data
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300320 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200321 * If the database does not support the TRUNCATE statement,
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300322 * then this method maps to 'DELETE FROM table'
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200323 *
Andrey Andreeva24e52e2012-11-02 03:54:12 +0200324 * @param string $table
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200325 * @return string
326 */
327 protected function _truncate($table)
328 {
Andrey Andreeva6fe36e2012-04-05 16:00:32 +0300329 return 'DELETE FROM '.$table;
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200330 }
331
332 // --------------------------------------------------------------------
333
334 /**
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200335 * Close DB Connection
336 *
337 * @return void
338 */
Andrey Andreev79922c02012-05-23 12:27:17 +0300339 protected function _close()
Andrey Andreev8ae24c52012-01-16 13:05:23 +0200340 {
341 $this->conn_id->close();
342 }
343
344}