b2evolution

Multilingual multiuser multiblog engine

b2evolution Technical Documentation (0.9.x) [ class tree: evocore ] [ index: evocore ] [ all elements ]

Source for file _class_db.php

Documentation is available at _class_db.php

  1. <?php
  2. /**
  3.  * This file implements the DB class.
  4.  *
  5.  * Based on ezSQL - Class to make it very easy to deal with MySQL database connections.
  6.  * b2evo Additions:
  7.  * - nested transactions
  8.  * - symbolic table names
  9.  * - query log
  10.  * - get_list
  11.  * - dynamic extension loading
  12.  * - Debug features (EXPLAIN...)
  13.  * and more...
  14.  *
  15.  * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
  16.  * See also {@link http://sourceforge.net/projects/evocms/}.
  17.  *
  18.  * @copyright (c)2003-2005 by Francois PLANQUE - {@link http://fplanque.net/}.
  19.  *  Parts of this file are copyright (c)2004 by Justin Vincent - {@link http://php.justinvincent.com}
  20.  *  Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}.
  21.  *
  22.  * @license http://b2evolution.net/about/license.html GNU General Public License (GPL)
  23.  *  {@internal 
  24.  *  b2evolution is free software; you can redistribute it and/or modify
  25.  *  it under the terms of the GNU General Public License as published by
  26.  *  the Free Software Foundation; either version 2 of the License, or
  27.  *  (at your option) any later version.
  28.  *
  29.  *  b2evolution is distributed in the hope that it will be useful,
  30.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  31.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  32.  *  GNU General Public License for more details.
  33.  *
  34.  *  You should have received a copy of the GNU General Public License
  35.  *  along with b2evolution; if not, write to the Free Software
  36.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  37.  *  }}}
  38.  *
  39.  *  {@internal 
  40.  *  This file is based on the following package (excerpt from ezSQL's readme.txt):
  41.  *  =======================================================================
  42.  *  Author:  Justin Vincent (justin@visunet.ie)
  43.  *  Web:      http://php.justinvincent.com
  44.  *  Name:      ezSQL
  45.  *  Desc:      Class to make it very easy to deal with database connections.
  46.  *  License: FREE / Donation (LGPL - You may do what you like with ezSQL - no exceptions.)
  47.  *  =======================================================================
  48.  *  A $10 donation has been made to Justin VINCENT on behalf of the b2evolution team.
  49.  *  The package has been relicensed as GPL based on
  50.  *  "You may do what you like with ezSQL - no exceptions."
  51.  *  2004-10-14 (email): Justin VINCENT grants François PLANQUE the right to relicense
  52.  *  this modified class under other licenses. "Just include a link to where you got it from."
  53.  *  }}}
  54.  *
  55.  *  {@internal 
  56.  *  Daniel HAHLER grants François PLANQUE the right to license
  57.  *  Daniel HAHLER's contributions to this file and the b2evolution project
  58.  *  under any OSI approved OSS license (http://www.opensource.org/licenses/).
  59.  *  }}}
  60.  *
  61.  * @package evocore
  62.  *
  63.  *  {@internal Below is a list of authors who have contributed to design/coding of this file: }}
  64.  * @author blueyed: Daniel HAHLER
  65.  * @author fplanque: François PLANQUE
  66.  * @author Justin VINCENT
  67.  *
  68.  * @version $Id: _class_db.php,v 1.11.2.9 2005/09/02 21:31:34 fplanque Exp $
  69.  * @todo transaction support
  70.  */
  71. if!defined('DB_USER') ) die'Please, do not access this page directly.' );
  72.  
  73. /**
  74.  * ezSQL Constants
  75.  */
  76. define'EZSQL_VERSION''1.25' );
  77. define'OBJECT''OBJECT'true );
  78. define'ARRAY_A''ARRAY_A'true);
  79. define'ARRAY_N''ARRAY_N'true);
  80.  
  81. iffunction_exists'mysql_real_escape_string' ) )
  82. // Function only available since PHP 4.3.0
  83.     function mysql_real_escape_string$unescaped_string 
  84.     {
  85.         return mysql_escape_string$unescaped_string )
  86.     }
  87. }
  88.  
  89. /**
  90.  * The Main Class
  91.  *
  92.  * @package evocore
  93.  */
  94. class DB
  95. {
  96.     /**
  97.      * Do we want to explain joins?
  98.      */
  99.     var $debug_explain_joins = false;
  100.  
  101.   /**
  102.      * Number of rows we want to dump in debug output:
  103.      */
  104.     var $debug_dump_rows = 0;
  105.  
  106.     var $show_errors = true;
  107.     var $halt_on_error = true;
  108.     var $error = false;        // no error yet
  109.     var $num_queries = 0;
  110.     var $last_query = '';        // last query SQL string
  111.     var $last_error = '';            // last DB error string
  112.     var $col_info;
  113.  
  114.     var $vardump_called;
  115.     var $insert_id = 0;
  116.     var $num_rows = 0;
  117.     var $rows_affected = 0;
  118.     var $last_result;
  119.     /**
  120.      * Log of queries:
  121.      */
  122.     var $queries = array();
  123.     /**
  124.      * Aliases that will be replaced in queries:
  125.      */
  126.     var $dbaliases = array();
  127.     /**
  128.      * Strings that will replace the aliases in queries:
  129.      */
  130.     var $dbreplaces = array();
  131.  
  132.     /**
  133.      * CREATE TABLE options.
  134.      */
  135.     var $dbtableoptions;
  136.  
  137.     /**
  138.      * Do we want to use transactions:
  139.      */
  140.     var $use_transactions;
  141.  
  142.     /**
  143.      * How many transactions are currently nested?
  144.      */
  145.     var $transaction_nesting_level = 0;
  146.  
  147.     /**
  148.      * Rememeber if we have to rollback at the end of a nested transaction construct
  149.      */
  150.     var $rollback_nested_transaction = false;
  151.  
  152.  
  153.     /**
  154.      * DB Constructor
  155.      *
  156.      * connects to the server and selects a database
  157.      *
  158.      * blueyed> Note: Too many parameters (and without default). Should be accessed through members. $halt_on_error is relevant to the connect procedure and should be put after $dbhost.
  159.      */
  160.     function DB$dbuser$dbpassword$dbname$dbhost$dbaliases$halt_on_error true$db_use_transactions false$dbtableoptions '' )
  161.     {
  162.         $this->halt_on_error = $halt_on_error;
  163.  
  164.         if!extension_loaded('mysql') )
  165.         {    // The mysql extension is not loaded, try to dynamically load it:
  166.             if (strtoupper(substr(PHP_OS03== 'WIN'))
  167.             {
  168.                 @dl('php_mysql.dll');
  169.             }
  170.             else
  171.             {
  172.                 @dl('mysql.so');
  173.             }
  174.  
  175.             if!extension_loaded('mysql') )
  176.             // Still not loaded:
  177.                 $this->print_error'<p><strong>The PHP MySQL module could not be loaded.</strong></p>
  178.                     <p>You must edit your php configuration (php.ini) and enable this module.</p>
  179.                     <p>Do not forget to restart your webserver (if necessary) after editing the PHP conf.</p>' );
  180.                 return;
  181.             }
  182.         }
  183.  
  184.         // Connect to the Database:
  185.         $this->dbh @mysql_connect($dbhost,$dbuser,$dbpassword);
  186.  
  187.         if$this->dbh )
  188.         {
  189.             $this->print_error'<p><strong>Error establishing a database connection!</strong></p>
  190.                 <p>('.mysql_error().')</p>
  191.                 <ol>
  192.                     <li>Are you sure you have typed the correct user/password?</li>
  193.                     <li>Are you sure that you have typed the correct hostname?</li>
  194.                     <li>Are you sure that the database server is running?</li>
  195.                 </ol>' );
  196.         }
  197.         else
  198.         {
  199.             $this->select($dbname);
  200.         }
  201.  
  202.         // Prepare aliases for replacements:
  203.         foreach$dbaliases as $dbalias => $dbreplace )
  204.         {
  205.             $this->dbaliases['#\b'.$dbalias.'\b#'// \b = word boundary
  206.             $this->dbreplaces[$dbreplace;
  207.             // echo '<br />'.'#\b'.$dbalias.'\b#';
  208.         }
  209.         // echo count($this->dbaliases);
  210.  
  211.         $this->use_transactions = $db_use_transactions;
  212.         $this->dbtableoptions = $dbtableoptions;
  213.     }
  214.  
  215.  
  216.     /**
  217.      * Select a DB (if another one needs to be selected)
  218.      */
  219.     function select($db)
  220.     {
  221.         if !@mysql_select_db($db,$this->dbh))
  222.         {
  223.             $this->print_error'<strong>Error selecting database ['.$db.']!</strong>
  224.                 <ol>
  225.                     <li>Are you sure the database exists?</li>
  226.                     <li>Are you sure there is a valid database connection?</li>
  227.                 </ol>' );
  228.         }
  229.     }
  230.  
  231.  
  232.     /**
  233.      * Format a string correctly for safe insert under all PHP conditions
  234.      */
  235.     function escape($str)
  236.     {
  237.         return mysql_real_escape_string($str);                
  238.     }
  239.  
  240.  
  241.     function quote($str)
  242.     {
  243.         if$str === NULL )
  244.             return 'NULL';
  245.         else
  246.             return "'".mysql_real_escape_string($str)."'";                
  247.     }
  248.  
  249.  
  250.     function null($val)
  251.     {
  252.         if$val === NULL )
  253.             return 'NULL';
  254.         else
  255.             return $val;                
  256.     }
  257.  
  258.  
  259.     /**
  260.      * Returns the correct WEEK() function to get the week number for the given date.
  261.      *
  262.      * {@see http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html}
  263.      *
  264.      * @todo disable when MySQL < 4
  265.      * @param string will be used as is
  266.      * @param integer 0 for sunday, 1 for monday
  267.      */
  268.     function week$date$startofweek )
  269.     {
  270.         if$startofweek == )
  271.         {    // Week starts on Monday:
  272.             return ' WEEK( '.$date.', 5 ) ';
  273.         }
  274.  
  275.         // Week starts on Sunday:
  276.         return ' WEEK( '.$date.', 0 ) ';
  277.     }
  278.  
  279.     /**
  280.      * Returns the appropriate string to compare $val in a WHERE clause.
  281.      *
  282.      * @param mixed Value to create a "compare-String" for
  283.      * @return string Either 'IS NULL', 'IN ("a", "b", "c")' or " = 'a'".
  284.      */
  285.     function compString$val )
  286.     {
  287.         if$val === NULL )
  288.         {
  289.             return 'IS NULL';
  290.         }
  291.         elseifis_array($val) )
  292.         {
  293.             return 'IN ("'.implode('","'$val).'")';
  294.         }
  295.         else
  296.         {
  297.             return " = '$root'";
  298.         }
  299.     }
  300.  
  301.  
  302.     /**
  303.      * Print SQL/DB error.
  304.      */
  305.     function print_error$str ''$query_title '' )
  306.     {
  307.         // All errors go to the global error array $EZSQL_ERROR..
  308.         global $EZSQL_ERROR;
  309.  
  310.         $this->error = true;
  311.  
  312.         // If no special error string then use mysql default..
  313.         $this->last_error = empty($strmysql_error().'(Errno='.mysql_errno().')' $str;
  314.         
  315.         // Log this error to the global array..
  316.         $EZSQL_ERROR[array 
  317.                         (
  318.                             'query' => $this->last_query,
  319.                             'error_str'  => $this->last_error
  320.                         );
  321.  
  322.         // Is error output turned on or not..
  323.         if $this->show_errors )
  324.         {
  325.             // If there is an error then take note of it
  326.             echo '<div class="error">';
  327.             echo '<p class="error">MySQL error!</p>';
  328.             echo '<p>'$this->last_error'</p>';
  329.             if!empty($this->last_query) ) echo '<p class="error">Your query: '.$query_title.'<br /><pre>'.htmlspecialcharsstr_replace("\t"'  '$this->last_query) ).'</pre></p>';
  330.  
  331.             iffunction_exists'xdebug_is_enabled' && xdebug_is_enabled() )
  332.             {
  333.                 ?>
  334.                 <table class="grouped">
  335.                     <thead>
  336.                         <tr>
  337.                             <th>Function / Include</th>
  338.                             <th>File</th>
  339.                             <th>Line</th>
  340.                         </tr>
  341.                     </thead>
  342.  
  343.                 <?php
  344.                 foreachxdebug_get_function_stack(as $lStack )
  345.                 {
  346.                     ?>
  347.                     <tr>
  348.                         <td>
  349.                             <?php
  350.                             ifisset$lStack['include_filename') )
  351.                             {
  352.                                 echo '<strong>=&gt;</strong> '.$lStack['include_filename'];
  353.                             }
  354.                             else
  355.                             {
  356.                                 ifisset$lStack['class') )
  357.                                 {
  358.                                     echo $lStack['class'].'::';
  359.                                 }
  360.                                 echo $lStack['function'].'()';
  361.                             }
  362.                             ?>
  363.                         </td>
  364.                         <td><?php echo $lStack['file'?></td>
  365.                         <td><?php echo $lStack['line'?></td>
  366.                     </tr>
  367.                     <?php
  368.                 }
  369.                 echo '</table>';
  370.             }
  371.  
  372.             echo '</div>';
  373.         }
  374.  
  375.         if$this->halt_on_error die();
  376.     }
  377.  
  378.  
  379.     /**
  380.      * Kill cached query results
  381.      */
  382.     function flush()
  383.     {
  384.         // Get rid of these
  385.         $this->last_result = NULL;
  386.         $this->col_info = NULL;
  387.         $this->last_query = NULL;
  388.         $this->current_idx 0;
  389.     }
  390.  
  391.  
  392.     /** 
  393.      * Basic Query
  394.      *
  395.      * {@internal DB::query(-) }}
  396.      *
  397.      * @param string SQL query
  398.      * @param string title for debugging
  399.      * @return mixed # of rows affected or false if error
  400.      */
  401.     function query$query$title '' )
  402.     {
  403.         global $Timer;
  404.  
  405.         // initialise return
  406.         $return_val 0;
  407.  
  408.         // Flush cached values..
  409.         $this->flush();
  410.  
  411.         // Log how the function was called
  412.         $this->func_call '$db->query("'.$query.'")';
  413.         // echo $this->func_call, '<br />';
  414.  
  415.         // Replace aliases:
  416.         $query preg_replace$this->dbaliases$this->dbreplaces$query );
  417.  
  418.         ifpreg_match'#^ \s* create \s* table \s #ix'$query) )
  419.         {    // Query is a table creation, we add table options:
  420.             $query .= $this->dbtableoptions;
  421.         }
  422.  
  423.         // Keep track of the last query for debug..
  424.         $this->last_query = $query;
  425.  
  426.         // Perform the query via std mysql_query function..
  427.         $this->num_queries++;
  428.         $this->queries$this->num_queries - array(
  429.                                                                                                     'title' => $title,
  430.                                                                                                     'sql' => $query,
  431.                                                                                                     'rows' => -1,
  432.                                                                                                     'time' => 'unknown',
  433.                                                                                                     'results' => 'unknown' );
  434.  
  435.         ifis_object$Timer ) )
  436.         {
  437.             // Resume global query timer
  438.             $Timer->resume'sql_queries' );
  439.             // Start a timer fot this paritcular query:
  440.             $Timer->start'query' );
  441.             // Run query:
  442.             $this->result @mysql_query$query$this->dbh );
  443.             // Get duration fpor last query:
  444.             $this->queries$this->num_queries - ]['time'$Timer->get_duration'query' );
  445.             // Pause global query timer:
  446.             $Timer->pause'sql_queries' );
  447.         }
  448.         else
  449.         {
  450.             $this->result @mysql_query($query,$this->dbh);
  451.         }
  452.  
  453.         // If there is an error then take note of it..
  454.         if mysql_error() )
  455.         {
  456.             $this->print_error''$title );
  457.             return false;
  458.         }
  459.  
  460.         ifpreg_match'#^ \s* (insert|delete|update|replace) \s #ix'$query) )
  461.         // Query was an insert, delete, update, replace:
  462.  
  463.             $this->rows_affected = mysql_affected_rows();
  464.             $this->queries$this->num_queries - ]['rows'$this->rows_affected;
  465.  
  466.             // Take note of the insert_id
  467.             if preg_match("/^\\s*(insert|replace) /i",$query) )
  468.             {
  469.                 $this->insert_id = mysql_insert_id($this->dbh);
  470.             }
  471.  
  472.             // Return number fo rows affected
  473.             $return_val $this->rows_affected;
  474.         }
  475.         else
  476.         // Query was a select, alter, etc...:
  477.  
  478.             // Take note of column info
  479.             $i 0;
  480.             while$i @mysql_num_fields($this->result) )
  481.             {
  482.                 $this->col_info[$i@mysql_fetch_field($this->result);
  483.                 $i++;
  484.             }
  485.  
  486.             // Store Query Results
  487.             $num_rows 0;
  488.             while$row @mysql_fetch_object($this->result) )
  489.             {
  490.                 // Store relults as an objects within main array
  491.                 $this->last_result[$num_rows$row;
  492.                 $num_rows++;
  493.             }
  494.  
  495.             @mysql_free_result($this->result);
  496.  
  497.             // Log number of rows the query returned
  498.             $this->num_rows = $num_rows;
  499.             $this->queries$this->num_queries - ]['rows'$this->num_rows;
  500.  
  501.             // Return number of rows selected
  502.             $return_val $this->num_rows;
  503.         }
  504.  
  505.  
  506.         // EXPLAIN JOINS ??
  507.         if$this->debug_explain_joins && preg_match'#^ \s* select \s #ix'$query) )
  508.         // Query was a select, let's try to explain joins...
  509.  
  510.             // save values:
  511.             $saved_last_result $this->last_result;
  512.             $saved_col_info $this->col_info;
  513.             $saved_num_rows $this->num_rows;
  514.  
  515.             $this->last_result = NULL;
  516.             $this->col_info = NULL;
  517.             $this->num_rows = 0;
  518.  
  519.             $this->result @mysql_query'EXPLAIN '.$query$this->dbh );
  520.             // Take note of column info
  521.             $i 0;
  522.             while$i @mysql_num_fields($this->result) )
  523.             {
  524.                 $this->col_info[$i@mysql_fetch_field($this->result);
  525.                 $i++;
  526.             }
  527.  
  528.             // Store Query Results
  529.             $num_rows 0;
  530.             while$row @mysql_fetch_object($this->result) )
  531.             {
  532.                 // Store results as an objects within main array
  533.                 $this->last_result[$num_rows$row;
  534.                 $num_rows++;
  535.             }
  536.  
  537.             @mysql_free_result($this->result);
  538.  
  539.             // Log number of rows the query returned
  540.             $this->num_rows = $num_rows;
  541.  
  542.             $this->queries$this->num_queries - ]['explain'$this->debug_dump_rows100true );
  543.  
  544.             // Retsore:
  545.              $this->last_result = $saved_last_result;
  546.             $this->col_info = $saved_col_info;
  547.             $this->num_rows = $saved_num_rows;
  548.         }
  549.  
  550.  
  551.         // If debug ALL queries
  552.         if$this->debug_dump_rows )
  553.         {
  554.             $this->queries$this->num_queries - ]['results'$this->debug_dump_rows$this->debug_dump_rows );
  555.         }
  556.  
  557.         return $return_val;
  558.     }
  559.  
  560.  
  561.     /**
  562.      * Get one variable from the DB - see docs for more detail
  563.      *
  564.      * Note: To be sure that you received NULL from the DB and not "no rows" check
  565.      *       for {@link $num_rows}.
  566.      *
  567.      * @return mixed NULL if not found, the value otherwise (which may also be NULL).
  568.      */
  569.     function get_var$query NULL$x 0$y 0$title '' )
  570.     {
  571.         // Log how the function was called
  572.         $this->func_call "\$db->get_var(\"$query\",$x,$y)";
  573.  
  574.         // If there is a query then perform it if not then use cached results..
  575.         if$query )
  576.         {
  577.             $this->query($query$title);
  578.         }
  579.  
  580.         // Extract var out of cached results based x,y vals
  581.         if$this->last_result[$y)
  582.         {
  583.             $values array_values(get_object_vars($this->last_result[$y]));
  584.         }
  585.  
  586.         ifisset($values[$x]) )
  587.         {
  588.             return $values[$x];
  589.         }
  590.  
  591.         return NULL;
  592.     }
  593.  
  594.  
  595.     /**
  596.      * Get one row from the DB - see docs for more detail
  597.      *
  598.      * @return array|object 
  599.      */
  600.     function get_row$query NULL$output OBJECT$y 0$title '' )
  601.     {
  602.         // Log how the function was called
  603.         $this->func_call "\$db->get_row(\"$query\",$output,$y)";
  604.         // echo $this->func_call, '<br />';
  605.  
  606.         // If there is a query then perform it if not then use cached results..
  607.         if $query )
  608.         {
  609.             $this->query($query$title);
  610.         }
  611.  
  612.         // If the output is an object then return object using the row offset..
  613.         if $output == OBJECT )
  614.         {
  615.             return $this->last_result[$y]
  616.                             ? $this->last_result[$y]
  617.                             : array();
  618.         }
  619.         // If the output is an associative array then return row as such..
  620.         elseif $output == ARRAY_A )
  621.         {
  622.             return $this->last_result[$y]
  623.                             ? get_object_vars$this->last_result[$y)
  624.                             : array();
  625.         }
  626.         // If the output is an numerical array then return row as such..
  627.         elseif $output == ARRAY_N )
  628.         {
  629.             return $this->last_result[$y]
  630.                             ? array_valuesget_object_vars($this->last_result[$y]) )
  631.                             : array();
  632.         }
  633.         // If invalid output type was specified..
  634.         else
  635.         {
  636.             $this->print_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N");
  637.         }
  638.     }
  639.  
  640.  
  641.     /**
  642.      * Function to get 1 column from the cached result set based in X index
  643.      * see docs for usage and info
  644.      *
  645.      * @return array 
  646.      */
  647.     function get_col$query NULL$x 0$title '' )
  648.     {
  649.         // If there is a query then perform it if not then use cached results..
  650.         if$query )
  651.         {
  652.             $this->query$query$title );
  653.         }
  654.  
  655.         // Extract the column values
  656.         $new_array array();
  657.         for$i 0$count count($this->last_result)$i $count$i++ )
  658.         {
  659.             $new_array[$i$this->get_varNULL$x$i );
  660.         }
  661.  
  662.         return $new_array;
  663.     }
  664.  
  665.  
  666.     /**
  667.      * Get a column as comma-seperated list.
  668.      *
  669.      * @param string|NULLQuery to execute
  670.      * @param integer Column of the result set
  671.      * @return string 
  672.      */
  673.     function get_list$query NULL$x 0$title '' )
  674.     {
  675.         return implode','$this->get_col$query$x$title ) );
  676.     }
  677.     
  678.  
  679.     /**
  680.      * Return the the query as a result set - see docs for more details
  681.      *
  682.      * @return array 
  683.      */
  684.     function get_results$query NULL$output OBJECT$title '' )
  685.     {
  686.         // Log how the function was called
  687.         $this->func_call "\$db->get_results(\"$query\", $output)";
  688.  
  689.         // If there is a query then perform it if not then use cached results..
  690.         if$query )
  691.         {
  692.             $this->query($query$title);
  693.         }
  694.  
  695.         // Send back array of objects. Each row is an object
  696.         if $output == OBJECT )
  697.         {
  698.             return $this->last_result ? $this->last_result : array();
  699.         }
  700.         elseif $output == ARRAY_A || $output == ARRAY_N )
  701.         {
  702.             $new_array array();
  703.  
  704.             if$this->last_result )
  705.             {
  706.                 $i 0;
  707.  
  708.                 foreach$this->last_result as $row )
  709.                 {
  710.                     $new_array[$iget_object_vars($row);
  711.  
  712.                     if $output == ARRAY_N )
  713.                     {
  714.                         $new_array[$iarray_values($new_array[$i]);
  715.                     }
  716.  
  717.                     $i++;
  718.                 }
  719.  
  720.                 return $new_array;
  721.             }
  722.             else
  723.             {
  724.                 return array();
  725.             }
  726.         }
  727.     }
  728.  
  729.  
  730.     /**
  731.      * Function to get column meta data info pertaining to the last query
  732.      * see docs for more info and usage
  733.      */
  734.     function get_col_info$info_type 'name'$col_offset = -)
  735.     {
  736.         if$this->col_info )
  737.         {
  738.             if$col_offset == -)
  739.             {
  740.                 $i 0;
  741.                 foreach($this->col_info as $col )
  742.                 {
  743.                     $new_array[$i$col->{$info_type};
  744.                     $i++;
  745.                 }
  746.                 return $new_array;
  747.             }
  748.             else
  749.             {
  750.                 return $this->col_info[$col_offset]->{$info_type};
  751.             }
  752.         }
  753.     }
  754.  
  755.  
  756.     /**
  757.      * Dumps the contents of any input variable to screen in a nicely
  758.      * formatted and easy to understand way - any type: Object, Var or Array
  759.      *
  760.      * @param mixed Variable to dump
  761.      */
  762.     function vardump$mixed '' )
  763.     {
  764.         echo '<p><table><tr><td bgcolor="fff"><blockquote style="color:#000090">';
  765.         echo '<pre style="font-family:Arial">';
  766.  
  767.         if $this->vardump_called )
  768.         {
  769.             echo '<span style="color:#800080"><strong>ezSQL</strong> (v'.EZSQL_VERSION.") <strong>Variable Dump..</strong></span>\n\n";
  770.         }
  771.  
  772.         $var_type gettype ($mixed);
  773.         print_r( ( $mixed $mixed '<span style="color:#f00">No Value / False</span>') );
  774.         echo "\n\n<strong>Type:</strong> ".ucfirst$var_type )."\n"
  775.                 ."<strong>Last Query</strong> [$this->num_queries]<strong>:</strong> "
  776.                 .$this->last_query $this->last_query "NULL" )."\n"
  777.                 .'<strong>Last Function Call:</strong> '.$this->func_call $this->func_call 'None' )."\n"
  778.                 .'<strong>Last Rows Returned:</strong> '.count$this->last_result )."\n"
  779.                 .'</pre></blockquote></td></tr></table>';
  780.         echo "\n<hr size=1 noshade color=dddddd>";
  781.  
  782.         $this->vardump_called true;
  783.     }
  784.  
  785.  
  786.     /**
  787.      * Alias for {@link vardump()}
  788.      *
  789.      * @param mixed Variable to dump
  790.      */
  791.     function dumpvar$mixed )
  792.     {
  793.         $this->vardump$mixed );
  794.     }
  795.  
  796.  
  797.     /**
  798.      * Displays the last query string that was sent to the database & a
  799.      * table listing results (if there were any).
  800.      * (abstracted into a seperate file to save server overhead).
  801.      */
  802.     function debug_dump_rows$max_lines$break_at_comma false )
  803.     {
  804.         $r '';
  805.  
  806.         if $this->col_info )
  807.         {
  808.             // =====================================================
  809.             // Results top rows
  810.             $r .= '<table cellspacing="0">';
  811.             for$i 0$count count($this->col_info)$i $count$i++ )
  812.             {
  813.                 $r .= '<th><span class="type">'.$this->col_info[$i]->type.' '.$this->col_info[$i]->max_length.'</span><br />'
  814.                             .$this->col_info[$i]->name.'</th>';
  815.             }
  816.             $r .= '</tr>';
  817.  
  818.             $i=0;
  819.  
  820.             // ======================================================
  821.             // print main results
  822.             if$this->last_result )
  823.             {
  824.                 foreach$this->get_results(NULL,ARRAY_Nas $one_row )
  825.                 {
  826.                     $i++;
  827.                     if$i >= $max_lines )
  828.                     {
  829.                         break;
  830.                     }
  831.                     foreach$one_row as $item )
  832.                     {
  833.                         if$i )
  834.                         {
  835.                             $r .= '<td class="odd">';
  836.                         }
  837.                         else
  838.                         {
  839.                             $r .= '<td>';
  840.                         }
  841.  
  842.                         if$break_at_comma )
  843.                         {
  844.                             $item str_replace',''<br />'$item );
  845.                             $item str_replace';''<br />'$item );
  846.                             $r .= $item;
  847.                         }
  848.                         else
  849.                         {
  850.                             ifstrlen$item 50 )
  851.                             {
  852.                                 $item substr$item050 ).'...';
  853.                             }
  854.                             $r .= htmlspecialchars($item);
  855.                         }
  856.                         $r .= '</td>';
  857.                     }
  858.  
  859.                     $r .= '</tr>';
  860.                 }
  861.  
  862.             // if last result
  863.             else
  864.             {
  865.                 $r .= '<tr><td colspan="'.(count($this->col_info)+1).'">No Results</td></tr>';
  866.             }
  867.             if$i >= $max_lines )
  868.             {
  869.                 $r .= '<tr><td colspan="'.(count($this->col_info)+1).'">Max number of dumped rows has been reached.</td></tr>';
  870.             }
  871.  
  872.             $r .= '</table>';
  873.  
  874.         // if col_info
  875.         else
  876.         {
  877.             $r .= 'No Results';
  878.         }
  879.  
  880.  
  881.         return $r;
  882.     }
  883.  
  884.  
  885.     /** 
  886.      * Displays all queries that have been exectuted
  887.      *
  888.      * {@internal DB::dump_queries(-) }}
  889.      */
  890.     function dump_queries()
  891.     {
  892.         global $Timer;
  893.         ifis_object$Timer ) )
  894.         {
  895.             $time_queries $Timer->get_duration'sql_queries' );
  896.         }
  897.         else
  898.         {
  899.             $time_queries 0;
  900.         }
  901.  
  902.         foreach$this->queries as $query )
  903.         {
  904.             echo '<h4>Query: '.$query['title'].'</h4>';
  905.             echo '<code>';
  906.             $sql str_replace'FROM''<br />FROM'htmlspecialchars($query['sql']) );
  907.             $sql str_replace'WHERE''<br />WHERE'$sql );
  908.             $sql str_replace'GROUP BY''<br />GROUP BY'$sql );
  909.             $sql str_replace'ORDER BY''<br />ORDER BY'$sql );
  910.             $sql str_replace'LIMIT''<br />LIMIT'$sql );
  911.             $sql str_replace'AND ''<br />&nbsp; AND '$sql );
  912.             $sql str_replace'OR ''<br />&nbsp; OR '$sql );
  913.             $sql str_replace'VALUES''<br />VALUES'$sql );
  914.             echo $sql;
  915.             echo '</code>';
  916.             echo '<p class="rows">Rows: '.$query['rows'].' - Time: '.$query['time'].'s';
  917.             if$time_queries )
  918.             {    // We have a total time we can use to calculate percentage:
  919.                 echo ' ('.number_format100/$time_queries $query['time']).'%)';
  920.             }
  921.             echo '</p>';
  922.  
  923.             // Explain:
  924.             ifisset($query['explain']) )
  925.             {
  926.                 echo $query['explain'];
  927.             }
  928.  
  929.             // Results:
  930.             if$query['results'!= 'unknown' )
  931.             {
  932.                 echo $query['results'];
  933.             }
  934.         }
  935.     }
  936.  
  937.  
  938.     /**
  939.      * BEGIN A TRANSCATION
  940.      *
  941.      * Note:  By default, MySQL runs with autocommit mode enabled.
  942.      * This means that as soon as you execute a statement that updates (modifies)
  943.      * a table, MySQL stores the update on disk.
  944.      * Once you execute a BEGIN, the updates are "pending" until you execute a
  945.      * COMMIT {@see DB::commit()} or a ROLLBACK {@see DB:rollback()}
  946.      *
  947.      * Note 2: standard syntax would be START TRANSACTION but it's not supported by older
  948.      * MySQL versions whereas BEGIN is...
  949.      *
  950.      * Note 3: The default isolation level is REPEATABLE READ.
  951.      */
  952.     function begin()
  953.     {
  954.         if$this->use_transactions )
  955.         {
  956.             $this->query'BEGIN''BEGIN transaction' );
  957.  
  958.             $this->transaction_nesting_level++;
  959.         }
  960.     }
  961.  
  962.  
  963.     /**
  964.      * Commit current transaction
  965.      */
  966.     function commit()
  967.     {
  968.         if$this->use_transactions )
  969.         {
  970.             if$this->transaction_nesting_level == )
  971.             {    // Only COMMIT if there are no remaining nested transactions:
  972.                 if$this->rollback_nested_transaction )
  973.                 {
  974.                     $this->query'ROLLBACK''ROLLBACK transaction because there was a failure somewhere in the nesting of transactions' );
  975.                 }
  976.                 else
  977.                 {
  978.                     $this->query'COMMIT''COMMIT transaction' );
  979.                 }
  980.                 $this->rollback_nested_transaction false;
  981.             }
  982.             $this->transaction_nesting_level--;
  983.         }
  984.     }
  985.  
  986.  
  987.     /**
  988.      * @todo implement transactions!
  989.      */
  990.     function rollback()
  991.     {
  992.         if$this->use_transactions )
  993.         {
  994.             if$this->transaction_nesting_level == )
  995.             {    // Only ROLLBACK if there are no remaining nested transactions:
  996.                 $this->query'ROLLBACK''ROLLBACK transaction' );
  997.                 $this->rollback_nested_transaction false;
  998.             }
  999.             else
  1000.             {    // Remember we'll have to roll back at the end!
  1001.                 $this->rollback_nested_transaction true;
  1002.             }
  1003.             $this->transaction_nesting_level--;
  1004.         }
  1005.     }
  1006.  
  1007. }
  1008.  
  1009. /*
  1010.  * $Log: _class_db.php,v $
  1011.  * Revision 1.11.2.9  2005/09/02 21:31:34  fplanque
  1012.  * enhanced query debugging features
  1013.  *
  1014.  * Revision 1.23  2005/08/22 18:30:29  fplanque
  1015.  * minor
  1016.  *
  1017.  * Revision 1.22  2005/08/21 22:54:18  blueyed
  1018.  * Updated documentation for get_var().
  1019.  *
  1020.  * Revision 1.21  2005/08/21 22:44:32  blueyed
  1021.  * Removed dependencies on T_() and $Timer.
  1022.  *
  1023.  * Revision 1.20  2005/08/17 16:20:54  fplanque
  1024.  * rollback! I can't see a damn good reason to break existing code just because it happens that MySQL does not have a real boolean type!
  1025.  *
  1026.  * Revision 1.19  2005/07/22 13:54:45  blueyed
  1027.  * Better format for queries in print_error(); return value of get_var() is false, if nothing found (a DB cannot return false [boolean], but NULL?!)
  1028.  *
  1029.  * Revision 1.18  2005/07/15 18:11:16  fplanque
  1030.  * output debug context
  1031.  *
  1032.  * Revision 1.17  2005/07/12 23:05:36  blueyed
  1033.  * Added Timer class with categories 'main' and 'sql_queries' for now.
  1034.  *
  1035.  * Revision 1.16  2005/06/02 18:50:52  fplanque
  1036.  * no message
  1037.  *
  1038.  * Revision 1.15  2005/04/21 12:10:50  blueyed
  1039.  * minor
  1040.  *
  1041.  * Revision 1.14  2005/04/20 18:37:59  fplanque
  1042.  * Relocation of javascripts and CSS files to their proper places...
  1043.  *
  1044.  * Revision 1.13  2005/04/19 18:04:38  fplanque
  1045.  * implemented nested transactions for MySQL
  1046.  *
  1047.  * Revision 1.12  2005/03/08 20:32:07  fplanque
  1048.  * small fixes; slightly enhanced WEEK() handling
  1049.  *
  1050.  * Revision 1.11  2005/02/28 09:06:32  blueyed
  1051.  * removed constants for DB config (allows to override it from _config_TEST.php), introduced EVO_CONFIG_LOADED
  1052.  *
  1053.  * Revision 1.10  2005/02/23 22:32:44  blueyed
  1054.  * output xdebug function stack in case of error
  1055.  *
  1056.  * Revision 1.6  2005/02/08 00:43:15  blueyed
  1057.  * doc, whitespace, html, get_results() and get_row() now always return array, get_var() return false in case of error
  1058.  *
  1059.  * Revision 1.5  2004/11/09 00:25:11  blueyed
  1060.  * minor translation changes (+MySQL spelling :/)
  1061.  *
  1062.  * Revision 1.3  2004/10/28 11:11:09  fplanque
  1063.  * MySQL table options handling
  1064.  *
  1065.  * Revision 1.2  2004/10/14 16:28:41  fplanque
  1066.  * minor changes
  1067.  *
  1068.  * Revision 1.1  2004/10/13 22:46:32  fplanque
  1069.  * renamed [b2]evocore/*
  1070.  *
  1071.  * Revision 1.21  2004/10/12 10:27:18  fplanque
  1072.  * Edited code documentation.
  1073.  *
  1074.  */
  1075. ?>

Documentation generated on Tue, 20 May 2008 01:52:58 +0200 by phpDocumentor 1.4.2