Take two:
[www-register-wizard.git] / database / drivers / mysqli / mysqli_driver.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
2 /**\r
3  * CodeIgniter\r
4  *\r
5  * An open source application development framework for PHP 4.3.2 or newer\r
6  *\r
7  * @package             CodeIgniter\r
8  * @author              ExpressionEngine Dev Team\r
9  * @copyright   Copyright (c) 2008, EllisLab, Inc.\r
10  * @license             http://codeigniter.com/user_guide/license.html\r
11  * @link                http://codeigniter.com\r
12  * @since               Version 1.0\r
13  * @filesource\r
14  */\r
15 \r
16 // ------------------------------------------------------------------------\r
17 \r
18 /**\r
19  * MySQLi Database Adapter Class - MySQLi only works with PHP 5\r
20  *\r
21  * Note: _DB is an extender class that the app controller\r
22  * creates dynamically based on whether the active record\r
23  * class is being used or not.\r
24  *\r
25  * @package             CodeIgniter\r
26  * @subpackage  Drivers\r
27  * @category    Database\r
28  * @author              ExpressionEngine Dev Team\r
29  * @link                http://codeigniter.com/user_guide/database/\r
30  */\r
31 class CI_DB_mysqli_driver extends CI_DB {\r
32 \r
33         var $dbdriver = 'mysqli';\r
34         \r
35         // The character used for escaping\r
36         var $_escape_char = '`';\r
37 \r
38         /**\r
39          * The syntax to count rows is slightly different across different\r
40          * database engines, so this string appears in each driver and is\r
41          * used for the count_all() and count_all_results() functions.\r
42          */\r
43         var $_count_string = "SELECT COUNT(*) AS ";\r
44         var $_random_keyword = ' RAND()'; // database specific random keyword\r
45 \r
46         /**\r
47          * Whether to use the MySQL "delete hack" which allows the number\r
48          * of affected rows to be shown. Uses a preg_replace when enabled,\r
49          * adding a bit more processing to all queries.\r
50          */     \r
51         var $delete_hack = TRUE;\r
52 \r
53         // --------------------------------------------------------------------\r
54 \r
55         /**\r
56          * Non-persistent database connection\r
57          *\r
58          * @access      private called by the base class\r
59          * @return      resource\r
60          */     \r
61         function db_connect()\r
62         {\r
63                 return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);\r
64         }\r
65 \r
66         // --------------------------------------------------------------------\r
67 \r
68         /**\r
69          * Persistent database connection\r
70          *\r
71          * @access      private called by the base class\r
72          * @return      resource\r
73          */     \r
74         function db_pconnect()\r
75         {\r
76                 return $this->db_connect();\r
77         }\r
78         \r
79         // --------------------------------------------------------------------\r
80 \r
81         /**\r
82          * Select the database\r
83          *\r
84          * @access      private called by the base class\r
85          * @return      resource\r
86          */     \r
87         function db_select()\r
88         {\r
89                 return @mysqli_select_db($this->conn_id, $this->database);\r
90         }\r
91 \r
92         // --------------------------------------------------------------------\r
93 \r
94         /**\r
95          * Set client character set\r
96          *\r
97          * @access      private\r
98          * @param       string\r
99          * @param       string\r
100          * @return      resource\r
101          */\r
102         function _db_set_charset($charset, $collation)\r
103         {\r
104                 return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");\r
105         }\r
106 \r
107         // --------------------------------------------------------------------\r
108         \r
109         /**\r
110          * Version number query string\r
111          *\r
112          * @access      public\r
113          * @return      string\r
114          */\r
115         function _version()\r
116         {\r
117                 return "SELECT version() AS ver";\r
118         }\r
119 \r
120         // --------------------------------------------------------------------\r
121 \r
122         /**\r
123          * Execute the query\r
124          *\r
125          * @access      private called by the base class\r
126          * @param       string  an SQL query\r
127          * @return      resource\r
128          */     \r
129         function _execute($sql)\r
130         {\r
131                 $sql = $this->_prep_query($sql);        \r
132                 $result = @mysqli_query($this->conn_id, $sql);\r
133                 return $result;\r
134         }\r
135         \r
136         // --------------------------------------------------------------------\r
137 \r
138         /**\r
139          * Prep the query\r
140          *\r
141          * If needed, each database adapter can prep the query string\r
142          *\r
143          * @access      private called by execute()\r
144          * @param       string  an SQL query\r
145          * @return      string\r
146          */     \r
147         function _prep_query($sql)\r
148         {\r
149                 // "DELETE FROM TABLE" returns 0 affected rows This hack modifies\r
150                 // the query so that it returns the number of affected rows\r
151                 if ($this->delete_hack === TRUE)\r
152                 {\r
153                         if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))\r
154                         {\r
155                                 $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);\r
156                         }\r
157                 }\r
158                 \r
159                 return $sql;\r
160         }\r
161 \r
162         // --------------------------------------------------------------------\r
163 \r
164         /**\r
165          * Begin Transaction\r
166          *\r
167          * @access      public\r
168          * @return      bool            \r
169          */     \r
170         function trans_begin($test_mode = FALSE)\r
171         {\r
172                 if ( ! $this->trans_enabled)\r
173                 {\r
174                         return TRUE;\r
175                 }\r
176                 \r
177                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
178                 if ($this->_trans_depth > 0)\r
179                 {\r
180                         return TRUE;\r
181                 }\r
182 \r
183                 // Reset the transaction failure flag.\r
184                 // If the $test_mode flag is set to TRUE transactions will be rolled back\r
185                 // even if the queries produce a successful result.\r
186                 $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;\r
187 \r
188                 $this->simple_query('SET AUTOCOMMIT=0');\r
189                 $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK\r
190                 return TRUE;\r
191         }\r
192 \r
193         // --------------------------------------------------------------------\r
194 \r
195         /**\r
196          * Commit Transaction\r
197          *\r
198          * @access      public\r
199          * @return      bool            \r
200          */     \r
201         function trans_commit()\r
202         {\r
203                 if ( ! $this->trans_enabled)\r
204                 {\r
205                         return TRUE;\r
206                 }\r
207 \r
208                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
209                 if ($this->_trans_depth > 0)\r
210                 {\r
211                         return TRUE;\r
212                 }\r
213 \r
214                 $this->simple_query('COMMIT');\r
215                 $this->simple_query('SET AUTOCOMMIT=1');\r
216                 return TRUE;\r
217         }\r
218 \r
219         // --------------------------------------------------------------------\r
220 \r
221         /**\r
222          * Rollback Transaction\r
223          *\r
224          * @access      public\r
225          * @return      bool            \r
226          */     \r
227         function trans_rollback()\r
228         {\r
229                 if ( ! $this->trans_enabled)\r
230                 {\r
231                         return TRUE;\r
232                 }\r
233 \r
234                 // When transactions are nested we only begin/commit/rollback the outermost ones\r
235                 if ($this->_trans_depth > 0)\r
236                 {\r
237                         return TRUE;\r
238                 }\r
239 \r
240                 $this->simple_query('ROLLBACK');\r
241                 $this->simple_query('SET AUTOCOMMIT=1');\r
242                 return TRUE;\r
243         }\r
244 \r
245         // --------------------------------------------------------------------\r
246 \r
247         /**\r
248          * Escape String\r
249          *\r
250          * @access      public\r
251          * @param       string\r
252          * @return      string\r
253          */\r
254         function escape_str($str)       \r
255         {\r
256                 if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))\r
257                 {\r
258                         return mysqli_real_escape_string($this->conn_id, $str);\r
259                 }\r
260                 elseif (function_exists('mysql_escape_string'))\r
261                 {\r
262                         return mysql_escape_string($str);\r
263                 }\r
264                 else\r
265                 {\r
266                         return addslashes($str);\r
267                 }\r
268         }\r
269                 \r
270         // --------------------------------------------------------------------\r
271 \r
272         /**\r
273          * Affected Rows\r
274          *\r
275          * @access      public\r
276          * @return      integer\r
277          */\r
278         function affected_rows()\r
279         {\r
280                 return @mysqli_affected_rows($this->conn_id);\r
281         }\r
282         \r
283         // --------------------------------------------------------------------\r
284 \r
285         /**\r
286          * Insert ID\r
287          *\r
288          * @access      public\r
289          * @return      integer\r
290          */\r
291         function insert_id()\r
292         {\r
293                 return @mysqli_insert_id($this->conn_id);\r
294         }\r
295 \r
296         // --------------------------------------------------------------------\r
297 \r
298         /**\r
299          * "Count All" query\r
300          *\r
301          * Generates a platform-specific query string that counts all records in\r
302          * the specified database\r
303          *\r
304          * @access      public\r
305          * @param       string\r
306          * @return      string\r
307          */\r
308         function count_all($table = '')\r
309         {\r
310                 if ($table == '')\r
311                         return '0';\r
312                 \r
313                 $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows'). " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));\r
314                 \r
315                 if ($query->num_rows() == 0)\r
316                         return '0';\r
317 \r
318                 $row = $query->row();\r
319                 return $row->numrows;\r
320         }\r
321 \r
322         // --------------------------------------------------------------------\r
323 \r
324         /**\r
325          * List table query\r
326          *\r
327          * Generates a platform-specific query string so that the table names can be fetched\r
328          *\r
329          * @access      private\r
330          * @param       boolean\r
331          * @return      string\r
332          */\r
333         function _list_tables($prefix_limit = FALSE)\r
334         {\r
335                 $sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;     \r
336                 \r
337                 if ($prefix_limit !== FALSE AND $this->dbprefix != '')\r
338                 {\r
339                         $sql .= " LIKE '".$this->dbprefix."%'";\r
340                 }\r
341                 \r
342                 return $sql;\r
343         }\r
344 \r
345         // --------------------------------------------------------------------\r
346 \r
347         /**\r
348          * Show column query\r
349          *\r
350          * Generates a platform-specific query string so that the column names can be fetched\r
351          *\r
352          * @access      public\r
353          * @param       string  the table name\r
354          * @return      string\r
355          */\r
356         function _list_columns($table = '')\r
357         {\r
358                 return "SHOW COLUMNS FROM ".$table;\r
359         }\r
360 \r
361         // --------------------------------------------------------------------\r
362 \r
363         /**\r
364          * Field data query\r
365          *\r
366          * Generates a platform-specific query so that the column data can be retrieved\r
367          *\r
368          * @access      public\r
369          * @param       string  the table name\r
370          * @return      object\r
371          */\r
372         function _field_data($table)\r
373         {\r
374                 return "SELECT * FROM ".$table." LIMIT 1";\r
375         }\r
376 \r
377         // --------------------------------------------------------------------\r
378 \r
379         /**\r
380          * The error message string\r
381          *\r
382          * @access      private\r
383          * @return      string\r
384          */\r
385         function _error_message()\r
386         {\r
387                 return mysqli_error($this->conn_id);\r
388         }\r
389         \r
390         // --------------------------------------------------------------------\r
391 \r
392         /**\r
393          * The error message number\r
394          *\r
395          * @access      private\r
396          * @return      integer\r
397          */\r
398         function _error_number()\r
399         {\r
400                 return mysqli_errno($this->conn_id);\r
401         }\r
402 \r
403         // --------------------------------------------------------------------\r
404 \r
405         /**\r
406          * Escape the SQL Identifiers\r
407          *\r
408          * This function escapes column and table names\r
409          *\r
410          * @access      private\r
411          * @param       string\r
412          * @return      string\r
413          */\r
414         function _escape_identifiers($item)\r
415         {\r
416                 if ($this->_escape_char == '')\r
417                 {\r
418                         return $item;\r
419                 }\r
420         \r
421                 if (strpos($item, '.') !== FALSE)\r
422                 {\r
423                         $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;                    \r
424                 }\r
425                 else\r
426                 {\r
427                         $str = $this->_escape_char.$item.$this->_escape_char;\r
428                 }\r
429                 \r
430                 // remove duplicates if the user already included the escape\r
431                 return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);\r
432         }\r
433                         \r
434         // --------------------------------------------------------------------\r
435 \r
436         /**\r
437          * From Tables\r
438          *\r
439          * This function implicitly groups FROM tables so there is no confusion\r
440          * about operator precedence in harmony with SQL standards\r
441          *\r
442          * @access      public\r
443          * @param       type\r
444          * @return      type\r
445          */\r
446         function _from_tables($tables)\r
447         {\r
448                 if ( ! is_array($tables))\r
449                 {\r
450                         $tables = array($tables);\r
451                 }\r
452                 \r
453                 return '('.implode(', ', $tables).')';\r
454         }\r
455 \r
456         // --------------------------------------------------------------------\r
457         \r
458         /**\r
459          * Insert statement\r
460          *\r
461          * Generates a platform-specific insert string from the supplied data\r
462          *\r
463          * @access      public\r
464          * @param       string  the table name\r
465          * @param       array   the insert keys\r
466          * @param       array   the insert values\r
467          * @return      string\r
468          */\r
469         function _insert($table, $keys, $values)\r
470         {       \r
471                 return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";\r
472         }\r
473         \r
474         // --------------------------------------------------------------------\r
475 \r
476         /**\r
477          * Update statement\r
478          *\r
479          * Generates a platform-specific update string from the supplied data\r
480          *\r
481          * @access      public\r
482          * @param       string  the table name\r
483          * @param       array   the update data\r
484          * @param       array   the where clause\r
485          * @param       array   the orderby clause\r
486          * @param       array   the limit clause\r
487          * @return      string\r
488          */\r
489         function _update($table, $values, $where, $orderby = array(), $limit = FALSE)\r
490         {\r
491                 foreach($values as $key => $val)\r
492                 {\r
493                         $valstr[] = $key." = ".$val;\r
494                 }\r
495                 \r
496                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
497                 \r
498                 $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';\r
499         \r
500                 $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);\r
501                 \r
502                 $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';\r
503                 \r
504                 $sql .= $orderby.$limit;\r
505                 \r
506                 return $sql;\r
507         }\r
508 \r
509         \r
510         // --------------------------------------------------------------------\r
511 \r
512         /**\r
513          * Truncate statement\r
514          *\r
515          * Generates a platform-specific truncate string from the supplied data\r
516          * If the database does not support the truncate() command\r
517          * This function maps to "DELETE FROM table"\r
518          *\r
519          * @access      public\r
520          * @param       string  the table name\r
521          * @return      string\r
522          */     \r
523         function _truncate($table)\r
524         {\r
525                 return "TRUNCATE ".$table;\r
526         }\r
527         \r
528         // --------------------------------------------------------------------\r
529 \r
530         /**\r
531          * Delete statement\r
532          *\r
533          * Generates a platform-specific delete string from the supplied data\r
534          *\r
535          * @access      public\r
536          * @param       string  the table name\r
537          * @param       array   the where clause\r
538          * @param       string  the limit clause\r
539          * @return      string\r
540          */     \r
541         function _delete($table, $where = array(), $like = array(), $limit = FALSE)\r
542         {\r
543                 $conditions = '';\r
544 \r
545                 if (count($where) > 0 OR count($like) > 0)\r
546                 {\r
547                         $conditions = "\nWHERE ";\r
548                         $conditions .= implode("\n", $this->ar_where);\r
549 \r
550                         if (count($where) > 0 && count($like) > 0)\r
551                         {\r
552                                 $conditions .= " AND ";\r
553                         }\r
554                         $conditions .= implode("\n", $like);\r
555                 }\r
556 \r
557                 $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;\r
558         \r
559                 return "DELETE FROM ".$table.$conditions.$limit;\r
560         }\r
561 \r
562         // --------------------------------------------------------------------\r
563 \r
564         /**\r
565          * Limit string\r
566          *\r
567          * Generates a platform-specific LIMIT clause\r
568          *\r
569          * @access      public\r
570          * @param       string  the sql query string\r
571          * @param       integer the number of rows to limit the query to\r
572          * @param       integer the offset value\r
573          * @return      string\r
574          */\r
575         function _limit($sql, $limit, $offset)\r
576         {       \r
577                 $sql .= "LIMIT ".$limit;\r
578         \r
579                 if ($offset > 0)\r
580                 {\r
581                         $sql .= " OFFSET ".$offset;\r
582                 }\r
583                 \r
584                 return $sql;\r
585         }\r
586 \r
587         // --------------------------------------------------------------------\r
588 \r
589         /**\r
590          * Close DB Connection\r
591          *\r
592          * @access      public\r
593          * @param       resource\r
594          * @return      void\r
595          */\r
596         function _close($conn_id)\r
597         {\r
598                 @mysqli_close($conn_id);\r
599         }\r
600 \r
601 \r
602 }\r
603 \r
604 \r
605 /* End of file mysqli_driver.php */\r
606 /* Location: ./system/database/drivers/mysqli/mysqli_driver.php */