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