[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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('oci_new_connect')) 49 { 50 $this->connect_error = 'oci_new_connect function does not exist, is oci extension installed?'; 51 return $this->sql_error(''); 52 } 53 $this->db_connect_id = @oci_new_connect($this->user, $sqlpassword, $connect, 'UTF8'); 54 } 55 else if ($this->persistency) 56 { 57 if (!function_exists('oci_pconnect')) 58 { 59 $this->connect_error = 'oci_pconnect function does not exist, is oci extension installed?'; 60 return $this->sql_error(''); 61 } 62 $this->db_connect_id = @oci_pconnect($this->user, $sqlpassword, $connect, 'UTF8'); 63 } 64 else 65 { 66 if (!function_exists('oci_connect')) 67 { 68 $this->connect_error = 'oci_connect function does not exist, is oci extension installed?'; 69 return $this->sql_error(''); 70 } 71 $this->db_connect_id = @oci_connect($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 global $cache; 89 90 if (empty($cache) || ($this->sql_server_version = $cache->get('oracle_version')) === false) 91 { 92 $result = @ociparse($this->db_connect_id, 'SELECT * FROM v$version WHERE banner LIKE \'Oracle%\''); 93 @ociexecute($result, OCI_DEFAULT); 94 @ocicommit($this->db_connect_id); 95 96 $row = array(); 97 @ocifetchinto($result, $row, OCI_ASSOC + OCI_RETURN_NULLS); 98 @ocifreestatement($result); 99 $this->sql_server_version = trim($row['BANNER']); 100 101 $cache->put('oracle_version', $this->sql_server_version); 102 } 103 */ 104 $this->sql_server_version = @oci_server_version($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 @oci_commit($this->db_connect_id); 123 break; 124 125 case 'rollback': 126 return @oci_rollback($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 (count($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 if ($this->debug_sql_explain) 250 { 251 $this->sql_report('start', $query); 252 } 253 else if ($this->debug_load_time) 254 { 255 $this->curtime = microtime(true); 256 } 257 258 $this->last_query_text = $query; 259 $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; 260 $this->sql_add_num_queries($this->query_result); 261 262 if ($this->query_result === false) 263 { 264 $in_transaction = false; 265 if (!$this->transaction) 266 { 267 $this->sql_transaction('begin'); 268 } 269 else 270 { 271 $in_transaction = true; 272 } 273 274 $array = array(); 275 276 // We overcome Oracle's 4000 char limit by binding vars 277 if (strlen($query) > 4000) 278 { 279 if (preg_match('/^(INSERT INTO[^(]++)\\(([^()]+)\\) VALUES[^(]++\\((.*?)\\)$/sU', $query, $regs)) 280 { 281 if (strlen($regs[3]) > 4000) 282 { 283 $cols = explode(', ', $regs[2]); 284 285 preg_match_all('/\'(?:[^\']++|\'\')*+\'|[\d-.]+/', $regs[3], $vals, PREG_PATTERN_ORDER); 286 287 /* The code inside this comment block breaks clob handling, but does allow the 288 database restore script to work. If you want to allow no posts longer than 4KB 289 and/or need the db restore script, uncomment this. 290 291 292 if (count($cols) !== count($vals)) 293 { 294 // Try to replace some common data we know is from our restore script or from other sources 295 $regs[3] = str_replace("'||chr(47)||'", '/', $regs[3]); 296 $_vals = explode(', ', $regs[3]); 297 298 $vals = array(); 299 $is_in_val = false; 300 $i = 0; 301 $string = ''; 302 303 foreach ($_vals as $value) 304 { 305 if (strpos($value, "'") === false && !$is_in_val) 306 { 307 $vals[$i++] = $value; 308 continue; 309 } 310 311 if (substr($value, -1) === "'") 312 { 313 $vals[$i] = $string . (($is_in_val) ? ', ' : '') . $value; 314 $string = ''; 315 $is_in_val = false; 316 317 if ($vals[$i][0] !== "'") 318 { 319 $vals[$i] = "''" . $vals[$i]; 320 } 321 $i++; 322 continue; 323 } 324 else 325 { 326 $string .= (($is_in_val) ? ', ' : '') . $value; 327 $is_in_val = true; 328 } 329 } 330 331 if ($string) 332 { 333 // New value if cols != value 334 $vals[(count($cols) !== count($vals)) ? $i : $i - 1] .= $string; 335 } 336 337 $vals = array(0 => $vals); 338 } 339 */ 340 341 $inserts = $vals[0]; 342 unset($vals); 343 344 foreach ($inserts as $key => $value) 345 { 346 if (!empty($value) && $value[0] === "'" && strlen($value) > 4002) // check to see if this thing is greater than the max + 'x2 347 { 348 $inserts[$key] = ':' . strtoupper($cols[$key]); 349 $array[$inserts[$key]] = str_replace("''", "'", substr($value, 1, -1)); 350 } 351 } 352 353 $query = $regs[1] . '(' . $regs[2] . ') VALUES (' . implode(', ', $inserts) . ')'; 354 } 355 } 356 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)) 357 { 358 if (strlen($data[0][2]) > 4000) 359 { 360 $update = $data[0][1]; 361 $where = $data[0][3]; 362 preg_match_all('/([\\w_]++)\\s*=\\s*(\'(?:[^\']++|\'\')*+\'|[\d-.]++)/', $data[0][2], $temp, PREG_SET_ORDER); 363 unset($data); 364 365 $cols = array(); 366 foreach ($temp as $value) 367 { 368 if (!empty($value[2]) && $value[2][0] === "'" && strlen($value[2]) > 4002) // check to see if this thing is greater than the max + 'x2 369 { 370 $cols[] = $value[1] . '=:' . strtoupper($value[1]); 371 $array[$value[1]] = str_replace("''", "'", substr($value[2], 1, -1)); 372 } 373 else 374 { 375 $cols[] = $value[1] . '=' . $value[2]; 376 } 377 } 378 379 $query = $update . implode(', ', $cols) . ' ' . $where; 380 unset($cols); 381 } 382 } 383 } 384 385 switch (substr($query, 0, 6)) 386 { 387 case 'DELETE': 388 if (preg_match('/^(DELETE FROM [\w_]++ WHERE)((?:\s*(?:AND|OR)?\s*[\w_]+\s*(?:(?:=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]+)|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]+,? ?)*+\)))*+)$/', $query, $regs)) 389 { 390 $query = $regs[1] . $this->_rewrite_where($regs[2]); 391 unset($regs); 392 } 393 break; 394 395 case 'UPDATE': 396 if (preg_match('/^(UPDATE [\\w_]++\\s+SET [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++)(?:, [\\w_]+\s*=\s*(?:\'(?:[^\']++|\'\')*+\'|[\d-.]++|:\w++))*+\\s+WHERE)(.*)$/s', $query, $regs)) 397 { 398 $query = $regs[1] . $this->_rewrite_where($regs[2]); 399 unset($regs); 400 } 401 break; 402 403 case 'SELECT': 404 $query = preg_replace_callback('/([\w_.]++)\s*(?:(=|<>)\s*(?>\'(?>[^\']++|\'\')*+\'|[\d-.]++|([\w_.]++))|(?:NOT )?IN\s*\((?>\'(?>[^\']++|\'\')*+\',? ?|[\d-.]++,? ?)*+\))/', array($this, '_rewrite_col_compare'), $query); 405 break; 406 } 407 408 $this->query_result = @oci_parse($this->db_connect_id, $query); 409 410 foreach ($array as $key => $value) 411 { 412 @oci_bind_by_name($this->query_result, $key, $array[$key], -1); 413 } 414 415 $success = @oci_execute($this->query_result, OCI_DEFAULT); 416 417 if (!$success) 418 { 419 $this->sql_error($query); 420 $this->query_result = false; 421 } 422 else 423 { 424 if (!$in_transaction) 425 { 426 $this->sql_transaction('commit'); 427 } 428 } 429 430 if ($this->debug_sql_explain) 431 { 432 $this->sql_report('stop', $query); 433 } 434 else if ($this->debug_load_time) 435 { 436 $this->sql_time += microtime(true) - $this->curtime; 437 } 438 439 if (!$this->query_result) 440 { 441 return false; 442 } 443 444 $safe_query_id = $this->clean_query_id($this->query_result); 445 446 if ($cache && $cache_ttl) 447 { 448 $this->open_queries[$safe_query_id] = $this->query_result; 449 $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); 450 } 451 else if (strpos($query, 'SELECT') === 0) 452 { 453 $this->open_queries[$safe_query_id] = $this->query_result; 454 } 455 } 456 else if ($this->debug_sql_explain) 457 { 458 $this->sql_report('fromcache', $query); 459 } 460 } 461 else 462 { 463 return false; 464 } 465 466 return $this->query_result; 467 } 468 469 /** 470 * Build LIMIT query 471 */ 472 function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) 473 { 474 $this->query_result = false; 475 476 $query = 'SELECT * FROM (SELECT /*+ FIRST_ROWS */ rownum AS xrownum, a.* FROM (' . $query . ') a WHERE rownum <= ' . ($offset + $total) . ') WHERE xrownum >= ' . $offset; 477 478 return $this->sql_query($query, $cache_ttl); 479 } 480 481 /** 482 * {@inheritDoc} 483 */ 484 function sql_affectedrows() 485 { 486 return ($this->query_result) ? @oci_num_rows($this->query_result) : false; 487 } 488 489 /** 490 * {@inheritDoc} 491 */ 492 function sql_fetchrow($query_id = false) 493 { 494 global $cache; 495 496 if ($query_id === false) 497 { 498 $query_id = $this->query_result; 499 } 500 501 $safe_query_id = $this->clean_query_id($query_id); 502 if ($cache && $cache->sql_exists($safe_query_id)) 503 { 504 return $cache->sql_fetchrow($safe_query_id); 505 } 506 507 if ($query_id) 508 { 509 if (!$row = oci_fetch_array($query_id, OCI_ASSOC + OCI_RETURN_NULLS)) 510 { 511 return false; 512 } 513 514 $result_row = array(); 515 foreach ($row as $key => $value) 516 { 517 // Oracle treats empty strings as null 518 if (is_null($value)) 519 { 520 $value = ''; 521 } 522 523 // OCI->CLOB? 524 if (is_object($value)) 525 { 526 $value = $value->load(); 527 } 528 529 $result_row[strtolower($key)] = $value; 530 } 531 532 return $result_row; 533 } 534 535 return false; 536 } 537 538 /** 539 * {@inheritDoc} 540 */ 541 function sql_rowseek($rownum, &$query_id) 542 { 543 global $cache; 544 545 if ($query_id === false) 546 { 547 $query_id = $this->query_result; 548 } 549 550 $safe_query_id = $this->clean_query_id($query_id); 551 if ($cache && $cache->sql_exists($safe_query_id)) 552 { 553 return $cache->sql_rowseek($rownum, $safe_query_id); 554 } 555 556 if (!$query_id) 557 { 558 return false; 559 } 560 561 // Reset internal pointer 562 @oci_execute($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 public function sql_last_inserted_id() 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 = @oci_parse($this->db_connect_id, $query); 589 if ($stmt) 590 { 591 $success = @oci_execute($stmt, OCI_DEFAULT); 592 593 if ($success) 594 { 595 $temp_array = oci_fetch_array($stmt, OCI_ASSOC + OCI_RETURN_NULLS); 596 oci_free_statement($stmt); 597 598 if (!empty($temp_array)) 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 $safe_query_id = $this->clean_query_id($query_id); 627 if ($cache && $cache->sql_exists($safe_query_id)) 628 { 629 return $cache->sql_freeresult($safe_query_id); 630 } 631 632 if (isset($this->open_queries[$safe_query_id])) 633 { 634 unset($this->open_queries[$safe_query_id]); 635 return oci_free_statement($query_id); 636 } 637 638 return false; 639 } 640 641 /** 642 * {@inheritDoc} 643 */ 644 function sql_escape($msg) 645 { 646 return str_replace(array("'", "\0"), array("''", ''), $msg); 647 } 648 649 /** 650 * Build LIKE expression 651 * @access private 652 */ 653 function _sql_like_expression($expression) 654 { 655 return $expression . " ESCAPE '\\'"; 656 } 657 658 /** 659 * Build NOT LIKE expression 660 * @access private 661 */ 662 function _sql_not_like_expression($expression) 663 { 664 return $expression . " ESCAPE '\\'"; 665 } 666 667 function _sql_custom_build($stage, $data) 668 { 669 return $data; 670 } 671 672 function _sql_bit_and($column_name, $bit, $compare = '') 673 { 674 return 'BITAND(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : ''); 675 } 676 677 function _sql_bit_or($column_name, $bit, $compare = '') 678 { 679 return 'BITOR(' . $column_name . ', ' . (1 << $bit) . ')' . (($compare) ? ' ' . $compare : ''); 680 } 681 682 /** 683 * return sql error array 684 * @access private 685 */ 686 function _sql_error() 687 { 688 if (function_exists('oci_error')) 689 { 690 $error = @oci_error(); 691 $error = (!$error) ? @oci_error($this->query_result) : $error; 692 $error = (!$error) ? @oci_error($this->db_connect_id) : $error; 693 694 if ($error) 695 { 696 $this->last_error_result = $error; 697 } 698 else 699 { 700 $error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array(); 701 } 702 } 703 else 704 { 705 $error = array( 706 'message' => $this->connect_error, 707 'code' => '', 708 ); 709 } 710 711 return $error; 712 } 713 714 /** 715 * Close sql connection 716 * @access private 717 */ 718 function _sql_close() 719 { 720 return @oci_close($this->db_connect_id); 721 } 722 723 /** 724 * Build db-specific report 725 * @access private 726 */ 727 function _sql_report($mode, $query = '') 728 { 729 switch ($mode) 730 { 731 case 'start': 732 733 $html_table = false; 734 735 // Grab a plan table, any will do 736 $sql = "SELECT table_name 737 FROM USER_TABLES 738 WHERE table_name LIKE '%PLAN_TABLE%'"; 739 $stmt = oci_parse($this->db_connect_id, $sql); 740 oci_execute($stmt); 741 742 if ($result = oci_fetch_array($stmt, 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 = oci_parse($this->db_connect_id, "DELETE FROM $table WHERE statement_id='$statement_id'"); 751 oci_execute($stmt2); 752 oci_free_statement($stmt2); 753 754 // Explain the plan 755 $sql = "EXPLAIN PLAN 756 SET STATEMENT_ID = '$statement_id' 757 FOR $query"; 758 $stmt2 = oci_parse($this->db_connect_id, $sql); 759 oci_execute($stmt2); 760 oci_free_statement($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 = oci_parse($this->db_connect_id, $sql); 769 oci_execute($stmt2); 770 771 while ($row = oci_fetch_array($stmt2, OCI_ASSOC + OCI_RETURN_NULLS)) 772 { 773 $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); 774 } 775 776 oci_free_statement($stmt2); 777 778 // Remove the plan we just made, we delete them on request anyway 779 $stmt2 = oci_parse($this->db_connect_id, "DELETE FROM $table WHERE statement_id='$statement_id'"); 780 oci_execute($stmt2); 781 oci_free_statement($stmt2); 782 } 783 784 oci_free_statement($stmt); 785 786 if ($html_table) 787 { 788 $this->html_hold .= '</table>'; 789 } 790 791 break; 792 793 case 'fromcache': 794 $endtime = explode(' ', microtime()); 795 $endtime = $endtime[0] + $endtime[1]; 796 797 $result = @oci_parse($this->db_connect_id, $query); 798 if ($result) 799 { 800 $success = @oci_execute($result, OCI_DEFAULT); 801 if ($success) 802 { 803 array(); 804 805 while ($row = oci_fetch_array($result, OCI_ASSOC + OCI_RETURN_NULLS)) 806 { 807 // Take the time spent on parsing rows into account 808 } 809 @oci_free_statement($result); 810 } 811 } 812 813 $splittime = explode(' ', microtime()); 814 $splittime = $splittime[0] + $splittime[1]; 815 816 $this->sql_report('record_fromcache', $query, $endtime, $splittime); 817 818 break; 819 } 820 } 821 822 /** 823 * {@inheritDoc} 824 */ 825 function sql_quote($msg) 826 { 827 return '"' . $msg . '"'; 828 } 829 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |