source: pro-violet-viettel/www/deploy/20150304/system/database/drivers/mysqli/mysqli_driver.php

Last change on this file was 780, checked in by dungnv, 10 years ago
File size: 17.0 KB
Line 
1<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.1.6 or newer
6 *
7 * @package             CodeIgniter
8 * @author              ExpressionEngine Dev Team
9 * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
10 * @license             http://codeigniter.com/user_guide/license.html
11 * @link                http://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              ExpressionEngine Dev Team
29 * @link                http://codeigniter.com/user_guide/database/
30 */
31class CI_DB_mysqli_driver extends CI_DB {
32
33        var $dbdriver = 'mysqli';
34
35        // The character used for escaping
36        var $_escape_char = '`';
37
38        // clause and character used for LIKE escape sequences - not used in MySQL
39        var $_like_escape_str = '';
40        var $_like_escape_chr = '';
41
42        /**
43         * The syntax to count rows is slightly different across different
44         * database engines, so this string appears in each driver and is
45         * used for the count_all() and count_all_results() functions.
46         */
47        var $_count_string = "SELECT COUNT(*) AS ";
48        var $_random_keyword = ' RAND()'; // database specific random keyword
49
50        /**
51         * Whether to use the MySQL "delete hack" which allows the number
52         * of affected rows to be shown. Uses a preg_replace when enabled,
53         * adding a bit more processing to all queries.
54         */
55        var $delete_hack = TRUE;
56
57        // whether SET NAMES must be used to set the character set
58        var $use_set_names;
59       
60        // --------------------------------------------------------------------
61
62        /**
63         * Non-persistent database connection
64         *
65         * @access      private called by the base class
66         * @return      resource
67         */
68        function db_connect()
69        {
70                if ($this->port != '')
71                {
72                        return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);
73                }
74                else
75                {
76                        return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
77                }
78
79        }
80
81        // --------------------------------------------------------------------
82
83        /**
84         * Persistent database connection
85         *
86         * @access      private called by the base class
87         * @return      resource
88         */
89        function db_pconnect()
90        {
91                return $this->db_connect();
92        }
93
94        // --------------------------------------------------------------------
95
96        /**
97         * Reconnect
98         *
99         * Keep / reestablish the db connection if no queries have been
100         * sent for a length of time exceeding the server's idle timeout
101         *
102         * @access      public
103         * @return      void
104         */
105        function reconnect()
106        {
107                if (mysqli_ping($this->conn_id) === FALSE)
108                {
109                        $this->conn_id = FALSE;
110                }
111        }
112
113        // --------------------------------------------------------------------
114
115        /**
116         * Select the database
117         *
118         * @access      private called by the base class
119         * @return      resource
120         */
121        function db_select()
122        {
123                return @mysqli_select_db($this->conn_id, $this->database);
124        }
125
126        // --------------------------------------------------------------------
127
128        /**
129         * Set client character set
130         *
131         * @access      private
132         * @param       string
133         * @param       string
134         * @return      resource
135         */
136        function _db_set_charset($charset, $collation)
137        {
138                if ( ! isset($this->use_set_names))
139                {
140                        // mysqli_set_charset() requires MySQL >= 5.0.7, use SET NAMES as fallback
141                        $this->use_set_names = (version_compare(mysqli_get_server_info($this->conn_id), '5.0.7', '>=')) ? FALSE : TRUE;
142                }
143
144                if ($this->use_set_names === TRUE)
145                {
146                        return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'");
147                }
148                else
149                {
150                        return @mysqli_set_charset($this->conn_id, $charset);
151                }
152        }
153
154        // --------------------------------------------------------------------
155
156        /**
157         * Version number query string
158         *
159         * @access      public
160         * @return      string
161         */
162        function _version()
163        {
164                return "SELECT version() AS ver";
165        }
166
167        // --------------------------------------------------------------------
168
169        /**
170         * Execute the query
171         *
172         * @access      private called by the base class
173         * @param       string  an SQL query
174         * @return      resource
175         */
176        function _execute($sql)
177        {
178                $sql = $this->_prep_query($sql);
179                $result = @mysqli_query($this->conn_id, $sql);
180                return $result;
181        }
182
183        // --------------------------------------------------------------------
184
185        /**
186         * Prep the query
187         *
188         * If needed, each database adapter can prep the query string
189         *
190         * @access      private called by execute()
191         * @param       string  an SQL query
192         * @return      string
193         */
194        function _prep_query($sql)
195        {
196                // "DELETE FROM TABLE" returns 0 affected rows This hack modifies
197                // the query so that it returns the number of affected rows
198                if ($this->delete_hack === TRUE)
199                {
200                        if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
201                        {
202                                $sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
203                        }
204                }
205
206                return $sql;
207        }
208
209        // --------------------------------------------------------------------
210
211        /**
212         * Begin Transaction
213         *
214         * @access      public
215         * @return      bool
216         */
217        function trans_begin($test_mode = FALSE)
218        {
219                if ( ! $this->trans_enabled)
220                {
221                        return TRUE;
222                }
223
224                // When transactions are nested we only begin/commit/rollback the outermost ones
225                if ($this->_trans_depth > 0)
226                {
227                        return TRUE;
228                }
229
230                // Reset the transaction failure flag.
231                // If the $test_mode flag is set to TRUE transactions will be rolled back
232                // even if the queries produce a successful result.
233                $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
234
235                $this->simple_query('SET AUTOCOMMIT=0');
236                $this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
237                return TRUE;
238        }
239
240        // --------------------------------------------------------------------
241
242        /**
243         * Commit Transaction
244         *
245         * @access      public
246         * @return      bool
247         */
248        function trans_commit()
249        {
250                if ( ! $this->trans_enabled)
251                {
252                        return TRUE;
253                }
254
255                // When transactions are nested we only begin/commit/rollback the outermost ones
256                if ($this->_trans_depth > 0)
257                {
258                        return TRUE;
259                }
260
261                $this->simple_query('COMMIT');
262                $this->simple_query('SET AUTOCOMMIT=1');
263                return TRUE;
264        }
265
266        // --------------------------------------------------------------------
267
268        /**
269         * Rollback Transaction
270         *
271         * @access      public
272         * @return      bool
273         */
274        function trans_rollback()
275        {
276                if ( ! $this->trans_enabled)
277                {
278                        return TRUE;
279                }
280
281                // When transactions are nested we only begin/commit/rollback the outermost ones
282                if ($this->_trans_depth > 0)
283                {
284                        return TRUE;
285                }
286
287                $this->simple_query('ROLLBACK');
288                $this->simple_query('SET AUTOCOMMIT=1');
289                return TRUE;
290        }
291
292        // --------------------------------------------------------------------
293
294        /**
295         * Escape String
296         *
297         * @access      public
298         * @param       string
299         * @param       bool    whether or not the string will be used in a LIKE condition
300         * @return      string
301         */
302        function escape_str($str, $like = FALSE)
303        {
304                if (is_array($str))
305                {
306                        foreach ($str as $key => $val)
307                        {
308                                $str[$key] = $this->escape_str($val, $like);
309                        }
310
311                        return $str;
312                }
313
314                if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))
315                {
316                        $str = mysqli_real_escape_string($this->conn_id, $str);
317                }
318                elseif (function_exists('mysql_escape_string'))
319                {
320                        $str = mysql_escape_string($str);
321                }
322                else
323                {
324                        $str = addslashes($str);
325                }
326
327                // escape LIKE condition wildcards
328                if ($like === TRUE)
329                {
330                        $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
331                }
332
333                return $str;
334        }
335
336        // --------------------------------------------------------------------
337
338        /**
339         * Affected Rows
340         *
341         * @access      public
342         * @return      integer
343         */
344        function affected_rows()
345        {
346                return @mysqli_affected_rows($this->conn_id);
347        }
348
349        // --------------------------------------------------------------------
350
351        /**
352         * Insert ID
353         *
354         * @access      public
355         * @return      integer
356         */
357        function insert_id()
358        {
359                return @mysqli_insert_id($this->conn_id);
360        }
361
362        // --------------------------------------------------------------------
363
364        /**
365         * "Count All" query
366         *
367         * Generates a platform-specific query string that counts all records in
368         * the specified database
369         *
370         * @access      public
371         * @param       string
372         * @return      string
373         */
374        function count_all($table = '')
375        {
376                if ($table == '')
377                {
378                        return 0;
379                }
380
381                $query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
382
383                if ($query->num_rows() == 0)
384                {
385                        return 0;
386                }
387
388                $row = $query->row();
389                $this->_reset_select();
390                return (int) $row->numrows;
391        }
392
393        // --------------------------------------------------------------------
394
395        /**
396         * List table query
397         *
398         * Generates a platform-specific query string so that the table names can be fetched
399         *
400         * @access      private
401         * @param       boolean
402         * @return      string
403         */
404        function _list_tables($prefix_limit = FALSE)
405        {
406                $sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;
407
408                if ($prefix_limit !== FALSE AND $this->dbprefix != '')
409                {
410                        $sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
411                }
412
413                return $sql;
414        }
415
416        // --------------------------------------------------------------------
417
418        /**
419         * Show column query
420         *
421         * Generates a platform-specific query string so that the column names can be fetched
422         *
423         * @access      public
424         * @param       string  the table name
425         * @return      string
426         */
427        function _list_columns($table = '')
428        {
429                return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
430        }
431
432        // --------------------------------------------------------------------
433
434        /**
435         * Field data query
436         *
437         * Generates a platform-specific query so that the column data can be retrieved
438         *
439         * @access      public
440         * @param       string  the table name
441         * @return      object
442         */
443        function _field_data($table)
444        {
445                return "DESCRIBE ".$table;
446        }
447
448        // --------------------------------------------------------------------
449
450        /**
451         * The error message string
452         *
453         * @access      private
454         * @return      string
455         */
456        function _error_message()
457        {
458                return mysqli_error($this->conn_id);
459        }
460
461        // --------------------------------------------------------------------
462
463        /**
464         * The error message number
465         *
466         * @access      private
467         * @return      integer
468         */
469        function _error_number()
470        {
471                return mysqli_errno($this->conn_id);
472        }
473
474        // --------------------------------------------------------------------
475
476        /**
477         * Escape the SQL Identifiers
478         *
479         * This function escapes column and table names
480         *
481         * @access      private
482         * @param       string
483         * @return      string
484         */
485        function _escape_identifiers($item)
486        {
487                if ($this->_escape_char == '')
488                {
489                        return $item;
490                }
491
492                foreach ($this->_reserved_identifiers as $id)
493                {
494                        if (strpos($item, '.'.$id) !== FALSE)
495                        {
496                                $str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
497
498                                // remove duplicates if the user already included the escape
499                                return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
500                        }
501                }
502
503                if (strpos($item, '.') !== FALSE)
504                {
505                        $str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
506                }
507                else
508                {
509                        $str = $this->_escape_char.$item.$this->_escape_char;
510                }
511
512                // remove duplicates if the user already included the escape
513                return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
514        }
515
516        // --------------------------------------------------------------------
517
518        /**
519         * From Tables
520         *
521         * This function implicitly groups FROM tables so there is no confusion
522         * about operator precedence in harmony with SQL standards
523         *
524         * @access      public
525         * @param       type
526         * @return      type
527         */
528        function _from_tables($tables)
529        {
530                if ( ! is_array($tables))
531                {
532                        $tables = array($tables);
533                }
534
535                return '('.implode(', ', $tables).')';
536        }
537
538        // --------------------------------------------------------------------
539
540        /**
541         * Insert statement
542         *
543         * Generates a platform-specific insert string from the supplied data
544         *
545         * @access      public
546         * @param       string  the table name
547         * @param       array   the insert keys
548         * @param       array   the insert values
549         * @return      string
550         */
551        function _insert($table, $keys, $values)
552        {
553                return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
554        }
555
556        // --------------------------------------------------------------------
557
558        /**
559         * Insert_batch statement
560         *
561         * Generates a platform-specific insert string from the supplied data
562         *
563         * @access      public
564         * @param       string  the table name
565         * @param       array   the insert keys
566         * @param       array   the insert values
567         * @return      string
568         */
569        function _insert_batch($table, $keys, $values)
570        {
571                return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
572        }
573
574        // --------------------------------------------------------------------
575
576
577        /**
578         * Replace statement
579         *
580         * Generates a platform-specific replace string from the supplied data
581         *
582         * @access      public
583         * @param       string  the table name
584         * @param       array   the insert keys
585         * @param       array   the insert values
586         * @return      string
587         */
588        function _replace($table, $keys, $values)
589        {
590                return "REPLACE INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
591        }
592       
593        // --------------------------------------------------------------------
594
595        /**
596         * Update statement
597         *
598         * Generates a platform-specific update string from the supplied data
599         *
600         * @access      public
601         * @param       string  the table name
602         * @param       array   the update data
603         * @param       array   the where clause
604         * @param       array   the orderby clause
605         * @param       array   the limit clause
606         * @return      string
607         */
608        function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
609        {
610                foreach ($values as $key => $val)
611                {
612                        $valstr[] = $key." = ".$val;
613                }
614
615                $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
616
617                $orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
618
619                $sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
620
621                $sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
622
623                $sql .= $orderby.$limit;
624
625                return $sql;
626        }
627
628        // --------------------------------------------------------------------
629
630        /**
631         * Update_Batch statement
632         *
633         * Generates a platform-specific batch update string from the supplied data
634         *
635         * @access      public
636         * @param       string  the table name
637         * @param       array   the update data
638         * @param       array   the where clause
639         * @return      string
640         */
641        function _update_batch($table, $values, $index, $where = NULL)
642        {
643                $ids = array();
644                $where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
645
646                foreach ($values as $key => $val)
647                {
648                        $ids[] = $val[$index];
649
650                        foreach (array_keys($val) as $field)
651                        {
652                                if ($field != $index)
653                                {
654                                        $final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
655                                }
656                        }
657                }
658
659                $sql = "UPDATE ".$table." SET ";
660                $cases = '';
661
662                foreach ($final as $k => $v)
663                {
664                        $cases .= $k.' = CASE '."\n";
665                        foreach ($v as $row)
666                        {
667                                $cases .= $row."\n";
668                        }
669
670                        $cases .= 'ELSE '.$k.' END, ';
671                }
672
673                $sql .= substr($cases, 0, -2);
674
675                $sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
676
677                return $sql;
678        }
679
680        // --------------------------------------------------------------------
681
682        /**
683         * Truncate statement
684         *
685         * Generates a platform-specific truncate string from the supplied data
686         * If the database does not support the truncate() command
687         * This function maps to "DELETE FROM table"
688         *
689         * @access      public
690         * @param       string  the table name
691         * @return      string
692         */
693        function _truncate($table)
694        {
695                return "TRUNCATE ".$table;
696        }
697
698        // --------------------------------------------------------------------
699
700        /**
701         * Delete statement
702         *
703         * Generates a platform-specific delete string from the supplied data
704         *
705         * @access      public
706         * @param       string  the table name
707         * @param       array   the where clause
708         * @param       string  the limit clause
709         * @return      string
710         */
711        function _delete($table, $where = array(), $like = array(), $limit = FALSE)
712        {
713                $conditions = '';
714
715                if (count($where) > 0 OR count($like) > 0)
716                {
717                        $conditions = "\nWHERE ";
718                        $conditions .= implode("\n", $this->ar_where);
719
720                        if (count($where) > 0 && count($like) > 0)
721                        {
722                                $conditions .= " AND ";
723                        }
724                        $conditions .= implode("\n", $like);
725                }
726
727                $limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
728
729                return "DELETE FROM ".$table.$conditions.$limit;
730        }
731
732        // --------------------------------------------------------------------
733
734        /**
735         * Limit string
736         *
737         * Generates a platform-specific LIMIT clause
738         *
739         * @access      public
740         * @param       string  the sql query string
741         * @param       integer the number of rows to limit the query to
742         * @param       integer the offset value
743         * @return      string
744         */
745        function _limit($sql, $limit, $offset)
746        {
747                $sql .= "LIMIT ".$limit;
748
749                if ($offset > 0)
750                {
751                        $sql .= " OFFSET ".$offset;
752                }
753
754                return $sql;
755        }
756
757        // --------------------------------------------------------------------
758
759        /**
760         * Close DB Connection
761         *
762         * @access      public
763         * @param       resource
764         * @return      void
765         */
766        function _close($conn_id)
767        {
768                @mysqli_close($conn_id);
769        }
770
771
772}
773
774
775/* End of file mysqli_driver.php */
776/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
Note: See TracBrowser for help on using the repository browser.