Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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