Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

dbal.php

Zuletzt modifiziert: 09.10.2024, 12:51 - Dateigröße: 19.11 KiB


 001  <?php
 002  /**
 003  *
 004  * @package dbal
 005  * @version $Id$
 006  * @copyright (c) 2005 phpBB Group
 007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 008  *
 009  */
 010   
 011  /**
 012  * @ignore
 013  */
 014  if (!defined('IN_PHPBB'))
 015  {
 016      exit;
 017  }
 018   
 019  /**
 020  * Database Abstraction Layer
 021  * @package dbal
 022  */
 023  class dbal
 024  {
 025      var $db_connect_id;
 026      var $query_result;
 027      var $return_on_error = false;
 028      var $transaction = false;
 029      var $sql_time = 0;
 030      var $num_queries = array();
 031      var $open_queries = array();
 032   
 033      var $curtime = 0;
 034      var $query_hold = '';
 035      var $html_hold = '';
 036      var $sql_report = '';
 037      
 038      var $persistency = false;
 039      var $user = '';
 040      var $server = '';
 041      var $dbname = '';
 042   
 043      // Set to true if error triggered
 044      var $sql_error_triggered = false;
 045   
 046      // Holding the last sql query on sql error
 047      var $sql_error_sql = '';
 048   
 049      // Holding transaction count
 050      var $transactions = 0;
 051   
 052      // Supports multi inserts?
 053      var $multi_insert = false;
 054   
 055      /**
 056      * Current sql layer
 057      */
 058      var $sql_layer = '';
 059   
 060      /**
 061      * Wildcards for matching any (%) or exactly one (_) character within LIKE expressions
 062      */
 063      var $any_char;
 064      var $one_char;
 065   
 066      /**
 067      * Constructor
 068      */
 069      function dbal()
 070      {
 071          $this->num_queries = array(
 072              'cached'        => 0,
 073              'normal'        => 0,
 074              'total'            => 0,
 075          );
 076   
 077          // Fill default sql layer based on the class being called.
 078          // This can be changed by the specified layer itself later if needed.
 079          $this->sql_layer = substr(get_class($this), 5);
 080   
 081          // Do not change this please! This variable is used to easy the use of it - and is hardcoded.
 082          $this->any_char = chr(0) . '%';
 083          $this->one_char = chr(0) . '_';
 084      }
 085   
 086      /**
 087      * return on error or display error message
 088      */
 089      function sql_return_on_error($fail = false)
 090      {
 091          $this->sql_error_triggered = false;
 092          $this->sql_error_sql = '';
 093   
 094          $this->return_on_error = $fail;
 095      }
 096   
 097      /**
 098      * Return number of sql queries and cached sql queries used
 099      */
 100      function sql_num_queries($cached = false)
 101      {
 102          return ($cached) ? $this->num_queries['cached'] : $this->num_queries['normal'];
 103      }
 104   
 105      /**
 106      * Add to query count
 107      */
 108      function sql_add_num_queries($cached = false)
 109      {
 110          $this->num_queries['cached'] += ($cached !== false) ? 1 : 0;
 111          $this->num_queries['normal'] += ($cached !== false) ? 0 : 1;
 112          $this->num_queries['total'] += 1;
 113      }
 114   
 115      /**
 116      * DBAL garbage collection, close sql connection
 117      */
 118      function sql_close()
 119      {
 120          if (!$this->db_connect_id)
 121          {
 122              return false;
 123          }
 124   
 125          if ($this->transaction)
 126          {
 127              do
 128              {
 129                  $this->sql_transaction('commit');
 130              }
 131              while ($this->transaction);
 132          }
 133   
 134          foreach ($this->open_queries as $query_id)
 135          {
 136              $this->sql_freeresult($query_id);
 137          }
 138          
 139          return $this->_sql_close();
 140      }
 141   
 142      /**
 143      * Build LIMIT query
 144      * Doing some validation here.
 145      */
 146      function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
 147      {
 148          if (empty($query))
 149          {
 150              return false;
 151          }
 152   
 153          // Never use a negative total or offset
 154          $total = ($total < 0) ? 0 : $total;
 155          $offset = ($offset < 0) ? 0 : $offset;
 156   
 157          return $this->_sql_query_limit($query, $total, $offset, $cache_ttl);
 158      }
 159   
 160      /**
 161      * Fetch all rows
 162      */
 163      function sql_fetchrowset($query_id = false)
 164      {
 165          if ($query_id === false)
 166          {
 167              $query_id = $this->query_result;
 168          }
 169   
 170          if ($query_id !== false)
 171          {
 172              $result = array();
 173              while ($row = $this->sql_fetchrow($query_id))
 174              {
 175                  $result[] = $row;
 176              }
 177   
 178              return $result;
 179          }
 180          
 181          return false;
 182      }
 183   
 184      /**
 185      * Fetch field
 186      * if rownum is false, the current row is used, else it is pointing to the row (zero-based)
 187      */
 188      function sql_fetchfield($field, $rownum = false, $query_id = false)
 189      {
 190          global $cache;
 191   
 192          if ($query_id === false)
 193          {
 194              $query_id = $this->query_result;
 195          }
 196   
 197          if ($query_id !== false)
 198          {
 199              if ($rownum !== false)
 200              {
 201                  $this->sql_rowseek($rownum, $query_id);
 202              }
 203   
 204              if (!is_object($query_id) && isset($cache->sql_rowset[$query_id]))
 205              {
 206                  return $cache->sql_fetchfield($query_id, $field);
 207              }
 208   
 209              $row = $this->sql_fetchrow($query_id);
 210              return (isset($row[$field])) ? $row[$field] : false;
 211          }
 212   
 213          return false;
 214      }
 215   
 216      /**
 217      * Correctly adjust LIKE expression for special characters
 218      * Some DBMS are handling them in a different way
 219      *
 220      * @param string $expression The expression to use. Every wildcard is escaped, except $this->any_char and $this->one_char
 221      * @return string LIKE expression including the keyword!
 222      */
 223      function sql_like_expression($expression)
 224      {
 225          $expression = str_replace(array('_', '%'), array("\_", "\%"), $expression);
 226          $expression = str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression);
 227   
 228          return $this->_sql_like_expression('LIKE \'' . $this->sql_escape($expression) . '\'');
 229      }
 230   
 231      /**
 232      * SQL Transaction
 233      * @access private
 234      */
 235      function sql_transaction($status = 'begin')
 236      {
 237          switch ($status)
 238          {
 239              case 'begin':
 240                  // If we are within a transaction we will not open another one, but enclose the current one to not loose data (prevening auto commit)
 241                  if ($this->transaction)
 242                  {
 243                      $this->transactions++;
 244                      return true;
 245                  }
 246   
 247                  $result = $this->_sql_transaction('begin');
 248   
 249                  if (!$result)
 250                  {
 251                      $this->sql_error();
 252                  }
 253   
 254                  $this->transaction = true;
 255              break;
 256   
 257              case 'commit':
 258                  // If there was a previously opened transaction we do not commit yet... but count back the number of inner transactions
 259                  if ($this->transaction && $this->transactions)
 260                  {
 261                      $this->transactions--;
 262                      return true;
 263                  }
 264   
 265                  $result = $this->_sql_transaction('commit');
 266   
 267                  if (!$result)
 268                  {
 269                      $this->sql_error();
 270                  }
 271   
 272                  $this->transaction = false;
 273                  $this->transactions = 0;
 274              break;
 275   
 276              case 'rollback':
 277                  $result = $this->_sql_transaction('rollback');
 278                  $this->transaction = false;
 279                  $this->transactions = 0;
 280              break;
 281   
 282              default:
 283                  $result = $this->_sql_transaction($status);
 284              break;
 285          }
 286   
 287          return $result;
 288      }
 289   
 290      /**
 291      * Build sql statement from array for insert/update/select statements
 292      *
 293      * Idea for this from Ikonboard
 294      * Possible query values: INSERT, INSERT_SELECT, MULTI_INSERT, UPDATE, SELECT
 295      *
 296      */
 297      function sql_build_array($query, $assoc_ary = false)
 298      {
 299          if (!is_array($assoc_ary))
 300          {
 301              return false;
 302          }
 303   
 304          $fields = $values = array();
 305   
 306          if ($query == 'INSERT' || $query == 'INSERT_SELECT')
 307          {
 308              foreach ($assoc_ary as $key => $var)
 309              {
 310                  $fields[] = $key;
 311   
 312                  if (is_array($var) && is_string($var[0]))
 313                  {
 314                      // This is used for INSERT_SELECT(s)
 315                      $values[] = $var[0];
 316                  }
 317                  else
 318                  {
 319                      $values[] = $this->_sql_validate_value($var);
 320                  }
 321              }
 322   
 323              $query = ($query == 'INSERT') ? ' (' . implode(', ', $fields) . ') VALUES (' . implode(', ', $values) . ')' : ' (' . implode(', ', $fields) . ') SELECT ' . implode(', ', $values) . ' ';
 324          }
 325          else if ($query == 'MULTI_INSERT')
 326          {
 327              $ary = array();
 328              foreach ($assoc_ary as $id => $sql_ary)
 329              {
 330                  // If by accident the sql array is only one-dimensional we build a normal insert statement
 331                  if (!is_array($sql_ary))
 332                  {
 333                      return $this->sql_build_array('INSERT', $assoc_ary);
 334                  }
 335   
 336                  $values = array();
 337                  foreach ($sql_ary as $key => $var)
 338                  {
 339                      $values[] = $this->_sql_validate_value($var);
 340                  }
 341                  $ary[] = '(' . implode(', ', $values) . ')';
 342              }
 343   
 344              $query = ' (' . implode(', ', array_keys($assoc_ary[0])) . ') VALUES ' . implode(', ', $ary);
 345          }
 346          else if ($query == 'UPDATE' || $query == 'SELECT')
 347          {
 348              $values = array();
 349              foreach ($assoc_ary as $key => $var)
 350              {
 351                  $values[] = "$key = " . $this->_sql_validate_value($var);
 352              }
 353              $query = implode(($query == 'UPDATE') ? ', ' : ' AND ', $values);
 354          }
 355   
 356          return $query;
 357      }
 358   
 359      /**
 360      * Build IN or NOT IN sql comparison string, uses <> or = on single element
 361      * arrays to improve comparison speed
 362      *
 363      * @access public
 364      * @param    string    $field                name of the sql column that shall be compared
 365      * @param    array    $array                array of values that are allowed (IN) or not allowed (NOT IN)
 366      * @param    bool    $negate                true for NOT IN (), false for IN () (default)
 367      * @param    bool    $allow_empty_set    If true, allow $array to be empty, this function will return 1=1 or 1=0 then. Default to false.
 368      */
 369      function sql_in_set($field, $array, $negate = false, $allow_empty_set = false)
 370      {
 371          if (!sizeof($array))
 372          {
 373              if (!$allow_empty_set)
 374              {
 375                  // Print the backtrace to help identifying the location of the problematic code
 376                  $this->sql_error('No values specified for SQL IN comparison');
 377              }
 378              else
 379              {
 380                  // NOT IN () actually means everything so use a tautology
 381                  if ($negate)
 382                  {
 383                      return '1=1';
 384                  }
 385                  // IN () actually means nothing so use a contradiction
 386                  else
 387                  {
 388                      return '1=0';
 389                  }
 390              }
 391          }
 392   
 393          if (!is_array($array))
 394          {
 395              $array = array($array);
 396          }
 397   
 398          if (sizeof($array) == 1)
 399          {
 400              @reset($array);
 401              $var = current($array);
 402   
 403              return $field . ($negate ? ' <> ' : ' = ') . $this->_sql_validate_value($var);
 404          }
 405          else
 406          {
 407              return $field . ($negate ? ' NOT IN ' : ' IN ') . '(' . implode(', ', array_map(array($this, '_sql_validate_value'), $array)) . ')';
 408          }
 409      }
 410   
 411      /**
 412      * Run more than one insert statement.
 413      *
 414      * @param string $table table name to run the statements on
 415      * @param array &$sql_ary multi-dimensional array holding the statement data.
 416      *
 417      * @return bool false if no statements were executed.
 418      * @access public
 419      */
 420      function sql_multi_insert($table, &$sql_ary)
 421      {
 422          if (!sizeof($sql_ary))
 423          {
 424              return false;
 425          }
 426   
 427          if ($this->multi_insert)
 428          {
 429              $this->sql_query('INSERT INTO ' . $table . ' ' . $this->sql_build_array('MULTI_INSERT', $sql_ary));
 430          }
 431          else
 432          {
 433              foreach ($sql_ary as $ary)
 434              {
 435                  if (!is_array($ary))
 436                  {
 437                      return false;
 438                  }
 439   
 440                  $this->sql_query('INSERT INTO ' . $table . ' ' . $this->sql_build_array('INSERT', $ary));
 441              }
 442          }
 443   
 444          return true;
 445      }
 446   
 447      /**
 448      * Function for validating values
 449      * @access private
 450      */
 451      function _sql_validate_value($var)
 452      {
 453          if (is_null($var))
 454          {
 455              return 'NULL';
 456          }
 457          else if (is_string($var))
 458          {
 459              return "'" . $this->sql_escape($var) . "'";
 460          }
 461          else
 462          {
 463              return (is_bool($var)) ? intval($var) : $var;
 464          }
 465      }
 466   
 467      /**
 468      * Build sql statement from array for select and select distinct statements
 469      *
 470      * Possible query values: SELECT, SELECT_DISTINCT
 471      */
 472      function sql_build_query($query, $array)
 473      {
 474          $sql = '';
 475          switch ($query)
 476          {
 477              case 'SELECT':
 478              case 'SELECT_DISTINCT';
 479   
 480                  $sql = str_replace('_', ' ', $query) . ' ' . $array['SELECT'] . ' FROM ';
 481   
 482                  $table_array = array();
 483                  foreach ($array['FROM'] as $table_name => $alias)
 484                  {
 485                      if (is_array($alias))
 486                      {
 487                          foreach ($alias as $multi_alias)
 488                          {
 489                              $table_array[] = $table_name . ' ' . $multi_alias;
 490                          }
 491                      }
 492                      else
 493                      {
 494                          $table_array[] = $table_name . ' ' . $alias;
 495                      }
 496                  }
 497   
 498                  $sql .= $this->_sql_custom_build('FROM', implode(', ', $table_array));
 499   
 500                  if (!empty($array['LEFT_JOIN']))
 501                  {
 502                      foreach ($array['LEFT_JOIN'] as $join)
 503                      {
 504                          $sql .= ' LEFT JOIN ' . key($join['FROM']) . ' ' . current($join['FROM']) . ' ON (' . $join['ON'] . ')';
 505                      }
 506                  }
 507   
 508                  if (!empty($array['WHERE']))
 509                  {
 510                      $sql .= ' WHERE ' . $this->_sql_custom_build('WHERE', $array['WHERE']);
 511                  }
 512   
 513                  if (!empty($array['GROUP_BY']))
 514                  {
 515                      $sql .= ' GROUP BY ' . $array['GROUP_BY'];
 516                  }
 517   
 518                  if (!empty($array['ORDER_BY']))
 519                  {
 520                      $sql .= ' ORDER BY ' . $array['ORDER_BY'];
 521                  }
 522   
 523              break;
 524          }
 525   
 526          return $sql;
 527      }
 528   
 529      /**
 530      * display sql error page
 531      */
 532      function sql_error($sql = '')
 533      {
 534          global $auth, $user, $config;
 535   
 536          // Set var to retrieve errored status
 537          $this->sql_error_triggered = true;
 538          $this->sql_error_sql = $sql;
 539   
 540          $error = $this->_sql_error();
 541   
 542          if (!$this->return_on_error)
 543          {
 544              $message = 'SQL ERROR [ ' . $this->sql_layer . ' ]<br /><br />' . $error['message'] . ' [' . $error['code'] . ']';
 545   
 546              // Show complete SQL error and path to administrators only
 547              // Additionally show complete error on installation or if extended debug mode is enabled
 548              // The DEBUG_EXTRA constant is for development only!
 549              if ((isset($auth) && $auth->acl_get('a_')) || defined('IN_INSTALL') || defined('DEBUG_EXTRA'))
 550              {
 551                  // Print out a nice backtrace...
 552                  $backtrace = get_backtrace();
 553   
 554                  $message .= ($sql) ? '<br /><br />SQL<br /><br />' . htmlspecialchars($sql) : '';
 555                  $message .= ($backtrace) ? '<br /><br />BACKTRACE<br />' . $backtrace : '';
 556                  $message .= '<br />';
 557              }
 558              else
 559              {
 560                  // If error occurs in initiating the session we need to use a pre-defined language string
 561                  // This could happen if the connection could not be established for example (then we are not able to grab the default language)
 562                  if (!isset($user->lang['SQL_ERROR_OCCURRED']))
 563                  {
 564                      $message .= '<br /><br />An sql error occurred while fetching this page. Please contact an administrator if this problem persists.';
 565                  }
 566                  else
 567                  {
 568                      if (!empty($config['board_contact']))
 569                      {
 570                          $message .= '<br /><br />' . sprintf($user->lang['SQL_ERROR_OCCURRED'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>');
 571                      }
 572                      else
 573                      {
 574                          $message .= '<br /><br />' . sprintf($user->lang['SQL_ERROR_OCCURRED'], '', '');
 575                      }
 576                  }
 577              }
 578   
 579              if ($this->transaction)
 580              {
 581                  $this->sql_transaction('rollback');
 582              }
 583   
 584              if (strlen($message) > 1024)
 585              {
 586                  // We need to define $msg_long_text here to circumvent text stripping.
 587                  global $msg_long_text;
 588                  $msg_long_text = $message;
 589   
 590                  trigger_error(false, E_USER_ERROR);
 591              }
 592   
 593              trigger_error($message, E_USER_ERROR);
 594          }
 595   
 596          if ($this->transaction)
 597          {
 598              $this->sql_transaction('rollback');
 599          }
 600   
 601          return $error;
 602      }
 603   
 604      /**
 605      * Explain queries
 606      */
 607      function sql_report($mode, $query = '')
 608      {
 609          global $cache, $starttime, $phpbb_root_path, $user;
 610   
 611          if (empty($_REQUEST['explain']))
 612          {
 613              return false;
 614          }
 615   
 616          if (!$query && $this->query_hold != '')
 617          {
 618              $query = $this->query_hold;
 619          }
 620   
 621          switch ($mode)
 622          {
 623              case 'display':
 624                  if (!empty($cache))
 625                  {
 626                      $cache->unload();
 627                  }
 628                  $this->sql_close();
 629   
 630                  $mtime = explode(' ', microtime());
 631                  $totaltime = $mtime[0] + $mtime[1] - $starttime;
 632   
 633                  echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 634                      <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
 635                      <head>
 636                          <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
 637                          <meta http-equiv="Content-Style-Type" content="text/css" />
 638                          <meta http-equiv="imagetoolbar" content="no" />
 639                          <title>SQL Report</title>
 640                          <link href="' . $phpbb_root_path . 'adm/style/admin.css" rel="stylesheet" type="text/css" media="screen" />
 641                      </head>
 642                      <body id="errorpage">
 643                      <div id="wrap">
 644                          <div id="page-header">
 645                              <a href="' . build_url('explain') . '">Return to previous page</a>
 646                          </div>
 647                          <div id="page-body">
 648                              <div id="acp">
 649                              <div class="panel">
 650                                  <span class="corners-top"><span></span></span>
 651                                  <div id="content">
 652                                      <h1>SQL Report</h1>
 653                                      <br />
 654                                      <p><b>Page generated in ' . round($totaltime, 4) . " seconds with {$this->num_queries['normal']} queries" . (($this->num_queries['cached']) ? " + {$this->num_queries['cached']} " . (($this->num_queries['cached'] == 1) ? 'query' : 'queries') . ' returning data from cache' : '') . '</b></p>
 655   
 656                                      <p>Time spent on ' . $this->sql_layer . ' queries: <b>' . round($this->sql_time, 5) . 's</b> | Time spent on PHP: <b>' . round($totaltime - $this->sql_time, 5) . 's</b></p>
 657   
 658                                      <br /><br />
 659                                      ' . $this->sql_report . '
 660                                  </div>
 661                                  <span class="corners-bottom"><span></span></span>
 662                              </div>
 663                              </div>
 664                          </div>
 665                          <div id="page-footer">
 666                              Powered by phpBB &copy; 2000, 2002, 2005, 2007 <a href="http://www.phpbb.com/">phpBB Group</a>
 667                          </div>
 668                      </div>
 669                      </body>
 670                      </html>';
 671   
 672                  exit_handler();
 673   
 674              break;
 675   
 676              case 'stop':
 677                  $endtime = explode(' ', microtime());
 678                  $endtime = $endtime[0] + $endtime[1];
 679   
 680                  $this->sql_report .= '
 681   
 682                      <table cellspacing="1">
 683                      <thead>
 684                      <tr>
 685                          <th>Query #' . $this->num_queries['total'] . '</th>
 686                      </tr>
 687                      </thead>
 688                      <tbody>
 689                      <tr>
 690                          <td class="row3"><textarea style="font-family:\'Courier New\',monospace;width:99%" rows="5" cols="10">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td>
 691                      </tr>
 692                      </tbody>
 693                      </table>
 694                      
 695                      ' . $this->html_hold . '
 696   
 697                      <p style="text-align: center;">
 698                  ';
 699   
 700                  if ($this->query_result)
 701                  {
 702                      if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
 703                      {
 704                          $this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows($this->query_result) . '</b> | ';
 705                      }
 706                      $this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $this->curtime) . 's</b>';
 707                  }
 708                  else
 709                  {
 710                      $error = $this->sql_error();
 711                      $this->sql_report .= '<b style="color: red">FAILED</b> - ' . $this->sql_layer . ' Error ' . $error['code'] . ': ' . htmlspecialchars($error['message']);
 712                  }
 713   
 714                  $this->sql_report .= '</p><br /><br />';
 715   
 716                  $this->sql_time += $endtime - $this->curtime;
 717              break;
 718   
 719              case 'start':
 720                  $this->query_hold = $query;
 721                  $this->html_hold = '';
 722              
 723                  $this->_sql_report($mode, $query);
 724   
 725                  $this->curtime = explode(' ', microtime());
 726                  $this->curtime = $this->curtime[0] + $this->curtime[1];
 727   
 728              break;
 729              
 730              case 'add_select_row':
 731   
 732                  $html_table = func_get_arg(2);
 733                  $row = func_get_arg(3);
 734                  
 735                  if (!$html_table && sizeof($row))
 736                  {
 737                      $html_table = true;
 738                      $this->html_hold .= '<table cellspacing="1"><tr>';
 739                                  
 740                      foreach (array_keys($row) as $val)
 741                      {
 742                          $this->html_hold .= '<th>' . (($val) ? ucwords(str_replace('_', ' ', $val)) : '&nbsp;') . '</th>';
 743                      }
 744                      $this->html_hold .= '</tr>';
 745                  }
 746                  $this->html_hold .= '<tr>';
 747   
 748                  $class = 'row1';
 749                  foreach (array_values($row) as $val)
 750                  {
 751                      $class = ($class == 'row1') ? 'row2' : 'row1';
 752                      $this->html_hold .= '<td class="' . $class . '">' . (($val) ? $val : '&nbsp;') . '</td>';
 753                  }
 754                  $this->html_hold .= '</tr>';
 755              
 756                  return $html_table;
 757   
 758              break;
 759   
 760              case 'fromcache':
 761   
 762                  $this->_sql_report($mode, $query);
 763   
 764              break;
 765   
 766              case 'record_fromcache':
 767   
 768                  $endtime = func_get_arg(2);
 769                  $splittime = func_get_arg(3);
 770   
 771                  $time_cache = $endtime - $this->curtime;
 772                  $time_db = $splittime - $endtime;
 773                  $color = ($time_db > $time_cache) ? 'green' : 'red';
 774   
 775                  $this->sql_report .= '<table cellspacing="1"><thead><tr><th>Query results obtained from the cache</th></tr></thead><tbody><tr>';
 776                  $this->sql_report .= '<td class="row3"><textarea style="font-family:\'Courier New\',monospace;width:99%" rows="5" cols="10">' . preg_replace('/\t(AND|OR)(\W)/', "\$1\$2", htmlspecialchars(preg_replace('/[\s]*[\n\r\t]+[\n\r\s\t]*/', "\n", $query))) . '</textarea></td></tr></tbody></table>';
 777                  $this->sql_report .= '<p style="text-align: center;">';
 778                  $this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed [cache]: <b style="color: ' . $color . '">' . sprintf('%.5f', ($time_cache)) . 's</b> | Elapsed [db]: <b>' . sprintf('%.5f', $time_db) . 's</b></p><br /><br />';
 779   
 780                  // Pad the start time to not interfere with page timing
 781                  $starttime += $time_db;
 782   
 783              break;
 784   
 785              default:
 786              
 787                  $this->_sql_report($mode, $query);
 788   
 789              break;
 790          }
 791   
 792          return true;
 793      }
 794  }
 795   
 796  /**
 797  * This variable holds the class name to use later
 798  */
 799  $sql_db = (!empty($dbms)) ? 'dbal_' . basename($dbms) : 'dbal';
 800   
 801  ?>