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