blob: ebed813903faf67666aa57f35fd8e031d807f4a0 [file] [log] [blame]
Derek Allardd2df9bc2007-04-15 17:41:17 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, EllisLab, Inc.
Derek Allard6838f002007-10-04 19:29:59 +000010 * @license http://www.codeigniter.com/user_guide/license.html
Derek Allardd2df9bc2007-04-15 17:41:17 +000011 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * MySQLi Database Adapter Class - MySQLi only works with PHP 5
20 *
21 * Note: _DB is an extender class that the app controller
22 * creates dynamically based on whether the active record
23 * class is being used or not.
24 *
25 * @package CodeIgniter
26 * @subpackage Drivers
27 * @category Database
28 * @author Rick Ellis
29 * @link http://www.codeigniter.com/user_guide/database/
30 */
31class CI_DB_mysqli_driver extends CI_DB {
32
33 /**
Derek Allard694b5b82007-12-18 15:58:03 +000034 * The syntax to count rows is slightly different across different
35 * database engines, so this string appears in each driver and is
36 * used for the count_all() and count_all_results() functions.
37 */
Derek Allard6ddb5a12007-12-18 17:22:50 +000038 var $_count_string = "SELECT COUNT(*) AS numrows ";
39 var $_random_keyword = ' RAND()'; // database specific random keyword
40
Derek Allard694b5b82007-12-18 15:58:03 +000041 /**
Derek Allardd2df9bc2007-04-15 17:41:17 +000042 * Whether to use the MySQL "delete hack" which allows the number
43 * of affected rows to be shown. Uses a preg_replace when enabled,
44 * adding a bit more processing to all queries.
45 */
46 var $delete_hack = TRUE;
47
48 // --------------------------------------------------------------------
49
50 /**
51 * Non-persistent database connection
52 *
53 * @access private called by the base class
54 * @return resource
55 */
56 function db_connect()
57 {
58 return @mysqli_connect($this->hostname, $this->username, $this->password);
59 }
60
61 // --------------------------------------------------------------------
62
63 /**
64 * Persistent database connection
65 *
66 * @access private called by the base class
67 * @return resource
68 */
69 function db_pconnect()
70 {
71 return $this->db_connect();
72 }
73
74 // --------------------------------------------------------------------
75
76 /**
77 * Select the database
78 *
79 * @access private called by the base class
80 * @return resource
81 */
82 function db_select()
83 {
84 return @mysqli_select_db($this->conn_id, $this->database);
85 }
86
87 // --------------------------------------------------------------------
88
89 /**
90 * Version number query string
91 *
92 * @access public
93 * @return string
94 */
95 function _version()
96 {
97 return "SELECT version() AS ver";
98 }
99
100 // --------------------------------------------------------------------
101
102 /**
103 * Execute the query
104 *
105 * @access private called by the base class
106 * @param string an SQL query
107 * @return resource
108 */
109 function _execute($sql)
110 {
111 $sql = $this->_prep_query($sql);
112 $result = @mysqli_query($this->conn_id, $sql);
113 return $result;
114 }
115
116 // --------------------------------------------------------------------
117
118 /**
119 * Prep the query
120 *
121 * If needed, each database adapter can prep the query string
122 *
123 * @access private called by execute()
124 * @param string an SQL query
125 * @return string
126 */
127 function _prep_query($sql)
128 {
129 // "DELETE FROM TABLE" returns 0 affected rows This hack modifies
130 // the query so that it returns the number of affected rows
131 if ($this->delete_hack === TRUE)
132 {
133 if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
134 {
135 $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
136 }
137 }
138
139 return $sql;
140 }
141
142 // --------------------------------------------------------------------
143
144 /**
145 * Begin Transaction
146 *
147 * @access public
148 * @return bool
149 */
150 function trans_begin($test_mode = FALSE)
151 {
152 if ( ! $this->trans_enabled)
153 {
154 return TRUE;
155 }
156
157 // When transactions are nested we only begin/commit/rollback the outermost ones
158 if ($this->_trans_depth > 0)
159 {
160 return TRUE;
161 }
162
163 // Reset the transaction failure flag.
164 // If the $test_mode flag is set to TRUE transactions will be rolled back
165 // even if the queries produce a successful result.
166 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
167
168 $this->simple_query('SET AUTOCOMMIT=0');
169 $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
170 return TRUE;
171 }
172
173 // --------------------------------------------------------------------
174
175 /**
176 * Commit Transaction
177 *
178 * @access public
179 * @return bool
180 */
181 function trans_commit()
182 {
183 if ( ! $this->trans_enabled)
184 {
185 return TRUE;
186 }
187
188 // When transactions are nested we only begin/commit/rollback the outermost ones
189 if ($this->_trans_depth > 0)
190 {
191 return TRUE;
192 }
193
194 $this->simple_query('COMMIT');
195 $this->simple_query('SET AUTOCOMMIT=1');
196 return TRUE;
197 }
198
199 // --------------------------------------------------------------------
200
201 /**
202 * Rollback Transaction
203 *
204 * @access public
205 * @return bool
206 */
207 function trans_rollback()
208 {
209 if ( ! $this->trans_enabled)
210 {
211 return TRUE;
212 }
213
214 // When transactions are nested we only begin/commit/rollback the outermost ones
215 if ($this->_trans_depth > 0)
216 {
217 return TRUE;
218 }
219
220 $this->simple_query('ROLLBACK');
221 $this->simple_query('SET AUTOCOMMIT=1');
222 return TRUE;
223 }
224
225 // --------------------------------------------------------------------
226
227 /**
228 * Escape String
229 *
230 * @access public
231 * @param string
232 * @return string
233 */
234 function escape_str($str)
Derek Allard694b5b82007-12-18 15:58:03 +0000235 {
236 if (function_exists('mysqli_real_escape_string') AND is_resource($this->conn_id))
237 {
238 return mysqli_real_escape_string($this->conn_id, $str);
239 }
240 elseif (function_exists('mysql_escape_string'))
241 {
242 return mysql_escape_string($str);
243 }
244 else
245 {
246 return addslashes($str);
247 }
Derek Allardd2df9bc2007-04-15 17:41:17 +0000248 }
249
250 // --------------------------------------------------------------------
251
252 /**
253 * Affected Rows
254 *
255 * @access public
256 * @return integer
257 */
258 function affected_rows()
259 {
260 return @mysqli_affected_rows($this->conn_id);
261 }
262
263 // --------------------------------------------------------------------
264
265 /**
266 * Insert ID
267 *
268 * @access public
269 * @return integer
270 */
271 function insert_id()
272 {
273 return @mysqli_insert_id($this->conn_id);
274 }
275
276 // --------------------------------------------------------------------
277
278 /**
279 * "Count All" query
280 *
281 * Generates a platform-specific query string that counts all records in
282 * the specified database
283 *
284 * @access public
285 * @param string
286 * @return string
287 */
288 function count_all($table = '')
289 {
290 if ($table == '')
291 return '0';
292
Derek Allard6ddb5a12007-12-18 17:22:50 +0000293 $query = $this->query($this->_count_string . "FROM `".$this->dbprefix.$table."`");
Derek Allardd2df9bc2007-04-15 17:41:17 +0000294
295 if ($query->num_rows() == 0)
296 return '0';
297
298 $row = $query->row();
299 return $row->numrows;
300 }
301
302 // --------------------------------------------------------------------
303
304 /**
305 * List table query
306 *
307 * Generates a platform-specific query string so that the table names can be fetched
308 *
309 * @access private
310 * @return string
311 */
Derek Allard694b5b82007-12-18 15:58:03 +0000312 function _list_tables($prefix_limit = FALSE)
Derek Allardd2df9bc2007-04-15 17:41:17 +0000313 {
Derek Allard694b5b82007-12-18 15:58:03 +0000314 $sql = "SHOW TABLES FROM `".$this->database."`";
315
316 if ($prefix_limit !== FALSE AND $this->_stdprefix != '')
317 {
318 $sql .= " LIKE '".$this->_stdprefix."%'";
319 }
320
321 return $sql;
Derek Allardd2df9bc2007-04-15 17:41:17 +0000322 }
323
324 // --------------------------------------------------------------------
325
326 /**
327 * Show column query
328 *
329 * Generates a platform-specific query string so that the column names can be fetched
330 *
331 * @access public
332 * @param string the table name
333 * @return string
334 */
335 function _list_columns($table = '')
336 {
337 return "SHOW COLUMNS FROM ".$this->_escape_table($table);
338 }
339
340 // --------------------------------------------------------------------
341
342 /**
343 * Field data query
344 *
345 * Generates a platform-specific query so that the column data can be retrieved
346 *
347 * @access public
348 * @param string the table name
349 * @return object
350 */
351 function _field_data($table)
352 {
353 return "SELECT * FROM ".$this->_escape_table($table)." LIMIT 1";
354 }
355
356 // --------------------------------------------------------------------
357
358 /**
359 * The error message string
360 *
361 * @access private
362 * @return string
363 */
364 function _error_message()
365 {
366 return mysqli_error($this->conn_id);
367 }
368
369 // --------------------------------------------------------------------
370
371 /**
372 * The error message number
373 *
374 * @access private
375 * @return integer
376 */
377 function _error_number()
378 {
379 return mysqli_errno($this->conn_id);
380 }
381
382 // --------------------------------------------------------------------
383
384 /**
385 * Escape Table Name
386 *
387 * This function adds backticks if the table name has a period
388 * in it. Some DBs will get cranky unless periods are escaped
389 *
390 * @access private
391 * @param string the table name
392 * @return string
393 */
394 function _escape_table($table)
395 {
396 if (stristr($table, '.'))
397 {
398 $table = preg_replace("/\./", "`.`", $table);
399 }
400
401 return $table;
402 }
403
404 // --------------------------------------------------------------------
405
406 /**
407 * Insert statement
408 *
409 * Generates a platform-specific insert string from the supplied data
410 *
411 * @access public
412 * @param string the table name
413 * @param array the insert keys
414 * @param array the insert values
415 * @return string
416 */
417 function _insert($table, $keys, $values)
418 {
419 return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
420 }
421
422 // --------------------------------------------------------------------
423
424 /**
425 * Update statement
426 *
427 * Generates a platform-specific update string from the supplied data
428 *
429 * @access public
430 * @param string the table name
431 * @param array the update data
432 * @param array the where clause
433 * @return string
434 */
Derek Allardda6d2402007-12-19 14:49:29 +0000435 function _update($table, $values, $where, $limit = FALSE)
Derek Allardd2df9bc2007-04-15 17:41:17 +0000436 {
437 foreach($values as $key => $val)
438 {
439 $valstr[] = $key." = ".$val;
440 }
Derek Allardda6d2402007-12-19 14:49:29 +0000441
442 $limit = (!$limit) ? '' : ' LIMIT '.$limit;
Derek Allardd2df9bc2007-04-15 17:41:17 +0000443
Derek Allardda6d2402007-12-19 14:49:29 +0000444 return "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where).$limit;
Derek Allardd2df9bc2007-04-15 17:41:17 +0000445 }
446
447 // --------------------------------------------------------------------
448
449 /**
450 * Delete statement
451 *
452 * Generates a platform-specific delete string from the supplied data
453 *
454 * @access public
455 * @param string the table name
456 * @param array the where clause
457 * @return string
458 */
Derek Allarde77d77c2007-12-19 15:01:55 +0000459 function _delete($table, $where, $limit = FALSE)
Derek Allardd2df9bc2007-04-15 17:41:17 +0000460 {
Derek Allarde77d77c2007-12-19 15:01:55 +0000461 $limit = (!$limit) ? '' : ' LIMIT '.$limit;
462
463 return "DELETE FROM ".$this->_escape_table($table)." WHERE ".implode(" ", $where).$limit;
Derek Allardd2df9bc2007-04-15 17:41:17 +0000464 }
465
466 // --------------------------------------------------------------------
467
468 /**
469 * Limit string
470 *
471 * Generates a platform-specific LIMIT clause
472 *
473 * @access public
474 * @param string the sql query string
475 * @param integer the number of rows to limit the query to
476 * @param integer the offset value
477 * @return string
478 */
479 function _limit($sql, $limit, $offset)
480 {
481 $sql .= "LIMIT ".$limit;
482
483 if ($offset > 0)
484 {
485 $sql .= " OFFSET ".$offset;
486 }
487
488 return $sql;
489 }
490
491 // --------------------------------------------------------------------
492
493 /**
494 * Close DB Connection
495 *
496 * @access public
497 * @param resource
498 * @return void
499 */
500 function _close($conn_id)
501 {
502 @mysqli_close($conn_id);
503 }
504
505
506}
507
adminff2d2512006-09-24 18:12:18 +0000508?>