]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - includes/class-mysql.php
Fix end of line
[Github/YOURLS.git] / includes / class-mysql.php
1 <?php
2
3 /**********************************************************************
4 *  Author: Justin Vincent (jv@vip.ie)
5 *  Web...: http://justinvincent.com
6 *  Name..: ezSQL
7 *  Desc..: ezSQL Core module - database abstraction library to make
8 *          it very easy to deal with databases. ezSQLcore can not be used by 
9 *          itself (it is designed for use by database specific modules).
10 *
11 */
12
13 /**********************************************************************
14 *  ezSQL Constants
15 */
16
17 define('EZSQL_VERSION','2.17');
18 define('OBJECT','OBJECT',true);
19 define('ARRAY_A','ARRAY_A',true);
20 define('ARRAY_N','ARRAY_N',true);
21
22 /**********************************************************************
23 *  Core class containg common functions to manipulate query result
24 *  sets once returned
25 */
26
27 class ezSQLcore
28 {
29
30         var $trace            = false;  // same as $debug_all
31         var $debug_all        = false;  // same as $trace
32         var $debug_called     = false;
33         var $vardump_called   = false;
34         var $show_errors      = true;
35         var $num_queries      = 0;
36         var $last_query       = null;
37         var $last_error       = null;
38         var $col_info         = null;
39         var $captured_errors  = array();
40         var $cache_dir        = false;
41         var $cache_queries    = false;
42         var $cache_inserts    = false;
43         var $use_disk_cache   = false;
44         var $cache_timeout    = 24; // hours
45         var $timers           = array();
46         var $total_query_time = 0;
47         var $db_connect_time  = 0;
48         var $trace_log        = array();
49         var $use_trace_log    = false;
50         var $sql_log_file     = false;
51         var $do_profile       = false;
52         var $profile_times    = array();
53         var $all_queries      = '';
54
55         // == TJH == default now needed for echo of debug function
56         var $debug_echo_is_on = true;
57
58         /**********************************************************************
59         *  Constructor
60         */
61
62         function ezSQLcore()
63         {
64         }
65
66         /**********************************************************************
67         *  Print SQL/DB error - over-ridden by specific DB class
68         */
69
70         function register_error($err_str)
71         {
72                 // Keep track of last error
73                 $this->last_error = $err_str;
74
75                 // Capture all errors to an error array no matter what happens
76                 $this->captured_errors[] = array
77                 (
78                         'error_str' => $err_str,
79                         'query'     => $this->last_query
80                 );
81         }
82
83         /**********************************************************************
84         *  Turn error handling on or off..
85         */
86
87         function show_errors()
88         {
89                 $this->show_errors = true;
90         }
91
92         function hide_errors()
93         {
94                 $this->show_errors = false;
95         }
96
97         /**********************************************************************
98         *  Kill cached query results
99         */
100
101         function flush()
102         {
103                 // Get rid of these
104                 $this->last_result = null;
105                 $this->col_info = null;
106                 $this->last_query = null;
107                 $this->from_disk_cache = false;
108         }
109
110         /**********************************************************************
111         *  Get one variable from the DB - see docs for more detail
112         */
113
114         function get_var($query=null,$x=0,$y=0)
115         {
116
117                 // Log how the function was called
118                 $this->func_call = "\$db->get_var(\"$query\",$x,$y)";
119
120                 // If there is a query then perform it if not then use cached results..
121                 if ( $query )
122                 {
123                         $this->query($query);
124                 }
125
126                 // Extract var out of cached results based x,y vals
127                 if ( $this->last_result[$y] )
128                 {
129                         $values = array_values(get_object_vars($this->last_result[$y]));
130                 }
131
132                 // If there is a value return it else return null
133                 return (isset($values[$x]) && $values[$x]!=='')?$values[$x]:null;
134         }
135
136         /**********************************************************************
137         *  Get one row from the DB - see docs for more detail
138         */
139
140         function get_row($query=null,$output=OBJECT,$y=0)
141         {
142
143                 // Log how the function was called
144                 $this->func_call = "\$db->get_row(\"$query\",$output,$y)";
145
146                 // If there is a query then perform it if not then use cached results..
147                 if ( $query )
148                 {
149                         $this->query($query);
150                 }
151
152                 // If the output is an object then return object using the row offset..
153                 if ( $output == OBJECT )
154                 {
155                         return $this->last_result[$y]?$this->last_result[$y]:null;
156                 }
157                 // If the output is an associative array then return row as such..
158                 elseif ( $output == ARRAY_A )
159                 {
160                         return $this->last_result[$y]?get_object_vars($this->last_result[$y]):null;
161                 }
162                 // If the output is an numerical array then return row as such..
163                 elseif ( $output == ARRAY_N )
164                 {
165                         return $this->last_result[$y]?array_values(get_object_vars($this->last_result[$y])):null;
166                 }
167                 // If invalid output type was specified..
168                 else
169                 {
170                         $this->show_errors ? trigger_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N",E_USER_WARNING) : null;
171                 }
172
173         }
174
175         /**********************************************************************
176         *  Function to get 1 column from the cached result set based in X index
177         *  see docs for usage and info
178         */
179
180         function get_col($query=null,$x=0)
181         {
182
183                 $new_array = array();
184
185                 // If there is a query then perform it if not then use cached results..
186                 if ( $query )
187                 {
188                         $this->query($query);
189                 }
190
191                 // Extract the column values
192                 for ( $i=0; $i < count($this->last_result); $i++ )
193                 {
194                         $new_array[$i] = $this->get_var(null,$x,$i);
195                 }
196
197                 return $new_array;
198         }
199
200
201         /**********************************************************************
202         *  Return the the query as a result set - see docs for more details
203         */
204
205         function get_results($query=null, $output = OBJECT)
206         {
207
208                 // Log how the function was called
209                 $this->func_call = "\$db->get_results(\"$query\", $output)";
210
211                 // If there is a query then perform it if not then use cached results..
212                 if ( $query )
213                 {
214                         $this->query($query);
215                 }
216
217                 // Send back array of objects. Each row is an object
218                 if ( $output == OBJECT )
219                 {
220                         return $this->last_result;
221                 }
222                 elseif ( $output == ARRAY_A || $output == ARRAY_N )
223                 {
224                         if ( $this->last_result )
225                         {
226                                 $i=0;
227                                 foreach( $this->last_result as $row )
228                                 {
229
230                                         $new_array[$i] = get_object_vars($row);
231
232                                         if ( $output == ARRAY_N )
233                                         {
234                                                 $new_array[$i] = array_values($new_array[$i]);
235                                         }
236
237                                         $i++;
238                                 }
239
240                                 return $new_array;
241                         }
242                         else
243                         {
244                                 return null;
245                         }
246                 }
247         }
248
249
250         /**********************************************************************
251         *  Function to get column meta data info pertaining to the last query
252         * see docs for more info and usage
253         */
254
255         function get_col_info($info_type="name",$col_offset=-1)
256         {
257
258                 if ( $this->col_info )
259                 {
260                         if ( $col_offset == -1 )
261                         {
262                                 $i=0;
263                                 foreach($this->col_info as $col )
264                                 {
265                                         $new_array[$i] = $col->{$info_type};
266                                         $i++;
267                                 }
268                                 return $new_array;
269                         }
270                         else
271                         {
272                                 return $this->col_info[$col_offset]->{$info_type};
273                         }
274
275                 }
276
277         }
278
279         /**********************************************************************
280         *  store_cache
281         */
282
283         function store_cache($query,$is_insert)
284         {
285
286                 // The would be cache file for this query
287                 $cache_file = $this->cache_dir.'/'.md5($query);
288
289                 // disk caching of queries
290                 if ( $this->use_disk_cache && ( $this->cache_queries && ! $is_insert ) || ( $this->cache_inserts && $is_insert ))
291                 {
292                         if ( ! is_dir($this->cache_dir) )
293                         {
294                                 $this->register_error("Could not open cache dir: $this->cache_dir");
295                                 $this->show_errors ? trigger_error("Could not open cache dir: $this->cache_dir",E_USER_WARNING) : null;
296                         }
297                         else
298                         {
299                                 // Cache all result values
300                                 $result_cache = array
301                                 (
302                                         'col_info' => $this->col_info,
303                                         'last_result' => $this->last_result,
304                                         'num_rows' => $this->num_rows,
305                                         'return_value' => $this->num_rows,
306                                 );
307                                 file_put_contents($cache_file, serialize($result_cache));
308                                 if( file_exists($cache_file . ".updating") )
309                                         unlink($cache_file . ".updating");
310                         }
311                 }
312
313         }
314
315         /**********************************************************************
316         *  get_cache
317         */
318
319         function get_cache($query)
320         {
321
322                 // The would be cache file for this query
323                 $cache_file = $this->cache_dir.'/'.md5($query);
324
325                 // Try to get previously cached version
326                 if ( $this->use_disk_cache && file_exists($cache_file) )
327                 {
328                         // Only use this cache file if less than 'cache_timeout' (hours)
329                         if ( (time() - filemtime($cache_file)) > ($this->cache_timeout*3600) && 
330                                 !(file_exists($cache_file . ".updating") && (time() - filemtime($cache_file . ".updating") < 60)) ) 
331                         {
332                                 touch($cache_file . ".updating"); // Show that we in the process of updating the cache
333                         }
334                         else
335                         {
336                                 $result_cache = unserialize(file_get_contents($cache_file));
337
338                                 $this->col_info = $result_cache['col_info'];
339                                 $this->last_result = $result_cache['last_result'];
340                                 $this->num_rows = $result_cache['num_rows'];
341
342                                 $this->from_disk_cache = true;
343
344                                 // If debug ALL queries
345                                 $this->trace || $this->debug_all ? $this->debug() : null ;
346
347                                 return $result_cache['return_value'];
348                         }
349                 }
350
351         }
352
353         /**********************************************************************
354         *  Dumps the contents of any input variable to screen in a nicely
355         *  formatted and easy to understand way - any type: Object, Var or Array
356         */
357
358         function vardump($mixed='')
359         {
360
361                 // Start outup buffering
362                 ob_start();
363
364                 echo "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>";
365                 echo "<pre><font face=arial>";
366
367                 if ( ! $this->vardump_called )
368                 {
369                         echo "<font color=800080><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Variable Dump..</b></font>\n\n";
370                 }
371
372                 $var_type = gettype ($mixed);
373                 print_r(($mixed?$mixed:"<font color=red>No Value / False</font>"));
374                 echo "\n\n<b>Type:</b> " . ucfirst($var_type) . "\n";
375                 echo "<b>Last Query</b> [$this->num_queries]<b>:</b> ".($this->last_query?$this->last_query:"NULL")."\n";
376                 echo "<b>Last Function Call:</b> " . ($this->func_call?$this->func_call:"None")."\n";
377                 echo "<b>Last Rows Returned:</b> ".count($this->last_result)."\n";
378                 echo "</font></pre></font></blockquote></td></tr></table>".$this->donation();
379                 echo "\n<hr size=1 noshade color=dddddd>";
380
381                 // Stop output buffering and capture debug HTML
382                 $html = ob_get_contents();
383                 ob_end_clean();
384
385                 // Only echo output if it is turned on
386                 if ( $this->debug_echo_is_on )
387                 {
388                         echo $html;
389                 }
390
391                 $this->vardump_called = true;
392
393                 return $html;
394
395         }
396
397         /**********************************************************************
398         *  Alias for the above function
399         */
400
401         function dumpvar($mixed)
402         {
403                 $this->vardump($mixed);
404         }
405
406         /**********************************************************************
407         *  Displays the last query string that was sent to the database & a
408         * table listing results (if there were any).
409         * (abstracted into a seperate file to save server overhead).
410         */
411
412         function debug($print_to_screen=true)
413         {
414
415                 // Start outup buffering
416                 ob_start();
417
418                 echo "<blockquote>";
419
420                 // Only show ezSQL credits once..
421                 if ( ! $this->debug_called )
422                 {
423                         echo "<font color=800080 face=arial size=2><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Debug..</b></font><p>\n";
424                 }
425
426                 if ( $this->last_error )
427                 {
428                         echo "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>";
429                 }
430
431                 if ( $this->from_disk_cache )
432                 {
433                         echo "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>";
434                 }
435
436                 echo "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> ";
437                 echo "[<font color=000000><b>$this->last_query</b></font>]</font><p>";
438
439                         echo "<font face=arial size=2 color=000099><b>Query Result..</b></font>";
440                         echo "<blockquote>";
441
442                 if ( $this->col_info )
443                 {
444
445                         // =====================================================
446                         // Results top rows
447
448                         echo "<table cellpadding=5 cellspacing=1 bgcolor=555555>";
449                         echo "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>";
450
451
452                         for ( $i=0; $i < count($this->col_info); $i++ )
453                         {
454                                 echo "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type} {$this->col_info[$i]->max_length}</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>";
455                         }
456
457                         echo "</tr>";
458
459                         // ======================================================
460                         // print main results
461
462                 if ( $this->last_result )
463                 {
464
465                         $i=0;
466                         foreach ( $this->get_results(null,ARRAY_N) as $one_row )
467                         {
468                                 $i++;
469                                 echo "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>";
470
471                                 foreach ( $one_row as $item )
472                                 {
473                                         echo "<td nowrap><font face=arial size=2>$item</font></td>";
474                                 }
475
476                                 echo "</tr>";
477                         }
478
479                 } // if last result
480                 else
481                 {
482                         echo "<tr bgcolor=ffffff><td colspan=".(count($this->col_info)+1)."><font face=arial size=2>No Results</font></td></tr>";
483                 }
484
485                 echo "</table>";
486
487                 } // if col_info
488                 else
489                 {
490                         echo "<font face=arial size=2>No Results</font>";
491                 }
492
493                 echo "</blockquote></blockquote>".$this->donation()."<hr noshade color=dddddd size=1>";
494
495                 // Stop output buffering and capture debug HTML
496                 $html = ob_get_contents();
497                 ob_end_clean();
498
499                 // Only echo output if it is turned on
500                 if ( $this->debug_echo_is_on && $print_to_screen)
501                 {
502                         echo $html;
503                 }
504
505                 $this->debug_called = true;
506
507                 return $html;
508
509         }
510
511         /**********************************************************************
512         *  Naughty little function to ask for some remuniration!
513         */
514
515         function donation()
516         {
517                 return "<font size=1 face=arial color=000000>If ezSQL has helped <a href=\"https://www.paypal.com/xclick/business=justin%40justinvincent.com&item_name=ezSQL&no_note=1&tax=0\" style=\"color: 0000CC;\">make a donation!?</a> &nbsp;&nbsp;<!--[ go on! you know you want to! ]--></font>";
518         }
519
520         /**********************************************************************
521         *  Timer related functions
522         */
523
524         function timer_get_cur()
525         {
526                 list($usec, $sec) = explode(" ",microtime());
527                 return ((float)$usec + (float)$sec);
528         }
529
530         function timer_start($timer_name)
531         {
532                 $this->timers[$timer_name] = $this->timer_get_cur();
533         }
534
535         function timer_elapsed($timer_name)
536         {
537                 return round($this->timer_get_cur() - $this->timers[$timer_name],2);
538         }
539
540         function timer_update_global($timer_name)
541         {
542                 if ( $this->do_profile )
543                 {
544                         $this->profile_times[] = array
545                         (
546                                 'query' => $this->last_query,
547                                 'time' => $this->timer_elapsed($timer_name)
548                         );
549                 }
550                 
551                 $this->total_query_time += $this->timer_elapsed($timer_name);
552         }
553
554         /**********************************************************************
555         * Creates a SET nvp sql string from an associative array (and escapes all values)
556         *
557         *  Usage:
558         *
559         *     $db_data = array('login'=>'jv','email'=>'jv@vip.ie', 'user_id' => 1, 'created' => 'NOW()');
560         *
561         *     $db->query("INSERT INTO users SET ".$db->get_set($db_data));
562         *
563         *     ...OR...
564         *
565         *     $db->query("UPDATE users SET ".$db->get_set($db_data)." WHERE user_id = 1");
566         *
567         * Output:
568         *
569         *     login = 'jv', email = 'jv@vip.ie', user_id = 1, created = NOW()
570         */
571
572         function get_set($parms)
573         {               
574                 $sql = '';
575                 foreach ( $parms as $field => $val )
576                 {
577                         if ( $val === 'true' ) $val = 1;
578                         if ( $val === 'false' ) $val = 0;
579                 
580                         if ( $val == 'NOW()' )
581                         {
582                                 $sql .= "$field = ".$this->escape($val).", ";
583                         }
584                         else
585                         {
586                                 $sql .= "$field = '".$this->escape($val)."', ";
587                         }
588                 }
589         
590                 return substr($sql,0,-2);
591         }
592
593 }
594
595
596 /**********************************************************************
597 *  Author: Justin Vincent (jv@jvmultimedia.com)
598 *  Web...: http://twitter.com/justinvincent
599 *  Name..: ezSQL_mysql
600 *  Desc..: mySQL component (part of ezSQL databse abstraction library)
601 *
602 */
603
604 /**********************************************************************
605 *  ezSQL error strings - mySQL
606 */
607
608 $ezsql_mysql_str = array
609 (
610         1 => 'Require $dbuser and $dbpassword to connect to a database server',
611         2 => 'Error establishing mySQL database connection. Correct user/password? Correct hostname? Database server running?',
612         3 => 'Require $dbname to select a database',
613         4 => 'mySQL database connection is not active',
614         5 => 'Unexpected error while trying to select database'
615 );
616
617 /**********************************************************************
618 *  ezSQL Database specific class - mySQL
619 */
620
621 if ( ! function_exists ('mysql_connect') ) die('<b>Fatal Error:</b> ezSQL_mysql requires mySQL Lib to be compiled and or linked in to the PHP engine');
622 if ( ! class_exists ('ezSQLcore') ) die('<b>Fatal Error:</b> ezSQL_mysql requires ezSQLcore (ez_sql_core.php) to be included/loaded before it can be used');
623
624 class ezSQL_mysql extends ezSQLcore
625 {
626
627         var $dbuser = false;
628         var $dbpassword = false;
629         var $dbname = false;
630         var $dbhost = false;
631         var $encoding = false;
632
633         /**********************************************************************
634         *  Constructor - allow the user to perform a qucik connect at the
635         *  same time as initialising the ezSQL_mysql class
636         */
637
638         function ezSQL_mysql($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $encoding='')
639         {
640                 $this->dbuser = $dbuser;
641                 $this->dbpassword = $dbpassword;
642                 $this->dbname = $dbname;
643                 $this->dbhost = $dbhost;
644                 $this->encoding = $encoding;
645         }
646
647         /**********************************************************************
648         *  Short hand way to connect to mySQL database server
649         *  and select a mySQL database at the same time
650         */
651
652         function quick_connect($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $encoding='')
653         {
654                 $return_val = false;
655                 if ( ! $this->connect($dbuser, $dbpassword, $dbhost,true) ) ;
656                 else if ( ! $this->select($dbname,$encoding) ) ;
657                 else $return_val = true;
658                 return $return_val;
659         }
660
661         /**********************************************************************
662         *  Try to connect to mySQL database server
663         */
664
665         function connect($dbuser='', $dbpassword='', $dbhost='localhost')
666         {
667                 global $ezsql_mysql_str; $return_val = false;
668                 
669                 // Keep track of how long the DB takes to connect
670                 $this->timer_start('db_connect_time');
671
672                 // Must have a user and a password
673                 if ( ! $dbuser )
674                 {
675                         $this->register_error($ezsql_mysql_str[1].' in '.__FILE__.' on line '.__LINE__);
676                         $this->show_errors ? trigger_error($ezsql_mysql_str[1],E_USER_WARNING) : null;
677                 }
678                 // Try to establish the server database handle
679                 else if ( ! $this->dbh = @mysql_connect($dbhost,$dbuser,$dbpassword,true,131074) )
680                 {
681                         $this->register_error($ezsql_mysql_str[2].' in '.__FILE__.' on line '.__LINE__);
682                         $this->show_errors ? trigger_error($ezsql_mysql_str[2],E_USER_WARNING) : null;
683                 }
684                 else
685                 {
686                         $this->dbuser = $dbuser;
687                         $this->dbpassword = $dbpassword;
688                         $this->dbhost = $dbhost;
689                         $return_val = true;
690                 }
691
692                 return $return_val;
693         }
694
695         /**********************************************************************
696         *  Try to select a mySQL database
697         */
698
699         function select($dbname='', $encoding='')
700         {
701                 global $ezsql_mysql_str; $return_val = false;
702
703                 // Must have a database name
704                 if ( ! $dbname )
705                 {
706                         $this->register_error($ezsql_mysql_str[3].' in '.__FILE__.' on line '.__LINE__);
707                         $this->show_errors ? trigger_error($ezsql_mysql_str[3],E_USER_WARNING) : null;
708                 }
709
710                 // Must have an active database connection
711                 else if ( ! $this->dbh )
712                 {
713                         $this->register_error($ezsql_mysql_str[4].' in '.__FILE__.' on line '.__LINE__);
714                         $this->show_errors ? trigger_error($ezsql_mysql_str[4],E_USER_WARNING) : null;
715                 }
716
717                 // Try to connect to the database
718                 else if ( !@mysql_select_db($dbname,$this->dbh) )
719                 {
720                         // Try to get error supplied by mysql if not use our own
721                         if ( !$str = @mysql_error($this->dbh))
722                                   $str = $ezsql_mysql_str[5];
723
724                         $this->register_error($str.' in '.__FILE__.' on line '.__LINE__);
725                         $this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
726                 }
727                 else
728                 {
729                         $this->dbname = $dbname;
730                         if($encoding!='')
731                         {
732                                 $encoding = strtolower(str_replace("-","",$encoding));
733                                 $charsets = array();
734                                 $result = mysql_query("SHOW CHARACTER SET");
735                                 while($row = mysql_fetch_array($result,MYSQL_ASSOC))
736                                 {
737                                         $charsets[] = $row["Charset"];
738                                 }
739                                 if(in_array($encoding,$charsets)){
740                                         mysql_query("SET NAMES '".$encoding."'");                                               
741                                 }
742                         }
743                         
744                         $return_val = true;
745                 }
746
747                 return $return_val;
748         }
749
750         /**********************************************************************
751         *  Format a mySQL string correctly for safe mySQL insert
752         *  (no mater if magic quotes are on or not)
753         */
754
755         function escape($str)
756         {
757                 // If there is no existing database connection then try to connect
758                 if ( ! isset($this->dbh) || ! $this->dbh )
759                 {
760                         $this->connect($this->dbuser, $this->dbpassword, $this->dbhost);
761                         $this->select($this->dbname, $this->encoding);
762                 }
763
764                 return mysql_real_escape_string(stripslashes($str));
765         }
766
767         /**********************************************************************
768         *  Return mySQL specific system date syntax
769         *  i.e. Oracle: SYSDATE Mysql: NOW()
770         */
771
772         function sysdate()
773         {
774                 return 'NOW()';
775         }
776
777         /**********************************************************************
778         *  Perform mySQL query and try to detirmin result value
779         */
780
781         function query($query)
782         {
783
784                 // This keeps the connection alive for very long running scripts
785                 if ( $this->num_queries >= 500 )
786                 {
787                         $this->disconnect();
788                         $this->quick_connect($this->dbuser,$this->dbpassword,$this->dbname,$this->dbhost,$this->encoding);
789                 }
790
791                 // Initialise return
792                 $return_val = 0;
793
794                 // Flush cached values..
795                 $this->flush();
796
797                 // For reg expressions
798                 $query = trim($query);
799
800                 // Log how the function was called
801                 $this->func_call = "\$db->query(\"$query\")";
802
803                 // Keep track of the last query for debug..
804                 $this->last_query = $query;
805
806                 // Count how many queries there have been
807                 $this->num_queries++;
808                 
809                 // Keep history of all queries
810                 $this->all_queries .= $query.'<br />';
811                 
812                 // Start timer
813                 $this->timer_start($this->num_queries);
814
815                 // Use core file cache function
816                 if ( $cache = $this->get_cache($query) )
817                 {
818                         // Keep tack of how long all queries have taken
819                         $this->timer_update_global($this->num_queries);
820
821                         // Trace all queries
822                         if ( $this->use_trace_log )
823                         {
824                                 $this->trace_log[] = $this->debug(false);
825                         }
826                         
827                         return $cache;
828                 }
829
830                 // If there is no existing database connection then try to connect
831                 if ( ! isset($this->dbh) || ! $this->dbh )
832                 {
833                         $this->connect($this->dbuser, $this->dbpassword, $this->dbhost);
834                         $this->select($this->dbname,$this->encoding);
835                 }
836
837                 // Perform the query via std mysql_query function..
838                 $this->result = @mysql_query($query,$this->dbh);
839
840                 // If there is an error then take note of it..
841                 if ( $str = @mysql_error($this->dbh) )
842                 {
843                         $is_insert = true;
844                         $this->register_error($str);
845                         $this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
846                         return false;
847                 }
848
849                 // Query was an insert, delete, update, replace
850                 $is_insert = false;
851                 if ( preg_match("/^(insert|delete|update|replace|truncate|drop|create|alter)\s+/i",$query) )
852                 {
853                         $this->rows_affected = @mysql_affected_rows($this->dbh);
854
855                         // Take note of the insert_id
856                         if ( preg_match("/^(insert|replace)\s+/i",$query) )
857                         {
858                                 $this->insert_id = @mysql_insert_id($this->dbh);
859                         }
860
861                         // Return number fo rows affected
862                         $return_val = $this->rows_affected;
863                 }
864                 // Query was a select
865                 else
866                 {
867
868                         // Take note of column info
869                         $i=0;
870                         while ($i < @mysql_num_fields($this->result))
871                         {
872                                 $this->col_info[$i] = @mysql_fetch_field($this->result);
873                                 $i++;
874                         }
875
876                         // Store Query Results
877                         $num_rows=0;
878                         while ( $row = @mysql_fetch_object($this->result) )
879                         {
880                                 // Store relults as an objects within main array
881                                 $this->last_result[$num_rows] = $row;
882                                 $num_rows++;
883                         }
884
885                         @mysql_free_result($this->result);
886
887                         // Log number of rows the query returned
888                         $this->num_rows = $num_rows;
889
890                         // Return number of rows selected
891                         $return_val = $this->num_rows;
892                 }
893
894                 // disk caching of queries
895                 $this->store_cache($query,$is_insert);
896
897                 // If debug ALL queries
898                 $this->trace || $this->debug_all ? $this->debug() : null ;
899
900                 // Keep tack of how long all queries have taken
901                 $this->timer_update_global($this->num_queries);
902
903                 // Trace all queries
904                 if ( $this->use_trace_log )
905                 {
906                         $this->trace_log[] = $this->debug(false);
907                 }
908
909                 return $return_val;
910
911         }
912         
913         /**********************************************************************
914         *  Close the active mySQL connection
915         */
916
917         function disconnect()
918         {
919                 @mysql_close($this->dbh);       
920         }
921
922         function mysql_version() {
923                 return  mysql_get_server_info( $this->dbh ) ;
924         }
925 }