Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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

oracle.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 18.91 KiB


001  <?php
002  /**
003  *
004  * This file is part of the phpBB Forum Software package.
005  *
006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
007  * @license GNU General Public License, version 2 (GPL-2.0)
008  *
009  * For full copyright and license information, please see
010  * the docs/CREDITS.txt file.
011  *
012  */
013   
014  namespace phpbb\db\driver;
015   
016  /**
017  * Oracle Database Abstraction Layer
018  */
019  class oracle extends \phpbb\db\driver\driver
020  {
021      var $last_query_text = '';
022      var $connect_error = '';
023   
024      /**
025      * {@inheritDoc}
026      */
027      function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
028      {
029          $this->persistency = $persistency;
030          $this->user = $sqluser;
031          $this->server = $sqlserver . (($port) ? ':' . $port : '');
032          $this->dbname = $database;
033   
034          $connect = $database;
035   
036          // support for "easy connect naming"
037          if ($sqlserver !== '' && $sqlserver !== '/')
038          {
039              if (substr($sqlserver, -1, 1) == '/')
040              {
041                  $sqlserver == substr($sqlserver, 0, -1);
042              }
043              $connect = $sqlserver . (($port) ? ':' . $port : '') . '/' . $database;
044          }
045   
046          if ($new_link)
047          {
048              if (!function_exists('ocinlogon'))
049              {
050                  $this->connect_error = 'ocinlogon function does not exist, is oci extension installed?';
051                  return $this->sql_error('');
052              }
053              $this->db_connect_id = @ocinlogon($this->user, $sqlpassword, $connect, 'UTF8');
054          }
055          else if ($this->persistency)
056          {
057              if (!function_exists('ociplogon'))
058              {
059                  $this->connect_error = 'ociplogon function does not exist, is oci extension installed?';
060                  return $this->sql_error('');
061              }
062              $this->db_connect_id = @ociplogon($this->user, $sqlpassword, $connect, 'UTF8');
063          }
064          else
065          {
066              if (!function_exists('ocilogon'))
067              {
068                  $this->connect_error = 'ocilogon function does not exist, is oci extension installed?';
069                  return $this->sql_error('');
070              }
071              $this->db_connect_id = @ocilogon($this->user, $sqlpassword, $connect, 'UTF8');
072          }
073   
074          return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
075      }
076   
077      /**
078      * {@inheritDoc}
079      */
080      function sql_server_info($raw = false, $use_cache = true)
081      {
082          /**
083          * force $use_cache false.  I didn't research why the caching code below is commented out
084          * but I assume its because the Oracle extension provides a direct method to access it
085          * without a query.
086          */
087   
088          $use_cache = false;
089  /*
090          global $cache;
091   
092          if (empty($cache) || ($this->sql_server_version = $cache->get('oracle_version')) === false)
093          {
094              $result = @ociparse($this->db_connect_id, 'SELECT * FROM v$version WHERE banner LIKE \'Oracle%\'');
095              @ociexecute($result, OCI_DEFAULT);
096              @ocicommit($this->db_connect_id);
097   
098              $row = array();
099              @ocifetchinto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS);
100              @ocifreestatement($result);
101              $this->sql_server_version = trim($row['BANNER']);
102   
103              $cache->put('oracle_version', $this->sql_server_version);
104          }
105  */
106          $this->sql_server_version = @ociserverversion($this->db_connect_id);
107   
108          return $this->sql_server_version;
109      }
110   
111      /**
112      * SQL Transaction
113      * @access private
114      */
115      function _sql_transaction($status = 'begin')
116      {
117          switch ($status)
118          {
119              case 'begin':
120                  return true;
121              break;
122   
123              case 'commit':
124                  return @ocicommit($this->db_connect_id);
125              break;
126   
127              case 'rollback':
128                  return @ocirollback($this->db_connect_id);
129              break;
130          }
131   
132          return true;
133      }
134   
135      /**
136      * Oracle specific code to handle the fact that it does not compare columns properly
137      * @access private
138      */
139      function _rewrite_col_compare($args)
140      {
141          if (sizeof($args) == 4)
142          {
143              if ($args[2] == '=')
144              {
145                  return '(' . $args[0] . ' OR (' . $args[1] . ' is NULL AND ' . $args[3] . ' is NULL))';
146              }
147              else if ($args[2] == '<>')
148              {
149                  // really just a fancy way of saying foo <> bar or (foo is NULL XOR bar is NULL) but SQL has no XOR :P
150                  return '(' . $args[0] . ' OR ((' . $args[1] . ' is NULL AND ' . $args[3] . ' is NOT NULL) OR (' . $args[1] . ' is NOT NULL AND ' . $args[3] . ' is NULL)))';
151              }
152          }
153          else
154          {
155              return $this->_rewrite_where($args[0]);
156          }
157      }
158   
159      /**
160      * Oracle specific code to handle it's lack of sanity
161      * @access private
162      */
163      function _rewrite_where($where_clause)
164      {
165          preg_match_all('/\s*(AND|OR)?\s*([\w_.()]++)\s*(?:(=|<[=>]?|>=?|LIKE)\s*((?>\'(?>[^\']++|\'\')*+\'|[\d-.()]+))|((NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]+,? ?)*+\)))/', $where_clause, $result, PREG_SET_ORDER);
166          $out = '';
167          foreach ($result as $val)
168          {
169              if (!isset($val[5]))
170              {
171                  if ($val[4] !== "''")
172                  {
173                      $out .= $val[0];
174                  }
175                  else
176                  {
177                      $out .= ' ' . $val[1] . ' ' . $val[2];
178                      if ($val[3] == '=')
179                      {
180                          $out .= ' is NULL';
181                      }
182                      else if ($val[3] == '<>')
183                      {
184                          $out .= ' is NOT NULL';
185                      }
186                  }
187              }
188              else
189              {
190                  $in_clause = array();
191                  $sub_exp = substr($val[5], strpos($val[5], '(') + 1, -1);
192                  $extra = false;
193                  preg_match_all('/\'(?>[^\']++|\'\')*+\'|[\d-.]++/', $sub_exp, $sub_vals, PREG_PATTERN_ORDER);
194                  $i = 0;
195                  foreach ($sub_vals[0] as $sub_val)
196                  {
197                      // two things:
198                      // 1) This determines if an empty string was in the IN clausing, making us turn it into a NULL comparison
199                      // 2) This fixes the 1000 list limit that Oracle has (ORA-01795)
200                      if ($sub_val !== "''")
201                      {
202                          $in_clause[(int) $i++/1000][] = $sub_val;
203                      }
204                      else
205                      {
206                          $extra = true;
207                      }
208                  }
209                  if (!$extra && $i < 1000)
210                  {
211                      $out .= $val[0];
212                  }
213                  else
214                  {
215                      $out .= ' ' . $val[1] . '(';
216                      $in_array = array();
217   
218                      // constuct each IN() clause
219                      foreach ($in_clause as $in_values)
220                      {
221                          $in_array[] = $val[2] . ' ' . (isset($val[6]) ? $val[6] : '') . 'IN(' . implode(', ', $in_values) . ')';
222                      }
223   
224                      // Join the IN() clauses against a few ORs (IN is just a nicer OR anyway)
225                      $out .= implode(' OR ', $in_array);
226   
227                      // handle the empty string case
228                      if ($extra)
229                      {
230                          $out .= ' OR ' . $val[2] . ' is ' . (isset($val[6]) ? $val[6] : '') . 'NULL';
231                      }
232                      $out .= ')';
233   
234                      unset($in_array, $in_clause);
235                  }
236              }
237          }
238   
239          return $out;
240      }
241   
242      /**
243      * {@inheritDoc}
244      */
245      function sql_query($query = '', $cache_ttl = 0)
246      {
247          if ($query != '')
248          {
249              global $cache;
250   
251              // EXPLAIN only in extra debug mode
252              if (defined('DEBUG'))
253              {
254                  $this->sql_report('start', $query);
255              }
256              else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
257              {
258                  $this->curtime = microtime(true);
259              }
260   
261              $this->last_query_text = $query;
262              $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false;
263              $this->sql_add_num_queries($this->query_result);
264   
265              if ($this->query_result === false)
266              {
267                  $in_transaction = false;
268                  if (!$this->transaction)
269                  {
270                      $this->sql_transaction('begin');
271                  }
272                  else
273                  {
274                      $in_transaction = true;
275                  }
276   
277                  $array = array();
278   
279                  // We overcome Oracle's 4000 char limit by binding vars
280                  if (strlen($query) > 4000)
281                  {
282                      if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/sU', $query, $regs))
283                      {
284                          if (strlen($regs[3]) > 4000)
285                          {
286                              $cols = explode(', ', $regs[2]);
287   
288                              preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER);
289   
290  /*                        The code inside this comment block breaks clob handling, but does allow the
291                          database restore script to work.  If you want to allow no posts longer than 4KB
292                          and/or need the db restore script, uncomment this.
293   
294   
295                              if (sizeof($cols) !== sizeof($vals))
296                              {
297                                  // Try to replace some common data we know is from our restore script or from other sources
298                                  $regs[3] = str_replace("'||chr(47)||'", '/', $regs[3]);
299                                  $_vals = explode(', ', $regs[3]);
300   
301                                  $vals = array();
302                                  $is_in_val = false;
303                                  $i = 0;
304                                  $string = '';
305   
306                                  foreach ($_vals as $value)
307                                  {
308                                      if (strpos($value, "'") === false && !$is_in_val)
309                                      {
310                                          $vals[$i++] = $value;
311                                          continue;
312                                      }
313   
314                                      if (substr($value, -1) === "'")
315                                      {
316                                          $vals[$i] = $string . (($is_in_val) ? ', ' : '') . $value;
317                                          $string = '';
318                                          $is_in_val = false;
319   
320                                          if ($vals[$i][0] !== "'")
321                                          {
322                                              $vals[$i] = "''" . $vals[$i];
323                                          }
324                                          $i++;
325                                          continue;
326                                      }
327                                      else
328                                      {
329                                          $string .= (($is_in_val) ? ', ' : '') . $value;
330                                          $is_in_val = true;
331                                      }
332                                  }
333   
334                                  if ($string)
335                                  {
336                                      // New value if cols != value
337                                      $vals[(sizeof($cols) !== sizeof($vals)) ? $i : $i - 1] .= $string;
338                                  }
339   
340                                  $vals = array(0 => $vals);
341                              }
342  */
343   
344                              $inserts = $vals[0];
345                              unset($vals);
346   
347                              foreach ($inserts as $key => $value)
348                              {
349                                  if (!empty($value) && $value[0] === "'" && strlen($value) > 4002) // check to see if this thing is greater than the max + 'x2
350                                  {
351                                      $inserts[$key] = ':' . strtoupper($cols[$key]);
352                                      $array[$inserts[$key]] = str_replace("''", "'", substr($value, 1, -1));
353                                  }
354                              }
355   
356                              $query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')';
357                          }
358                      }
359                      else if (preg_match_all('/^(UPDATE [\\w_]++\\s+SET )([\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+)(?:,\\s*[\\w_]++\\s*=\\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]+))*+)\\s+(WHERE.*)$/s', $query, $data, PREG_SET_ORDER))
360                      {
361                          if (strlen($data[0][2]) > 4000)
362                          {
363                              $update = $data[0][1];
364                              $where = $data[0][3];
365                              preg_match_all('/([\\w_]++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d-.]++)/', $data[0][2], $temp, PREG_SET_ORDER);
366                              unset($data);
367   
368                              $cols = array();
369                              foreach ($temp as $value)
370                              {
371                                  if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 4002) // check to see if this thing is greater than the max + 'x2
372                                  {
373                                      $cols[] = $value[1] . '=:' . strtoupper($value[1]);
374                                      $array[$value[1]] = str_replace("''", "'", substr($value[2], 1, -1));
375                                  }
376                                  else
377                                  {
378                                      $cols[] = $value[1] . '=' . $value[2];
379                                  }
380                              }
381   
382                              $query = $update . implode(', ', $cols) . ' ' . $where;
383                              unset($cols);
384                          }
385                      }
386                  }
387   
388                  switch (substr($query, 0, 6))
389                  {
390                      case 'DELETE':
391                          if (preg_match('/^(DELETE FROM [\w_]++ WHERE)((?:\s*(?:AND|OR)?\s*[\w_]+\s*(?:(?:=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]+)|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]+,? ?)*+\)))*+)$/', $query, $regs))
392                          {
393                              $query = $regs[1] . $this->_rewrite_where($regs[2]);
394                              unset($regs);
395                          }
396                      break;
397   
398                      case 'UPDATE':
399                          if (preg_match('/^(UPDATE [\\w_]++\\s+SET [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++)(?:, [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++))*+\\s+WHERE)(.*)$/s',  $query, $regs))
400                          {
401                              $query = $regs[1] . $this->_rewrite_where($regs[2]);
402                              unset($regs);
403                          }
404                      break;
405   
406                      case 'SELECT':
407                          $query = preg_replace_callback('/([\w_.]++)\s*(?:(=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]++|([\w_.]++))|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]++,? ?)*+\))/', array($this, '_rewrite_col_compare'), $query);
408                      break;
409                  }
410   
411                  $this->query_result = @ociparse($this->db_connect_id, $query);
412   
413                  foreach ($array as $key => $value)
414                  {
415                      @ocibindbyname($this->query_result, $key, $array[$key], -1);
416                  }
417   
418                  $success = @ociexecute($this->query_result, OCI_DEFAULT);
419   
420                  if (!$success)
421                  {
422                      $this->sql_error($query);
423                      $this->query_result = false;
424                  }
425                  else
426                  {
427                      if (!$in_transaction)
428                      {
429                          $this->sql_transaction('commit');
430                      }
431                  }
432   
433                  if (defined('DEBUG'))
434                  {
435                      $this->sql_report('stop', $query);
436                  }
437                  else if (defined('PHPBB_DISPLAY_LOAD_TIME'))
438                  {
439                      $this->sql_time += microtime(true) - $this->curtime;
440                  }
441   
442                  if ($cache && $cache_ttl)
443                  {
444                      $this->open_queries[(int) $this->query_result] = $this->query_result;
445                      $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl);
446                  }
447                  else if (strpos($query, 'SELECT') === 0 && $this->query_result)
448                  {
449                      $this->open_queries[(int) $this->query_result] = $this->query_result;
450                  }
451              }
452              else if (defined('DEBUG'))
453              {
454                  $this->sql_report('fromcache', $query);
455              }
456          }
457          else
458          {
459              return false;
460          }
461   
462          return $this->query_result;
463      }
464   
465      /**
466      * Build LIMIT query
467      */
468      function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
469      {
470          $this->query_result = false;
471   
472          $query = 'SELECT * FROM (SELECT /*+ FIRST_ROWS */ rownum AS xrownum, a.* FROM (' . $query . ') a WHERE rownum <= ' . ($offset + $total) . ') WHERE xrownum >= ' . $offset;
473   
474          return $this->sql_query($query, $cache_ttl);
475      }
476   
477      /**
478      * {@inheritDoc}
479      */
480      function sql_affectedrows()
481      {
482          return ($this->query_result) ? @ocirowcount($this->query_result) : false;
483      }
484   
485      /**
486      * {@inheritDoc}
487      */
488      function sql_fetchrow($query_id = false)
489      {
490          global $cache;
491   
492          if ($query_id === false)
493          {
494              $query_id = $this->query_result;
495          }
496   
497          if ($cache && $cache->sql_exists($query_id))
498          {
499              return $cache->sql_fetchrow($query_id);
500          }
501   
502          if ($query_id !== false)
503          {
504              $row = array();
505              $result = @ocifetchinto($query_id, $row, OCI_ASSOC + OCI_RETURN_NULLS);
506   
507              if (!$result || !$row)
508              {
509                  return false;
510              }
511   
512              $result_row = array();
513              foreach ($row as $key => $value)
514              {
515                  // Oracle treats empty strings as null
516                  if (is_null($value))
517                  {
518                      $value = '';
519                  }
520   
521                  // OCI->CLOB?
522                  if (is_object($value))
523                  {
524                      $value = $value->load();
525                  }
526   
527                  $result_row[strtolower($key)] = $value;
528              }
529   
530              return $result_row;
531          }
532   
533          return false;
534      }
535   
536      /**
537      * {@inheritDoc}
538      */
539      function sql_rowseek($rownum, &$query_id)
540      {
541          global $cache;
542   
543          if ($query_id === false)
544          {
545              $query_id = $this->query_result;
546          }
547   
548          if ($cache && $cache->sql_exists($query_id))
549          {
550              return $cache->sql_rowseek($rownum, $query_id);
551          }
552   
553          if ($query_id === false)
554          {
555              return false;
556          }
557   
558          // Reset internal pointer
559          @ociexecute($query_id, OCI_DEFAULT);
560   
561          // We do not fetch the row for rownum == 0 because then the next resultset would be the second row
562          for ($i = 0; $i < $rownum; $i++)
563          {
564              if (!$this->sql_fetchrow($query_id))
565              {
566                  return false;
567              }
568          }
569   
570          return true;
571      }
572   
573      /**
574      * {@inheritDoc}
575      */
576      function sql_nextid()
577      {
578          $query_id = $this->query_result;
579   
580          if ($query_id !== false && $this->last_query_text != '')
581          {
582              if (preg_match('#^INSERT[\t\n ]+INTO[\t\n ]+([a-z0-9\_\-]+)#is', $this->last_query_text, $tablename))
583              {
584                  $query = 'SELECT ' . $tablename[1] . '_seq.currval FROM DUAL';
585                  $stmt = @ociparse($this->db_connect_id, $query);
586                  @ociexecute($stmt, OCI_DEFAULT);
587   
588                  $temp_result = @ocifetchinto($stmt, $temp_array, OCI_ASSOC + OCI_RETURN_NULLS);
589                  @ocifreestatement($stmt);
590   
591                  if ($temp_result)
592                  {
593                      return $temp_array['CURRVAL'];
594                  }
595                  else
596                  {
597                      return false;
598                  }
599              }
600          }
601   
602          return false;
603      }
604   
605      /**
606      * {@inheritDoc}
607      */
608      function sql_freeresult($query_id = false)
609      {
610          global $cache;
611   
612          if ($query_id === false)
613          {
614              $query_id = $this->query_result;
615          }
616   
617          if ($cache && !is_object($query_id) && $cache->sql_exists($query_id))
618          {
619              return $cache->sql_freeresult($query_id);
620          }
621   
622          if (isset($this->open_queries[(int) $query_id]))
623          {
624              unset($this->open_queries[(int) $query_id]);
625              return @ocifreestatement($query_id);
626          }
627   
628          return false;
629      }
630   
631      /**
632      * {@inheritDoc}
633      */
634      function sql_escape($msg)
635      {
636          return str_replace(array("'", "\0"), array("''", ''), $msg);
637      }
638   
639      /**
640      * Build LIKE expression
641      * @access private
642      */
643      function _sql_like_expression($expression)
644      {
645          return $expression . " ESCAPE '\\'";
646      }
647   
648      /**
649      * Build NOT LIKE expression
650      * @access private
651      */
652      function _sql_not_like_expression($expression)
653      {
654          return $expression . " ESCAPE '\\'";
655      }
656   
657      function _sql_custom_build($stage, $data)
658      {
659          return $data;
660      }
661   
662      function _sql_bit_and($column_name, $bit, $compare = '')
663      {
664          return 'BITAND(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : '');
665      }
666   
667      function _sql_bit_or($column_name, $bit, $compare = '')
668      {
669          return 'BITOR(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : '');
670      }
671   
672      /**
673      * return sql error array
674      * @access private
675      */
676      function _sql_error()
677      {
678          if (function_exists('ocierror'))
679          {
680              $error = @ocierror();
681              $error = (!$error) ? @ocierror($this->query_result) : $error;
682              $error = (!$error) ? @ocierror($this->db_connect_id) : $error;
683   
684              if ($error)
685              {
686                  $this->last_error_result = $error;
687              }
688              else
689              {
690                  $error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array();
691              }
692          }
693          else
694          {
695              $error = array(
696                  'message'    => $this->connect_error,
697                  'code'        => '',
698              );
699          }
700   
701          return $error;
702      }
703   
704      /**
705      * Close sql connection
706      * @access private
707      */
708      function _sql_close()
709      {
710          return @ocilogoff($this->db_connect_id);
711      }
712   
713      /**
714      * Build db-specific report
715      * @access private
716      */
717      function _sql_report($mode, $query = '')
718      {
719          switch ($mode)
720          {
721              case 'start':
722   
723                  $html_table = false;
724   
725                  // Grab a plan table, any will do
726                  $sql = "SELECT table_name
727                      FROM USER_TABLES
728                      WHERE table_name LIKE '%PLAN_TABLE%'";
729                  $stmt = ociparse($this->db_connect_id, $sql);
730                  ociexecute($stmt);
731                  $result = array();
732   
733                  if (ocifetchinto($stmt, $result, OCI_ASSOC + OCI_RETURN_NULLS))
734                  {
735                      $table = $result['TABLE_NAME'];
736   
737                      // This is the statement_id that will allow us to track the plan
738                      $statement_id = substr(md5($query), 0, 30);
739   
740                      // Remove any stale plans
741                      $stmt2 = ociparse($this->db_connect_id, "DELETE FROM $table WHERE statement_id='$statement_id'");
742                      ociexecute($stmt2);
743                      ocifreestatement($stmt2);
744   
745                      // Explain the plan
746                      $sql = "EXPLAIN PLAN
747                          SET STATEMENT_ID = '$statement_id'
748                          FOR $query";
749                      $stmt2 = ociparse($this->db_connect_id, $sql);
750                      ociexecute($stmt2);
751                      ocifreestatement($stmt2);
752   
753                      // Get the data from the plan
754                      $sql = "SELECT operation, options, object_name, object_type, cardinality, cost
755                          FROM plan_table
756                          START WITH id = 0 AND statement_id = '$statement_id'
757                          CONNECT BY PRIOR id = parent_id
758                              AND statement_id = '$statement_id'";
759                      $stmt2 = ociparse($this->db_connect_id, $sql);
760                      ociexecute($stmt2);
761   
762                      $row = array();
763                      while (ocifetchinto($stmt2, $row, OCI_ASSOC + OCI_RETURN_NULLS))
764                      {
765                          $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
766                      }
767   
768                      ocifreestatement($stmt2);
769   
770                      // Remove the plan we just made, we delete them on request anyway
771                      $stmt2 = ociparse($this->db_connect_id, "DELETE FROM $table WHERE statement_id='$statement_id'");
772                      ociexecute($stmt2);
773                      ocifreestatement($stmt2);
774                  }
775   
776                  ocifreestatement($stmt);
777   
778                  if ($html_table)
779                  {
780                      $this->html_hold .= '</table>';
781                  }
782   
783              break;
784   
785              case 'fromcache':
786                  $endtime = explode(' ', microtime());
787                  $endtime = $endtime[0] + $endtime[1];
788   
789                  $result = @ociparse($this->db_connect_id, $query);
790                  $success = @ociexecute($result, OCI_DEFAULT);
791                  $row = array();
792   
793                  while (@ocifetchinto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS))
794                  {
795                      // Take the time spent on parsing rows into account
796                  }
797                  @ocifreestatement($result);
798   
799                  $splittime = explode(' ', microtime());
800                  $splittime = $splittime[0] + $splittime[1];
801   
802                  $this->sql_report('record_fromcache', $query, $endtime, $splittime);
803   
804              break;
805          }
806      }
807  }
808