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