Ticket #145: mysqli.php

File mysqli.php, 8.4 kB (added by ae, 13 months ago)

stored procedures example contained within

Line 
1<?PHP
2/**
3  * This library contain a new version of the mysqli library. Once run, it will
4  * replace the current mysqli db library. All further references to $this->db
5  * will call this library.
6
7  * @author Gary Stidston-Broadbent <gary@stroppytux.net>
8  * @copyright Copyright (c) 2007, Hugeobject
9  */
10
11class db
12{
13    # Connection details
14    private $host                                = 'localhost';
15    private $user                                = 'guest';
16    private $pass                                = 'blank';
17    public  $data                                = 'test';
18    private $pers                                = False;
19    public  $auto_commit                        = True;
20    private $debug                                = False;
21    public  $conn                                = False;
22
23    # Query details
24    public  $queries                            = array();
25    public  $query_times                        = array();
26    public  $benchmark                            = 0;
27    public  $query_count                        = 0;
28
29    # Result details
30    public  $assoc                                = True;
31    public  $results                            = array();
32    public  $error                                = True;
33    public  $m_error                            = False;
34    public  $auto_clear                            = True;
35
36    # Copy the database settings from within the database config file.
37    public function __construct($params='default') {
38        # Load the configuration file
39        include(APPPATH.'config/database'.EXT);
40
41        # Get the server_name and convert it into a usable variable
42        $server_name                            = $_SERVER['SERVER_NAME'];
43        $server_name                            = str_replace('.','_',$server_name);
44
45        # Check if we have a vhost specific config entry
46        if (isset($db[$server_name])) {
47            $params                                = $server_name;
48        }
49
50        # If we dont have a SERVER_NAME param, use the default one
51        if (!isset($db[$params])) {
52            show_error('You have specified an invalid database connection group: '.$params);
53        }
54
55        # Copy our config file params into position
56        $params                                    = $db[$params];
57        $this->host                                = $params['hostname'];
58        $this->user                                = $params['username'];
59        $this->pass                                = $params['password'];
60        $this->data                                = $params['database'];
61        $this->pers                                = $params['pconnect'];
62        $this->debug                            = $params['db_debug'];
63        $this->trace                            = $params['trace'];
64
65        # Check if we want to trace our procedure calls
66        if ($this->trace) {
67            $this->K                            =& get_instance();
68        }
69
70        # Create the connection to the server and select the database
71        if ($this->pers) {
72            $this->conn                            = $this->db_pconnect();
73        } else {
74            $this->conn                            = $this->db_connect();
75        }
76    }
77
78    # Create a standard connection to the server
79    private function db_connect()
80    {
81        $connection                                = new mysqli($this->host, $this->user, $this->pass, $this->data);
82
83        if (mysqli_connect_errno()) {
84            log_message('error', 'Unable to connect to the database');
85
86            if ($this->debug) {
87                $this->display_error(sprintf("Connect failed: %s\n", mysqli_connect_error()));
88            }
89            return FALSE;
90        } else {
91            return $connection;
92        }
93    }
94
95    # Create a persistant connection to the server
96    private function db_pconnect()
97    {
98        return $this->db_connect();
99    }
100
101    # Standard query method. This only does single resultset queries
102    public function query($q_string) {
103        # Check to see if we have a blank query
104        if ($q_string == '') {
105            if ($this->debug) {
106                log_message('error', 'Invalid query: '.$q_string);
107                return $this->display_error('db_invalid_query');
108            }
109            return FALSE;
110        }
111
112        # Keep a copy for debugging
113        if ($this->debug) {
114            $this->queries[]                    = $q_string;
115        } else {
116            $this->queries                        = array($q_string);
117        }
118
119        # Start the Query Timer
120        $time_start                                = list($sm, $ss) = explode(' ', microtime());
121
122        $results                                = $this->conn->query($q_string);
123
124        # Stop and aggregate the query time results
125        $time_end                                = list($em, $es) = explode(' ', microtime());
126        $this->benchmark                        += ($em + $es) - ($sm + $ss);
127
128        # Save individual query times for profiler
129        if ($this->debug) {
130            $this->query_times[]                = $this->benchmark;
131        }
132
133        # Increment the query counter
134        $this->query_count++;
135
136        # Copy the results to the instance results array
137        if ($this->auto_clear) {
138            $this->results                        = Array();
139        }
140        # If we want an accociative array, use mysqli_assoc, else use fetch
141        if ($this->assoc) {
142            while ($row = $result->fetch_assoc()) {
143                $this->results[]                = $row;
144            }
145        } else {
146            while ($row = $result->fetch_row()) {
147                $this->results[]                = $row;
148            }
149        }
150        $result->close();
151    }
152
153    # Fetch the number of rows within our results
154    public function num_rows() {
155        return $this->results->num_rows();
156    }
157
158    # Run a query and return the results to the calling method
159    # NOTE: We use a variadic (Well, as close as php gets to one)
160    #        method to let us pass in inifnate options. Please
161    #        remember the first argument must always be our proc.
162    public function call()
163    {
164        # Build our query to be executed
165        $q_string                                = 'CALL '.func_get_arg(0).'(';
166        # Please note we start on 1 not 0. We would end up with a
167        # off by one error if we didnt. (The first arg is proc).
168        for ($i = 1; $i < func_num_args(); $i++) {
169            $q_string                            .= "'".func_get_arg($i)."',";
170        }
171        $q_string                                .= '@returner);SELECT @returner;';
172
173        # Reset our error value
174        $this->error                            = True;
175
176        # Keep a copy for debugging
177        if ($this->debug) {
178            $this->queries[]                    = $q_string;
179        } else {
180            $this->queries                        = array($q_string);
181        }
182
183        # Start the Query Timer
184        $time_start                                = list($sm, $ss) = explode(' ', microtime());
185
186        # Execute our query, save our results, then check the result status
187        # from the second query (the local mylsq variable)
188        if ($this->conn->multi_query($q_string)) {
189            # Check if we need to clear our results first
190            if ($this->auto_clear) {
191                $this->results                    = Array();
192            }
193
194            # Fetch the result set and save it as an object variable
195            if ($result = $this->conn->store_result()) {
196                # If we want an accociative array, use mysqli_assoc, else use fetch
197                if ($this->assoc) {
198                    while ($row = $result->fetch_assoc()) {
199                        $this->results[]        = $row;
200                    }
201                } else {
202                    while ($row = $result->fetch_row()) {
203                        $this->results[]        = $row;
204                    }
205                }
206                $result->close();
207                $this->conn->next_result();
208            }
209
210            # Check the result status
211            if ($this->conn->more_results()) {
212                $this->conn->next_result();
213                $error                            = $this->conn->store_result();
214
215                # Lets check the error code
216                $error_num                        = $error->fetch_row();
217                $this->error                    = $error_num[0];
218                if ($this->trace) {
219                    $this->K->trace->set_data(func_get_arg(0), $this->error);
220                }
221                $error->free_result();
222                # If we dont have an error, change error to false
223                if ($this->error == '0' or $this->error==0) {
224                    $this->error                = False;
225                }
226            }
227
228            # Not needed, but just for safety (could probably be removed)
229            if ($this->conn->more_results()) {
230                do
231                {
232                    $waste                        = $this->conn->store_result();
233                    $waste->free_result();
234                } while ($this->conn->next_result());
235            }
236        } else {
237            $this->m_error                        = $this->conn->error;
238            if ($this->debug) {
239                # FIXME: These need to hook into the debugging class
240                #printf("MYSQL: %s\n", $this->m_error);
241            }
242        }
243        # Stop and aggregate the query time results
244        $time_end                                = list($em, $es) = explode(' ', microtime());
245        $this->benchmark                        += ($em + $es) - ($sm + $ss);
246
247        # Save individual query times for profiler
248        if ($this->debug) {
249            $this->query_times[]                = $this->benchmark;
250        }
251
252        # Increment the query counter
253        $this->query_count++;
254    }
255
256    # Enable or disable autocommit within our queries
257    public function autocommit($auto_commit=True) {
258        $this->auto_commit                        = $auto_commit;
259        $this->conn->autocommit($this->auto_commit);
260    }
261
262    # Commit a transaction
263    public function commit() {
264        return $this->conn->commit();
265    }
266
267    # Rollback the queries created from when auto_commit was turned off
268    public function rollback() {
269        return $this->conn->rollback();
270    }
271
272    # Fetch the last inserted id
273    public function insert_id() {
274        return $this->conn->insert_id();
275    }
276
277    # Check the elapsed time for this session
278    public function elapsed_time($decimals = 6) {
279        return number_format($this->benchmark, $decimals);
280    }
281
282    # Return the total number of queries this session
283    public function total_queries() {
284        return $this->query_count;
285    }
286
287    # Return the last query executed
288    public function last_query() {
289        return end($this->queries);
290    }
291
292    # Fetch the database stats and return them as key/value pares
293    public function get_stats() {
294        $stats                                    = $this->conn->stat();
295        $stat_vals                                = split('  ', $stats);
296        # Create an array to store results in
297        $return_vals                            = array();
298        foreach ($stat_vals as $stat_val) {
299            list($key, $value)                    = split(': ', $stat_val);
300            $return_vals[$key]                    = $value;
301        }
302        return $return_vals;
303    }
304}