| [ PHPXref.com ] | [ Generated: Sun Jul 20 20:47:21 2008 ] | [ TPLN 2.6 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 <?php 2 3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 4 5 /** 6 * The PEAR DB driver for PHP's fbsql extension 7 * for interacting with FrontBase databases 8 * 9 * PHP versions 4 and 5 10 * 11 * LICENSE: This source file is subject to version 3.0 of the PHP license 12 * that is available through the world-wide-web at the following URI: 13 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 14 * the PHP License and are unable to obtain it through the web, please 15 * send a note to license@php.net so we can mail you a copy immediately. 16 * 17 * @category Database 18 * @package DB 19 * @author Frank M. Kromann <frank@frontbase.com> 20 * @author Daniel Convissor <danielc@php.net> 21 * @copyright 1997-2005 The PHP Group 22 * @license http://www.php.net/license/3_0.txt PHP License 3.0 23 * @version CVS: $Id: fbsql.php,v 1.82 2005/03/04 23:12:36 danielc Exp $ 24 * @link http://pear.php.net/package/DB 25 */ 26 27 /** 28 * Obtain the DB_common class so it can be extended from 29 */ 30 require_once 'DB/common.php'; 31 32 /** 33 * The methods PEAR DB uses to interact with PHP's fbsql extension 34 * for interacting with FrontBase databases 35 * 36 * These methods overload the ones declared in DB_common. 37 * 38 * @category Database 39 * @package DB 40 * @author Frank M. Kromann <frank@frontbase.com> 41 * @author Daniel Convissor <danielc@php.net> 42 * @copyright 1997-2005 The PHP Group 43 * @license http://www.php.net/license/3_0.txt PHP License 3.0 44 * @version Release: @package_version@ 45 * @link http://pear.php.net/package/DB 46 * @since Class functional since Release 1.7.0 47 */ 48 class DB_fbsql extends DB_common 49 { 50 // {{{ properties 51 52 /** 53 * The DB driver type (mysql, oci8, odbc, etc.) 54 * @var string 55 */ 56 var $phptype = 'fbsql'; 57 58 /** 59 * The database syntax variant to be used (db2, access, etc.), if any 60 * @var string 61 */ 62 var $dbsyntax = 'fbsql'; 63 64 /** 65 * The capabilities of this DB implementation 66 * 67 * The 'new_link' element contains the PHP version that first provided 68 * new_link support for this DBMS. Contains false if it's unsupported. 69 * 70 * Meaning of the 'limit' element: 71 * + 'emulate' = emulate with fetch row by number 72 * + 'alter' = alter the query 73 * + false = skip rows 74 * 75 * @var array 76 */ 77 var $features = array( 78 'limit' => 'alter', 79 'new_link' => false, 80 'numrows' => true, 81 'pconnect' => true, 82 'prepare' => false, 83 'ssl' => false, 84 'transactions' => true, 85 ); 86 87 /** 88 * A mapping of native error codes to DB error codes 89 * @var array 90 */ 91 var $errorcode_map = array( 92 22 => DB_ERROR_SYNTAX, 93 85 => DB_ERROR_ALREADY_EXISTS, 94 108 => DB_ERROR_SYNTAX, 95 116 => DB_ERROR_NOSUCHTABLE, 96 124 => DB_ERROR_VALUE_COUNT_ON_ROW, 97 215 => DB_ERROR_NOSUCHFIELD, 98 217 => DB_ERROR_INVALID_NUMBER, 99 226 => DB_ERROR_NOSUCHFIELD, 100 231 => DB_ERROR_INVALID, 101 239 => DB_ERROR_TRUNCATED, 102 251 => DB_ERROR_SYNTAX, 103 266 => DB_ERROR_NOT_FOUND, 104 357 => DB_ERROR_CONSTRAINT_NOT_NULL, 105 358 => DB_ERROR_CONSTRAINT, 106 360 => DB_ERROR_CONSTRAINT, 107 361 => DB_ERROR_CONSTRAINT, 108 ); 109 110 /** 111 * The raw database connection created by PHP 112 * @var resource 113 */ 114 var $connection; 115 116 /** 117 * The DSN information for connecting to a database 118 * @var array 119 */ 120 var $dsn = array(); 121 122 123 // }}} 124 // {{{ constructor 125 126 /** 127 * This constructor calls <kbd>$this->DB_common()</kbd> 128 * 129 * @return void 130 */ 131 function DB_fbsql() 132 { 133 $this->DB_common(); 134 } 135 136 // }}} 137 // {{{ connect() 138 139 /** 140 * Connect to the database server, log in and open the database 141 * 142 * Don't call this method directly. Use DB::connect() instead. 143 * 144 * @param array $dsn the data source name 145 * @param bool $persistent should the connection be persistent? 146 * 147 * @return int DB_OK on success. A DB_Error object on failure. 148 */ 149 function connect($dsn, $persistent = false) 150 { 151 if (!PEAR::loadExtension('fbsql')) { 152 return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); 153 } 154 155 $this->dsn = $dsn; 156 if ($dsn['dbsyntax']) { 157 $this->dbsyntax = $dsn['dbsyntax']; 158 } 159 160 $params = array( 161 $dsn['hostspec'] ? $dsn['hostspec'] : 'localhost', 162 $dsn['username'] ? $dsn['username'] : null, 163 $dsn['password'] ? $dsn['password'] : null, 164 ); 165 166 $connect_function = $persistent ? 'fbsql_pconnect' : 'fbsql_connect'; 167 168 $ini = ini_get('track_errors'); 169 $php_errormsg = ''; 170 if ($ini) { 171 $this->connection = @call_user_func_array($connect_function, 172 $params); 173 } else { 174 ini_set('track_errors', 1); 175 $this->connection = @call_user_func_array($connect_function, 176 $params); 177 ini_set('track_errors', $ini); 178 } 179 180 if (!$this->connection) { 181 return $this->raiseError(DB_ERROR_CONNECT_FAILED, 182 null, null, null, 183 $php_errormsg); 184 } 185 186 if ($dsn['database']) { 187 if (!@fbsql_select_db($dsn['database'], $this->connection)) { 188 return $this->fbsqlRaiseError(); 189 } 190 } 191 192 return DB_OK; 193 } 194 195 // }}} 196 // {{{ disconnect() 197 198 /** 199 * Disconnects from the database server 200 * 201 * @return bool TRUE on success, FALSE on failure 202 */ 203 function disconnect() 204 { 205 $ret = @fbsql_close($this->connection); 206 $this->connection = null; 207 return $ret; 208 } 209 210 // }}} 211 // {{{ simpleQuery() 212 213 /** 214 * Sends a query to the database server 215 * 216 * @param string the SQL query string 217 * 218 * @return mixed + a PHP result resrouce for successful SELECT queries 219 * + the DB_OK constant for other successful queries 220 * + a DB_Error object on failure 221 */ 222 function simpleQuery($query) 223 { 224 $this->last_query = $query; 225 $query = $this->modifyQuery($query); 226 $result = @fbsql_query("$query;", $this->connection); 227 if (!$result) { 228 return $this->fbsqlRaiseError(); 229 } 230 // Determine which queries that should return data, and which 231 // should return an error code only. 232 if (DB::isManip($query)) { 233 return DB_OK; 234 } 235 return $result; 236 } 237 238 // }}} 239 // {{{ nextResult() 240 241 /** 242 * Move the internal fbsql result pointer to the next available result 243 * 244 * @param a valid fbsql result resource 245 * 246 * @access public 247 * 248 * @return true if a result is available otherwise return false 249 */ 250 function nextResult($result) 251 { 252 return @fbsql_next_result($result); 253 } 254 255 // }}} 256 // {{{ fetchInto() 257 258 /** 259 * Places a row from the result set into the given array 260 * 261 * Formating of the array and the data therein are configurable. 262 * See DB_result::fetchInto() for more information. 263 * 264 * This method is not meant to be called directly. Use 265 * DB_result::fetchInto() instead. It can't be declared "protected" 266 * because DB_result is a separate object. 267 * 268 * @param resource $result the query result resource 269 * @param array $arr the referenced array to put the data in 270 * @param int $fetchmode how the resulting array should be indexed 271 * @param int $rownum the row number to fetch (0 = first row) 272 * 273 * @return mixed DB_OK on success, NULL when the end of a result set is 274 * reached or on failure 275 * 276 * @see DB_result::fetchInto() 277 */ 278 function fetchInto($result, &$arr, $fetchmode, $rownum = null) 279 { 280 if ($rownum !== null) { 281 if (!@fbsql_data_seek($result, $rownum)) { 282 return null; 283 } 284 } 285 if ($fetchmode & DB_FETCHMODE_ASSOC) { 286 $arr = @fbsql_fetch_array($result, FBSQL_ASSOC); 287 if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { 288 $arr = array_change_key_case($arr, CASE_LOWER); 289 } 290 } else { 291 $arr = @fbsql_fetch_row($result); 292 } 293 if (!$arr) { 294 return null; 295 } 296 if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { 297 $this->_rtrimArrayValues($arr); 298 } 299 if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { 300 $this->_convertNullArrayValuesToEmpty($arr); 301 } 302 return DB_OK; 303 } 304 305 // }}} 306 // {{{ freeResult() 307 308 /** 309 * Deletes the result set and frees the memory occupied by the result set 310 * 311 * This method is not meant to be called directly. Use 312 * DB_result::free() instead. It can't be declared "protected" 313 * because DB_result is a separate object. 314 * 315 * @param resource $result PHP's query result resource 316 * 317 * @return bool TRUE on success, FALSE if $result is invalid 318 * 319 * @see DB_result::free() 320 */ 321 function freeResult($result) 322 { 323 return @fbsql_free_result($result); 324 } 325 326 // }}} 327 // {{{ autoCommit() 328 329 /** 330 * Enables or disables automatic commits 331 * 332 * @param bool $onoff true turns it on, false turns it off 333 * 334 * @return int DB_OK on success. A DB_Error object if the driver 335 * doesn't support auto-committing transactions. 336 */ 337 function autoCommit($onoff=false) 338 { 339 if ($onoff) { 340 $this->query("SET COMMIT TRUE"); 341 } else { 342 $this->query("SET COMMIT FALSE"); 343 } 344 } 345 346 // }}} 347 // {{{ commit() 348 349 /** 350 * Commits the current transaction 351 * 352 * @return int DB_OK on success. A DB_Error object on failure. 353 */ 354 function commit() 355 { 356 @fbsql_commit(); 357 } 358 359 // }}} 360 // {{{ rollback() 361 362 /** 363 * Reverts the current transaction 364 * 365 * @return int DB_OK on success. A DB_Error object on failure. 366 */ 367 function rollback() 368 { 369 @fbsql_rollback(); 370 } 371 372 // }}} 373 // {{{ numCols() 374 375 /** 376 * Gets the number of columns in a result set 377 * 378 * This method is not meant to be called directly. Use 379 * DB_result::numCols() instead. It can't be declared "protected" 380 * because DB_result is a separate object. 381 * 382 * @param resource $result PHP's query result resource 383 * 384 * @return int the number of columns. A DB_Error object on failure. 385 * 386 * @see DB_result::numCols() 387 */ 388 function numCols($result) 389 { 390 $cols = @fbsql_num_fields($result); 391 if (!$cols) { 392 return $this->fbsqlRaiseError(); 393 } 394 return $cols; 395 } 396 397 // }}} 398 // {{{ numRows() 399 400 /** 401 * Gets the number of rows in a result set 402 * 403 * This method is not meant to be called directly. Use 404 * DB_result::numRows() instead. It can't be declared "protected" 405 * because DB_result is a separate object. 406 * 407 * @param resource $result PHP's query result resource 408 * 409 * @return int the number of rows. A DB_Error object on failure. 410 * 411 * @see DB_result::numRows() 412 */ 413 function numRows($result) 414 { 415 $rows = @fbsql_num_rows($result); 416 if ($rows === null) { 417 return $this->fbsqlRaiseError(); 418 } 419 return $rows; 420 } 421 422 // }}} 423 // {{{ affectedRows() 424 425 /** 426 * Determines the number of rows affected by a data maniuplation query 427 * 428 * 0 is returned for queries that don't manipulate data. 429 * 430 * @return int the number of rows. A DB_Error object on failure. 431 */ 432 function affectedRows() 433 { 434 if (DB::isManip($this->last_query)) { 435 $result = @fbsql_affected_rows($this->connection); 436 } else { 437 $result = 0; 438 } 439 return $result; 440 } 441 442 // }}} 443 // {{{ nextId() 444 445 /** 446 * Returns the next free id in a sequence 447 * 448 * @param string $seq_name name of the sequence 449 * @param boolean $ondemand when true, the seqence is automatically 450 * created if it does not exist 451 * 452 * @return int the next id number in the sequence. 453 * A DB_Error object on failure. 454 * 455 * @see DB_common::nextID(), DB_common::getSequenceName(), 456 * DB_fbsql::createSequence(), DB_fbsql::dropSequence() 457 */ 458 function nextId($seq_name, $ondemand = true) 459 { 460 $seqname = $this->getSequenceName($seq_name); 461 do { 462 $repeat = 0; 463 $this->pushErrorHandling(PEAR_ERROR_RETURN); 464 $result = $this->query('SELECT UNIQUE FROM ' . $seqname); 465 $this->popErrorHandling(); 466 if ($ondemand && DB::isError($result) && 467 $result->getCode() == DB_ERROR_NOSUCHTABLE) { 468 $repeat = 1; 469 $result = $this->createSequence($seq_name); 470 if (DB::isError($result)) { 471 return $result; 472 } 473 } else { 474 $repeat = 0; 475 } 476 } while ($repeat); 477 if (DB::isError($result)) { 478 return $this->fbsqlRaiseError(); 479 } 480 $result->fetchInto($tmp, DB_FETCHMODE_ORDERED); 481 return $tmp[0]; 482 } 483 484 /** 485 * Creates a new sequence 486 * 487 * @param string $seq_name name of the new sequence 488 * 489 * @return int DB_OK on success. A DB_Error object on failure. 490 * 491 * @see DB_common::createSequence(), DB_common::getSequenceName(), 492 * DB_fbsql::nextID(), DB_fbsql::dropSequence() 493 */ 494 function createSequence($seq_name) 495 { 496 $seqname = $this->getSequenceName($seq_name); 497 $res = $this->query('CREATE TABLE ' . $seqname 498 . ' (id INTEGER NOT NULL,' 499 . ' PRIMARY KEY(id))'); 500 if ($res) { 501 $res = $this->query('SET UNIQUE = 0 FOR ' . $seqname); 502 } 503 return $res; 504 } 505 506 // }}} 507 // {{{ dropSequence() 508 509 /** 510 * Deletes a sequence 511 * 512 * @param string $seq_name name of the sequence to be deleted 513 * 514 * @return int DB_OK on success. A DB_Error object on failure. 515 * 516 * @see DB_common::dropSequence(), DB_common::getSequenceName(), 517 * DB_fbsql::nextID(), DB_fbsql::createSequence() 518 */ 519 function dropSequence($seq_name) 520 { 521 return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name) 522 . ' RESTRICT'); 523 } 524 525 // }}} 526 // {{{ modifyLimitQuery() 527 528 /** 529 * Adds LIMIT clauses to a query string according to current DBMS standards 530 * 531 * @param string $query the query to modify 532 * @param int $from the row to start to fetching (0 = the first row) 533 * @param int $count the numbers of rows to fetch 534 * @param mixed $params array, string or numeric data to be used in 535 * execution of the statement. Quantity of items 536 * passed must match quantity of placeholders in 537 * query: meaning 1 placeholder for non-array 538 * parameters or 1 placeholder per array element. 539 * 540 * @return string the query string with LIMIT clauses added 541 * 542 * @access protected 543 */ 544 function modifyLimitQuery($query, $from, $count, $params = array()) 545 { 546 if (DB::isManip($query)) { 547 return preg_replace('/^([\s(])*SELECT/i', 548 "\\1SELECT TOP($count)", $query); 549 } else { 550 return preg_replace('/([\s(])*SELECT/i', 551 "\\1SELECT TOP($from, $count)", $query); 552 } 553 } 554 555 // }}} 556 // {{{ quoteSmart() 557 558 /** 559 * Formats input so it can be safely used in a query 560 * 561 * @param mixed $in the data to be formatted 562 * 563 * @return mixed the formatted data. The format depends on the input's 564 * PHP type: 565 * + null = the string <samp>NULL</samp> 566 * + boolean = string <samp>TRUE</samp> or <samp>FALSE</samp> 567 * + integer or double = the unquoted number 568 * + other (including strings and numeric strings) = 569 * the data escaped according to FrontBase's settings 570 * then encapsulated between single quotes 571 * 572 * @see DB_common::quoteSmart() 573 * @since Method available since Release 1.6.0 574 */ 575 function quoteSmart($in) 576 { 577 if (is_int($in) || is_double($in)) { 578 return $in; 579 } elseif (is_bool($in)) { 580 return $in ? 'TRUE' : 'FALSE'; 581 } elseif (is_null($in)) { 582 return 'NULL'; 583 } else { 584 return "'" . $this->escapeSimple($in) . "'"; 585 } 586 } 587 588 // }}} 589 // {{{ fbsqlRaiseError() 590 591 /** 592 * Produces a DB_Error object regarding the current problem 593 * 594 * @param int $errno if the error is being manually raised pass a 595 * DB_ERROR* constant here. If this isn't passed 596 * the error information gathered from the DBMS. 597 * 598 * @return object the DB_Error object 599 * 600 * @see DB_common::raiseError(), 601 * DB_fbsql::errorNative(), DB_common::errorCode() 602 */ 603 function fbsqlRaiseError($errno = null) 604 { 605 if ($errno === null) { 606 $errno = $this->errorCode(fbsql_errno($this->connection)); 607 } 608 return $this->raiseError($errno, null, null, null, 609 @fbsql_error($this->connection)); 610 } 611 612 // }}} 613 // {{{ errorNative() 614 615 /** 616 * Gets the DBMS' native error code produced by the last query 617 * 618 * @return int the DBMS' error code 619 */ 620 function errorNative() 621 { 622 return @fbsql_errno($this->connection); 623 } 624 625 // }}} 626 // {{{ tableInfo() 627 628 /** 629 * Returns information about a table or a result set 630 * 631 * @param object|string $result DB_result object from a query or a 632 * string containing the name of a table. 633 * While this also accepts a query result 634 * resource identifier, this behavior is 635 * deprecated. 636 * @param int $mode a valid tableInfo mode 637 * 638 * @return array an associative array with the information requested. 639 * A DB_Error object on failure. 640 * 641 * @see DB_common::tableInfo() 642 */ 643 function tableInfo($result, $mode = null) 644 { 645 if (is_string($result)) { 646 /* 647 * Probably received a table name. 648 * Create a result resource identifier. 649 */ 650 $id = @fbsql_list_fields($this->dsn['database'], 651 $result, $this->connection); 652 $got_string = true; 653 } elseif (isset($result->result)) { 654 /* 655 * Probably received a result object. 656 * Extract the result resource identifier. 657 */ 658 $id = $result->result; 659 $got_string = false; 660 } else { 661 /* 662 * Probably received a result resource identifier. 663 * Copy it. 664 * Deprecated. Here for compatibility only. 665 */ 666 $id = $result; 667 $got_string = false; 668 } 669 670 if (!is_resource($id)) { 671 return $this->fbsqlRaiseError(DB_ERROR_NEED_MORE_DATA); 672 } 673 674 if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { 675 $case_func = 'strtolower'; 676 } else { 677 $case_func = 'strval'; 678 } 679 680 $count = @fbsql_num_fields($id); 681 $res = array(); 682 683 if ($mode) { 684 $res['num_fields'] = $count; 685 } 686 687 for ($i = 0; $i < $count; $i++) { 688 $res[$i] = array( 689 'table' => $case_func(@fbsql_field_table($id, $i)), 690 'name' => $case_func(@fbsql_field_name($id, $i)), 691 'type' => @fbsql_field_type($id, $i), 692 'len' => @fbsql_field_len($id, $i), 693 'flags' => @fbsql_field_flags($id, $i), 694 ); 695 if ($mode & DB_TABLEINFO_ORDER) { 696 $res['order'][$res[$i]['name']] = $i; 697 } 698 if ($mode & DB_TABLEINFO_ORDERTABLE) { 699 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; 700 } 701 } 702 703 // free the result only if we were called on a table 704 if ($got_string) { 705 @fbsql_free_result($id); 706 } 707 return $res; 708 } 709 710 // }}} 711 // {{{ getSpecialQuery() 712 713 /** 714 * Obtains the query string needed for listing a given type of objects 715 * 716 * @param string $type the kind of objects you want to retrieve 717 * 718 * @return string the SQL query string or null if the driver doesn't 719 * support the object type requested 720 * 721 * @access protected 722 * @see DB_common::getListOf() 723 */ 724 function getSpecialQuery($type) 725 { 726 switch ($type) { 727 case 'tables': 728 return 'SELECT "table_name" FROM information_schema.tables' 729 . ' t0, information_schema.schemata t1' 730 . ' WHERE t0.schema_pk=t1.schema_pk AND' 731 . ' "table_type" = \'BASE TABLE\'' 732 . ' AND "schema_name" = current_schema'; 733 case 'views': 734 return 'SELECT "table_name" FROM information_schema.tables' 735 . ' t0, information_schema.schemata t1' 736 . ' WHERE t0.schema_pk=t1.schema_pk AND' 737 . ' "table_type" = \'VIEW\'' 738 . ' AND "schema_name" = current_schema'; 739 case 'users': 740 return 'SELECT "user_name" from information_schema.users'; 741 case 'functions': 742 return 'SELECT "routine_name" FROM' 743 . ' information_schema.psm_routines' 744 . ' t0, information_schema.schemata t1' 745 . ' WHERE t0.schema_pk=t1.schema_pk' 746 . ' AND "routine_kind"=\'FUNCTION\'' 747 . ' AND "schema_name" = current_schema'; 748 case 'procedures': 749 return 'SELECT "routine_name" FROM' 750 . ' information_schema.psm_routines' 751 . ' t0, information_schema.schemata t1' 752 . ' WHERE t0.schema_pk=t1.schema_pk' 753 . ' AND "routine_kind"=\'PROCEDURE\'' 754 . ' AND "schema_name" = current_schema'; 755 default: 756 return null; 757 } 758 } 759 760 // }}} 761 } 762 763 /* 764 * Local variables: 765 * tab-width: 4 766 * c-basic-offset: 4 767 * End: 768 */ 769 770 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |