[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/phpbb/db/driver/ -> oracle.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  namespace phpbb\db\driver;
  15  
  16  /**
  17  * Oracle Database Abstraction Layer
  18  */
  19  class oracle extends \phpbb\db\driver\driver
  20  {
  21      var $last_query_text = '';
  22      var $connect_error = '';
  23  
  24      /**
  25      * {@inheritDoc}
  26      */
  27  	function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
  28      {
  29          $this->persistency = $persistency;
  30          $this->user = $sqluser;
  31          $this->server = $sqlserver . (($port) ? ':' . $port : '');
  32          $this->dbname = $database;
  33  
  34          $connect = $database;
  35  
  36          // support for "easy connect naming"
  37          if ($sqlserver !== '' && $sqlserver !== '/')
  38          {
  39              if (substr($sqlserver, -1, 1) == '/')
  40              {
  41                  $sqlserver == substr($sqlserver, 0, -1);
  42              }
  43              $connect = $sqlserver . (($port) ? ':' . $port : '') . '/' . $database;
  44          }
  45  
  46          if ($new_link)
  47          {
  48              if (!function_exists('ocinlogon'))
  49              {
  50                  $this->connect_error = 'ocinlogon function does not exist, is oci extension installed?';
  51                  return $this->sql_error('');
  52              }
  53              $this->db_connect_id = @ocinlogon($this->user, $sqlpassword, $connect, 'UTF8');
  54          }
  55          else if ($this->persistency)
  56          {
  57              if (!function_exists('ociplogon'))
  58              {
  59                  $this->connect_error = 'ociplogon function does not exist, is oci extension installed?';
  60                  return $this->sql_error('');
  61              }
  62              $this->db_connect_id = @ociplogon($this->user, $sqlpassword, $connect, 'UTF8');
  63          }
  64          else
  65          {
  66              if (!function_exists('ocilogon'))
  67              {
  68                  $this->connect_error = 'ocilogon function does not exist, is oci extension installed?';
  69                  return $this->sql_error('');
  70              }
  71              $this->db_connect_id = @ocilogon($this->user, $sqlpassword, $connect, 'UTF8');
  72          }
  73  
  74          return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
  75      }
  76  
  77      /**
  78      * {@inheritDoc}
  79      */
  80  	function sql_server_info($raw = false, $use_cache = true)
  81      {
  82          /**
  83          * force $use_cache false.  I didn't research why the caching code below is commented out
  84          * but I assume its because the Oracle extension provides a direct method to access it
  85          * without a query.
  86          */
  87  
  88          $use_cache = false;
  89  /*
  90          global $cache;
  91  
  92          if (empty($cache) || ($this->sql_server_version = $cache->get('oracle_version')) === false)
  93          {
  94              $result = @ociparse($this->db_connect_id, 'SELECT * FROM v$version WHERE banner LIKE \'Oracle%\'');
  95              @ociexecute($result, OCI_DEFAULT);
  96              @ocicommit($this->db_connect_id);
  97  
  98              $row = array();
  99              @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  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1