blob: 49adb5cc3ed3124cbcb3a82a04b637d02ef0cca3 [file] [log] [blame]
adminb0dd10f2006-08-25 17:25:49 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * Code Igniter
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, pMachine, Inc.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @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/libraries/database/
30 */
31class CI_DB_mysqli extends CI_DB {
32
33 /**
34 * Whether to use the MySQL "delete hack" which allows the number
35 * of affected rows to be shown. Uses a preg_replace when enabled,
36 * adding a bit more processing to all queries.
37 */
38 var $delete_hack = TRUE;
39
40 // --------------------------------------------------------------------
41
42 /**
43 * Non-persistent database connection
44 *
45 * @access private called by the base class
46 * @return resource
47 */
48 function db_connect()
49 {
50 return mysqli_connect($this->hostname, $this->username, $this->password);
51 }
52
53 // --------------------------------------------------------------------
54
55 /**
56 * Persistent database connection
57 *
58 * @access private called by the base class
59 * @return resource
60 */
61 function db_pconnect()
62 {
63 return $this->db_connect();
64 }
65
66 // --------------------------------------------------------------------
67
68 /**
69 * Select the database
70 *
71 * @access private called by the base class
72 * @return resource
73 */
74 function db_select()
75 {
76 return @mysqli_select_db($this->conn_id, $this->database);
77 }
78
79 // --------------------------------------------------------------------
80
81 /**
82 * Execute the query
83 *
84 * @access private called by the base class
85 * @param string an SQL query
86 * @return resource
87 */
88 function execute($sql)
89 {
90 $sql = $this->_prep_query($sql);
admin1082bdd2006-08-27 19:32:02 +000091 $result = @mysqli_query($this->conn_id, $sql);
admin46402b02006-09-19 04:56:14 +000092
93 // We only advance the result pointer if there isn't an error
94 if (mysqli_errno($this->conn_id) == 0)
95 {
96 mysqli_next_result($this->conn_id);
97 }
admin1082bdd2006-08-27 19:32:02 +000098 return $result;
adminb0dd10f2006-08-25 17:25:49 +000099 }
100
101 // --------------------------------------------------------------------
102
103 /**
104 * Prep the query
105 *
106 * If needed, each database adapter can prep the query string
107 *
108 * @access private called by execute()
109 * @param string an SQL query
110 * @return string
111 */
adminb071bb52006-08-26 19:28:37 +0000112 function _prep_query($sql)
adminb0dd10f2006-08-25 17:25:49 +0000113 {
114 // "DELETE FROM TABLE" returns 0 affected rows This hack modifies
115 // the query so that it returns the number of affected rows
116 if ($this->delete_hack === TRUE)
117 {
118 if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
119 {
120 $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
121 }
122 }
123
124 return $sql;
125 }
126
127 // --------------------------------------------------------------------
128
129 /**
130 * Escape String
131 *
132 * @access public
133 * @param string
134 * @return string
135 */
136 function escape_str($str)
137 {
adminb0dd10f2006-08-25 17:25:49 +0000138 return mysqli_real_escape_string($this->conn_id, $str);
139 }
140
141 // --------------------------------------------------------------------
142
143 /**
144 * Close DB Connection
145 *
146 * @access public
147 * @param resource
148 * @return void
149 */
150 function destroy($conn_id)
151 {
152 mysqli_close($conn_id);
153 }
154
155 // --------------------------------------------------------------------
156
157 /**
158 * Affected Rows
159 *
160 * @access public
161 * @return integer
162 */
163 function affected_rows()
164 {
165 return @mysqli_affected_rows($this->conn_id);
166 }
167
168 // --------------------------------------------------------------------
169
170 /**
171 * Insert ID
172 *
173 * @access public
174 * @return integer
175 */
176 function insert_id()
177 {
178 return @mysqli_insert_id($this->conn_id);
179 }
180
181 // --------------------------------------------------------------------
182
183 /**
184 * "Count All" query
185 *
186 * Generates a platform-specific query string that counts all records in
187 * the specified database
188 *
189 * @access public
190 * @param string
191 * @return string
192 */
193 function count_all($table = '')
194 {
195 if ($table == '')
196 return '0';
197
198 $query = $this->query("SELECT COUNT(*) AS numrows FROM `".$this->dbprefix.$table."`");
199
200 if ($query->num_rows() == 0)
201 return '0';
202
203 $row = $query->row();
204 return $row->numrows;
205 }
206
207 // --------------------------------------------------------------------
208
209 /**
210 * The error message string
211 *
212 * @access public
213 * @return string
214 */
215 function error_message()
216 {
217 return mysqli_error($this->conn_id);
218 }
219
220 // --------------------------------------------------------------------
221
222 /**
223 * The error message number
224 *
225 * @access public
226 * @return integer
227 */
228 function error_number()
229 {
230 return mysqli_errno($this->conn_id);
231 }
232
233 // --------------------------------------------------------------------
234
235 /**
236 * Escape Table Name
237 *
238 * This function adds backticks if the table name has a period
239 * in it. Some DBs will get cranky unless periods are escaped
240 *
241 * @access public
242 * @param string the table name
243 * @return string
244 */
245 function escape_table($table)
246 {
247 if (stristr($table, '.'))
248 {
249 $table = preg_replace("/\./", "`.`", $table);
250 }
251
252 return $table;
253 }
254
255 // --------------------------------------------------------------------
256
257 /**
258 * Field data query
259 *
260 * Generates a platform-specific query so that the column data can be retrieved
261 *
262 * @access public
263 * @param string the table name
264 * @return object
265 */
266 function _field_data($table)
267 {
268 $sql = "SELECT * FROM ".$this->escape_table($table)." LIMIT 1";
269 $query = $this->query($sql);
270 return $query->field_data();
271 }
272
273 // --------------------------------------------------------------------
274
275 /**
276 * Insert statement
277 *
278 * Generates a platform-specific insert string from the supplied data
279 *
280 * @access public
281 * @param string the table name
282 * @param array the insert keys
283 * @param array the insert values
284 * @return string
285 */
286 function _insert($table, $keys, $values)
287 {
288 return "INSERT INTO ".$this->escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
289 }
290
291 // --------------------------------------------------------------------
292
293 /**
294 * Update statement
295 *
296 * Generates a platform-specific update string from the supplied data
297 *
298 * @access public
299 * @param string the table name
300 * @param array the update data
301 * @param array the where clause
302 * @return string
303 */
304 function _update($table, $values, $where)
305 {
306 foreach($values as $key => $val)
307 {
308 $valstr[] = $key." = ".$val;
309 }
310
311 return "UPDATE ".$this->escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where);
312 }
313
314 // --------------------------------------------------------------------
315
316 /**
317 * Delete statement
318 *
319 * Generates a platform-specific delete string from the supplied data
320 *
321 * @access public
322 * @param string the table name
323 * @param array the where clause
324 * @return string
325 */
326 function _delete($table, $where)
327 {
328 return "DELETE FROM ".$this->escape_table($table)." WHERE ".implode(" ", $where);
329 }
330
331 // --------------------------------------------------------------------
332
333 /**
334 * Version number query string
335 *
336 * @access public
337 * @return string
338 */
339 function _version()
340 {
341 return "SELECT version() AS ver";
342 }
343
344 // --------------------------------------------------------------------
345
346 /**
347 * Show table query
348 *
349 * Generates a platform-specific query string so that the table names can be fetched
350 *
351 * @access public
352 * @return string
353 */
354 function _show_tables()
355 {
356 return "SHOW TABLES FROM `".$this->database."`";
357 }
358
359 // --------------------------------------------------------------------
360
361 /**
362 * Show columnn query
363 *
364 * Generates a platform-specific query string so that the column names can be fetched
365 *
366 * @access public
367 * @param string the table name
368 * @return string
369 */
370 function _show_columns($table = '')
371 {
372 return "SHOW COLUMNS FROM ".$this->escape_table($table);
373 }
374
375 // --------------------------------------------------------------------
376
377 /**
378 * Limit string
379 *
380 * Generates a platform-specific LIMIT clause
381 *
382 * @access public
383 * @param string the sql query string
384 * @param integer the number of rows to limit the query to
385 * @param integer the offset value
386 * @return string
387 */
388 function _limit($sql, $limit, $offset)
389 {
390 $sql .= "LIMIT ".$limit;
391
392 if ($offset > 0)
393 {
394 $sql .= " OFFSET ".$offset;
395 }
396
397 return $sql;
398 }
399
400}
401
402
403
404/**
405 * MySQLi Result Class
406 *
407 * This class extends the parent result class: CI_DB_result
408 *
409 * @category Database
410 * @author Rick Ellis
411 * @link http://www.codeigniter.com/user_guide/libraries/database/
412 */
413class CI_DB_mysqli_result extends CI_DB_result {
414
415 /**
416 * Number of rows in the result set
417 *
418 * @access public
419 * @return integer
420 */
421 function num_rows()
422 {
423 return @mysqli_num_rows($this->result_id);
424 }
425
426 // --------------------------------------------------------------------
427
428 /**
429 * Number of fields in the result set
430 *
431 * @access public
432 * @return integer
433 */
434 function num_fields()
435 {
436 return @mysqli_num_fields($this->result_id);
437 }
438
439 // --------------------------------------------------------------------
440
441 /**
442 * Field data
443 *
444 * Generates an array of objects containing field meta-data
445 *
446 * @access public
447 * @return array
448 */
449 function field_data()
450 {
451 $retval = array();
452 while ($field = mysqli_fetch_field($this->result_id))
453 {
454 $F = new CI_DB_field();
455 $F->name = $field->name;
456 $F->type = $field->type;
457 $F->default = $field->def;
458 $F->max_length = $field->max_length;
adminb68745e2006-09-17 18:13:34 +0000459 $F->primary_key = ($field->flags & MYSQLI_PRI_KEY_FLAG) ? 1 : 0;
adminb0dd10f2006-08-25 17:25:49 +0000460
461 $retval[] = $F;
462 }
463
464 return $retval;
465 }
466
467 // --------------------------------------------------------------------
468
469 /**
470 * Result - associative array
471 *
472 * Returns the result set as an array
473 *
474 * @access private
475 * @return array
476 */
477 function _fetch_assoc()
478 {
479 return mysqli_fetch_assoc($this->result_id);
480 }
481
482 // --------------------------------------------------------------------
483
484 /**
485 * Result - object
486 *
487 * Returns the result set as an object
488 *
489 * @access private
490 * @return object
491 */
492 function _fetch_object()
493 {
494 return mysqli_fetch_object($this->result_id);
495 }
496
497}
498
499?>