| [ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 // vim: set et ts=4 sw=4 fdm=marker: 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, | 7 // | Stig. S. Bakken, Lukas Smith | 8 // | All rights reserved. | 9 // +----------------------------------------------------------------------+ 10 // | MDB is a merge of PEAR DB and Metabases that provides a unified DB | 11 // | API as well as database abstraction for PHP applications. | 12 // | This LICENSE is in the BSD license style. | 13 // | | 14 // | Redistribution and use in source and binary forms, with or without | 15 // | modification, are permitted provided that the following conditions | 16 // | are met: | 17 // | | 18 // | Redistributions of source code must retain the above copyright | 19 // | notice, this list of conditions and the following disclaimer. | 20 // | | 21 // | Redistributions in binary form must reproduce the above copyright | 22 // | notice, this list of conditions and the following disclaimer in the | 23 // | documentation and/or other materials provided with the distribution. | 24 // | | 25 // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | 26 // | Lukas Smith nor the names of his contributors may be used to endorse | 27 // | or promote products derived from this software without specific prior| 28 // | written permission. | 29 // | | 30 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 31 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 32 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 33 // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 34 // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | 35 // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | 36 // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| 37 // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | 38 // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 39 // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| 40 // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 41 // | POSSIBILITY OF SUCH DAMAGE. | 42 // +----------------------------------------------------------------------+ 43 // | Author: Lukas Smith <smith@backendmedia.com> | 44 // +----------------------------------------------------------------------+ 45 // 46 // $Id: mysql.php,v 1.80.4.18 2004/04/22 11:31:56 lsmith Exp $ 47 // 48 49 require_once ('MDB/Common.php'); 50 51 /** 52 * MDB MySQL driver 53 * 54 * Notes: 55 * - The decimal type fields are emulated with integer fields. 56 * 57 * @package MDB 58 * @category Database 59 * @author Lukas Smith <smith@backendmedia.com> 60 */ 61 class MDB_mysql extends MDB_Common 62 { 63 // {{{ properties 64 65 var $connection = 0; 66 var $connected_host; 67 var $connected_user; 68 var $connected_password; 69 var $connected_port; 70 var $opened_persistent = ''; 71 72 var $escape_quotes = "\\"; 73 var $decimal_factor = 1.0; 74 75 var $highest_fetched_row = array(); 76 var $columns = array(); 77 78 // MySQL specific class variable 79 var $default_table_type = ''; 80 var $fixed_float = 0; 81 var $dummy_primary_key = 'dummy_primary_key'; 82 83 // }}} 84 // {{{ constructor 85 86 /** 87 * Constructor 88 */ 89 function MDB_mysql() 90 { 91 $this->MDB_Common(); 92 $this->phptype = 'mysql'; 93 $this->dbsyntax = 'mysql'; 94 95 $this->supported['Sequences'] = 1; 96 $this->supported['Indexes'] = 1; 97 $this->supported['AffectedRows'] = 1; 98 $this->supported['Summaryfunctions'] = 1; 99 $this->supported['OrderByText'] = 1; 100 $this->supported['CurrId'] = 1; 101 $this->supported['SelectRowRanges'] = 1; 102 $this->supported['LOBs'] = 1; 103 $this->supported['Replace'] = 1; 104 $this->supported['SubSelects'] = 0; 105 $this->supported['Transactions'] = 0; 106 107 $this->decimal_factor = pow(10.0, $this->decimal_places); 108 109 $this->options['DefaultTableType'] = FALSE; 110 $this->options['fixed_float'] = FALSE; 111 112 $this->errorcode_map = array( 113 1004 => MDB_ERROR_CANNOT_CREATE, 114 1005 => MDB_ERROR_CANNOT_CREATE, 115 1006 => MDB_ERROR_CANNOT_CREATE, 116 1007 => MDB_ERROR_ALREADY_EXISTS, 117 1008 => MDB_ERROR_CANNOT_DROP, 118 1022 => MDB_ERROR_ALREADY_EXISTS, 119 1046 => MDB_ERROR_NODBSELECTED, 120 1050 => MDB_ERROR_ALREADY_EXISTS, 121 1051 => MDB_ERROR_NOSUCHTABLE, 122 1054 => MDB_ERROR_NOSUCHFIELD, 123 1062 => MDB_ERROR_ALREADY_EXISTS, 124 1064 => MDB_ERROR_SYNTAX, 125 1100 => MDB_ERROR_NOT_LOCKED, 126 1136 => MDB_ERROR_VALUE_COUNT_ON_ROW, 127 1146 => MDB_ERROR_NOSUCHTABLE, 128 1048 => MDB_ERROR_CONSTRAINT, 129 1213 => MDB_ERROR_DEADLOCK, 130 1216 => MDB_ERROR_CONSTRAINT, 131 ); 132 } 133 134 // }}} 135 // {{{ errorNative() 136 137 /** 138 * Get the native error code of the last error (if any) that 139 * occured on the current connection. 140 * 141 * @access public 142 * 143 * @return int native MySQL error code 144 */ 145 function errorNative() 146 { 147 return(@mysql_errno($this->connection)); 148 } 149 150 // }}} 151 // {{{ mysqlRaiseError() 152 153 /** 154 * This method is used to communicate an error and invoke error 155 * callbacks etc. Basically a wrapper for MDB::raiseError 156 * that checks for native error msgs. 157 * 158 * @param integer $errno error code 159 * @param string $message userinfo message 160 * @return object a PEAR error object 161 * @access public 162 * @see PEAR_Error 163 */ 164 function mysqlRaiseError($errno = NULL, $message = NULL) 165 { 166 if ($errno == NULL) { 167 if ($this->connection) { 168 $errno = @mysql_errno($this->connection); 169 } else { 170 $errno = @mysql_errno(); 171 } 172 } 173 if ($this->connection) { 174 $error = @mysql_errno($this->connection); 175 } else { 176 $error = @mysql_error(); 177 } 178 return($this->raiseError($this->errorCode($errno), NULL, NULL, 179 $message, $error)); 180 } 181 182 // }}} 183 // {{{ quoteIdentifier() 184 185 /** 186 * Quote a string so it can be safely used as a table or column name 187 * 188 * Quoting style depends on which database driver is being used. 189 * 190 * MySQL can't handle the backtick character (<kbd>`</kbd>) in 191 * table or column names. 192 * 193 * @param string $str identifier name to be quoted 194 * 195 * @return string quoted identifier string 196 * 197 * @access public 198 * @internal 199 */ 200 function quoteIdentifier($str) 201 { 202 return '`' . $str . '`'; 203 } 204 205 // }}} 206 // {{{ autoCommit() 207 208 /** 209 * Define whether database changes done on the database be automatically 210 * committed. This function may also implicitly start or end a transaction. 211 * 212 * @param boolean $auto_commit flag that indicates whether the database 213 * changes should be committed right after 214 * executing every query statement. If this 215 * argument is 0 a transaction implicitly 216 * started. Otherwise, if a transaction is 217 * in progress it is ended by committing any 218 * database changes that were pending. 219 * 220 * @access public 221 * 222 * @return mixed MDB_OK on success, a MDB error on failure 223 */ 224 function autoCommit($auto_commit) 225 { 226 $this->debug("AutoCommit: ".($auto_commit ? "On" : "Off")); 227 if (!isset($this->supported['Transactions'])) { 228 return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 229 'Auto-commit transactions: transactions are not in use')); 230 } 231 if ($this->auto_commit == $auto_commit) { 232 return(MDB_OK); 233 } 234 if ($this->connection) { 235 if ($auto_commit) { 236 $result = $this->query('COMMIT'); 237 if (MDB::isError($result)) { 238 return($result); 239 } 240 $result = $this->query('SET AUTOCOMMIT = 1'); 241 if (MDB::isError($result)) { 242 return($result); 243 } 244 } else { 245 $result = $this->query('SET AUTOCOMMIT = 0'); 246 if (MDB::isError($result)) { 247 return($result); 248 } 249 } 250 } 251 $this->auto_commit = $auto_commit; 252 $this->in_transaction = !$auto_commit; 253 return(MDB_OK); 254 } 255 256 // }}} 257 // {{{ commit() 258 259 /** 260 * Commit the database changes done during a transaction that is in 261 * progress. This function may only be called when auto-committing is 262 * disabled, otherwise it will fail. Therefore, a new transaction is 263 * implicitly started after committing the pending changes. 264 * 265 * @access public 266 * 267 * @return mixed MDB_OK on success, a MDB error on failure 268 */ 269 function commit() 270 { 271 $this->debug("Commit Transaction"); 272 if (!isset($this->supported['Transactions'])) { 273 return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 274 'Commit transactions: transactions are not in use')); 275 } 276 if ($this->auto_commit) { 277 return($this->raiseError(MDB_ERROR, NULL, NULL, 278 'Commit transactions: transaction changes are being auto commited')); 279 } 280 return($this->query('COMMIT')); 281 } 282 283 // }}} 284 // {{{ rollback() 285 286 /** 287 * Cancel any database changes done during a transaction that is in 288 * progress. This function may only be called when auto-committing is 289 * disabled, otherwise it will fail. Therefore, a new transaction is 290 * implicitly started after canceling the pending changes. 291 * 292 * @access public 293 * 294 * @return mixed MDB_OK on success, a MDB error on failure 295 */ 296 function rollback() 297 { 298 $this->debug("Rollback Transaction"); 299 if (!isset($this->supported['Transactions'])) { 300 return($this->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 301 'Rollback transactions: transactions are not in use')); 302 } 303 if ($this->auto_commit) { 304 return($this->raiseError(MDB_ERROR, NULL, NULL, 305 'Rollback transactions: transactions can not be rolled back when changes are auto commited')); 306 } 307 return($this->query('ROLLBACK')); 308 } 309 310 // }}} 311 // {{{ connect() 312 313 /** 314 * Connect to the database 315 * 316 * @return TRUE on success, MDB_Error on failure 317 **/ 318 function connect() 319 { 320 $port = (isset($this->port) ? $this->port : ''); 321 if($this->connection != 0) { 322 if (!strcmp($this->connected_host, $this->host) 323 && !strcmp($this->connected_user, $this->user) 324 && !strcmp($this->connected_password, $this->password) 325 && !strcmp($this->connected_port, $port) 326 && $this->opened_persistent == $this->options['persistent']) 327 { 328 return(MDB_OK); 329 } 330 @mysql_close($this->connection); 331 $this->connection = 0; 332 $this->affected_rows = -1; 333 } 334 335 if(!PEAR::loadExtension($this->phptype)) { 336 return(PEAR::raiseError(NULL, MDB_ERROR_NOT_FOUND, 337 NULL, NULL, 'extension '.$this->phptype.' is not compiled into PHP', 338 'MDB_Error', TRUE)); 339 } 340 $UseTransactions = $this->getOption('UseTransactions'); 341 if(!MDB::isError($UseTransactions) && $UseTransactions) { 342 $this->supported['Transactions'] = 1; 343 $this->default_table_type = 'BDB'; 344 } else { 345 $this->supported['Transactions'] = 0; 346 $this->default_table_type = ''; 347 } 348 $DefaultTableType = $this->getOption('DefaultTableType'); 349 if(!MDB::isError($DefaultTableType) && $DefaultTableType) { 350 switch($this->default_table_type = strtoupper($DefaultTableType)) { 351 case 'BERKELEYDB': 352 $this->default_table_type = 'BDB'; 353 case 'BDB': 354 case 'INNODB': 355 case 'GEMINI': 356 break; 357 case 'HEAP': 358 case 'ISAM': 359 case 'MERGE': 360 case 'MRG_MYISAM': 361 case 'MYISAM': 362 if(isset($this->supported['Transactions'])) { 363 $this->warnings[] = $DefaultTableType 364 .' is not a transaction-safe default table type'; 365 } 366 break; 367 default: 368 $this->warnings[] = $DefaultTableType 369 .' is not a supported default table type'; 370 } 371 } 372 373 $this->fixed_float = 30; 374 $function = ($this->options['persistent'] ? 'mysql_pconnect' : 'mysql_connect'); 375 if (!function_exists($function)) { 376 return($this->raiseError(MDB_ERROR_UNSUPPORTED)); 377 } 378 379 @ini_set('track_errors', TRUE); 380 $this->connection = @$function( 381 $this->host.(!strcmp($port,'') ? '' : ':'.$port), 382 $this->user, $this->password); 383 @ini_restore('track_errors'); 384 if ($this->connection <= 0) { 385 return($this->raiseError(MDB_ERROR_CONNECT_FAILED, NULL, NULL, 386 $php_errormsg)); 387 } 388 389 if (isset($this->options['fixedfloat'])) { 390 $this->fixed_float = $this->options['fixedfloat']; 391 } else { 392 if (($result = @mysql_query('SELECT VERSION()', $this->connection))) { 393 $version = explode('.', @mysql_result($result,0,0)); 394 $major = intval($version[0]); 395 $minor = intval($version[1]); 396 $revision = intval($version[2]); 397 if ($major > 3 || ($major == 3 && $minor >= 23 398 && ($minor > 23 || $revision >= 6))) 399 { 400 $this->fixed_float = 0; 401 } 402 @mysql_free_result($result); 403 } 404 } 405 if (isset($this->supported['Transactions']) && !$this->auto_commit) { 406 if (!@mysql_query('SET AUTOCOMMIT = 0', $this->connection)) { 407 @mysql_close($this->connection); 408 $this->connection = 0; 409 $this->affected_rows = -1; 410 return($this->raiseError()); 411 } 412 $this->in_transaction = TRUE; 413 } 414 $this->connected_host = $this->host; 415 $this->connected_user = $this->user; 416 $this->connected_password = $this->password; 417 $this->connected_port = $port; 418 $this->opened_persistent = $this->getoption('persistent'); 419 return(MDB_OK); 420 } 421 422 // }}} 423 // {{{ _close() 424 /** 425 * all the RDBMS specific things needed close a DB connection 426 * 427 * @return boolean 428 * @access private 429 **/ 430 function _close() 431 { 432 if ($this->connection != 0) { 433 if (isset($this->supported['Transactions']) && !$this->auto_commit) { 434 $result = $this->autoCommit(TRUE); 435 } 436 @mysql_close($this->connection); 437 $this->connection = 0; 438 $this->affected_rows = -1; 439 440 if (isset($result) && MDB::isError($result)) { 441 return($result); 442 } 443 unset($GLOBALS['_MDB_databases'][$this->database]); 444 return(TRUE); 445 } 446 return(FALSE); 447 } 448 449 // }}} 450 // {{{ query() 451 452 /** 453 * Send a query to the database and return any results 454 * 455 * @access public 456 * 457 * @param string $query the SQL query 458 * @param mixed $types array that contains the types of the columns in 459 * the result set 460 * 461 * @return mixed a result handle or MDB_OK on success, a MDB error on failure 462 */ 463 function query($query, $types = NULL) 464 { 465 $this->debug("Query: $query"); 466 $ismanip = MDB::isManip($query); 467 $this->last_query = $query; 468 $first = $this->first_selected_row; 469 $limit = $this->selected_row_limit; 470 $this->first_selected_row = $this->selected_row_limit = 0; 471 472 $result = $this->connect(); 473 if (MDB::isError($result)) { 474 return($result); 475 } 476 if($limit > 0) { 477 if ($ismanip) { 478 $query .= " LIMIT $limit"; 479 } else { 480 $query .= " LIMIT $first,$limit"; 481 } 482 } 483 if ($this->database_name) { 484 if(!@mysql_select_db($this->database_name, $this->connection)) { 485 return($this->mysqlRaiseError()); 486 } 487 } 488 if ($result = @mysql_query($query, $this->connection)) { 489 if ($ismanip) { 490 $this->affected_rows = @mysql_affected_rows($this->connection); 491 return(MDB_OK); 492 } else { 493 $result_value = intval($result); 494 $this->highest_fetched_row[$result_value] = -1; 495 if ($types != NULL) { 496 if (!is_array($types)) { 497 $types = array($types); 498 } 499 if (MDB::isError($err = $this->setResultTypes($result, $types))) { 500 $this->freeResult($result); 501 return($err); 502 } 503 } 504 return($result); 505 } 506 } 507 return($this->mysqlRaiseError()); 508 } 509 510 // }}} 511 // {{{ subSelect() 512 513 /** 514 * simple subselect emulation for Mysql 515 * 516 * @access public 517 * 518 * @param string $query the SQL query for the subselect that may only 519 * return a column 520 * @param string $quote determines if the data needs to be quoted before 521 * being returned 522 * 523 * @return string the query 524 */ 525 function subSelect($query, $quote = FALSE) 526 { 527 if($this->supported['SubSelects'] == 1) { 528 return($query); 529 } 530 $col = $this->queryCol($query); 531 if (MDB::isError($col)) { 532 return($col); 533 } 534 if(!is_array($col) || count($col) == 0) { 535 return 'NULL'; 536 } 537 if($quote) { 538 for($i = 0, $j = count($col); $i < $j; ++$i) { 539 $col[$i] = $this->getTextValue($col[$i]); 540 } 541 } 542 return(implode(', ', $col)); 543 } 544 545 // }}} 546 // {{{ replace() 547 548 /** 549 * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT 550 * query, except that if there is already a row in the table with the same 551 * key field values, the REPLACE query just updates its values instead of 552 * inserting a new row. 553 * 554 * The REPLACE type of query does not make part of the SQL standards. Since 555 * practically only MySQL implements it natively, this type of query is 556 * emulated through this method for other DBMS using standard types of 557 * queries inside a transaction to assure the atomicity of the operation. 558 * 559 * @access public 560 * 561 * @param string $table name of the table on which the REPLACE query will 562 * be executed. 563 * @param array $fields associative array that describes the fields and the 564 * values that will be inserted or updated in the specified table. The 565 * indexes of the array are the names of all the fields of the table. The 566 * values of the array are also associative arrays that describe the 567 * values and other properties of the table fields. 568 * 569 * Here follows a list of field properties that need to be specified: 570 * 571 * Value: 572 * Value to be assigned to the specified field. This value may be 573 * of specified in database independent type format as this 574 * function can perform the necessary datatype conversions. 575 * 576 * Default: 577 * this property is required unless the Null property 578 * is set to 1. 579 * 580 * Type 581 * Name of the type of the field. Currently, all types Metabase 582 * are supported except for clob and blob. 583 * 584 * Default: no type conversion 585 * 586 * Null 587 * Boolean property that indicates that the value for this field 588 * should be set to NULL. 589 * 590 * The default value for fields missing in INSERT queries may be 591 * specified the definition of a table. Often, the default value 592 * is already NULL, but since the REPLACE may be emulated using 593 * an UPDATE query, make sure that all fields of the table are 594 * listed in this function argument array. 595 * 596 * Default: 0 597 * 598 * Key 599 * Boolean property that indicates that this field should be 600 * handled as a primary key or at least as part of the compound 601 * unique index of the table that will determine the row that will 602 * updated if it exists or inserted a new row otherwise. 603 * 604 * This function will fail if no key field is specified or if the 605 * value of a key field is set to NULL because fields that are 606 * part of unique index they may not be NULL. 607 * 608 * Default: 0 609 * 610 * @return mixed MDB_OK on success, a MDB error on failure 611 */ 612 function replace($table, $fields) 613 { 614 $count = count($fields); 615 for($keys = 0, $query = $values = '',reset($fields), $field = 0; 616 $field<$count; 617 next($fields), $field++) 618 { 619 $name = key($fields); 620 if ($field > 0) { 621 $query .= ','; 622 $values .= ','; 623 } 624 $query .= $name; 625 if (isset($fields[$name]['Null']) && $fields[$name]['Null']) { 626 $value = 'NULL'; 627 } else { 628 if(isset($fields[$name]['Type'])) { 629 switch ($fields[$name]['Type']) { 630 case 'text': 631 $value = $this->getTextValue($fields[$name]['Value']); 632 break; 633 case 'boolean': 634 $value = $this->getBooleanValue($fields[$name]['Value']); 635 break; 636 case 'integer': 637 $value = $this->getIntegerValue($fields[$name]['Value']); 638 break; 639 case 'decimal': 640 $value = $this->getDecimalValue($fields[$name]['Value']); 641 break; 642 case 'float': 643 $value = $this->getFloatValue($fields[$name]['Value']); 644 break; 645 case 'date': 646 $value = $this->getDateValue($fields[$name]['Value']); 647 break; 648 case 'time': 649 $value = $this->getTimeValue($fields[$name]['Value']); 650 break; 651 case 'timestamp': 652 $value = $this->getTimestampValue($fields[$name]['Value']); 653 break; 654 default: 655 return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL, 656 'no supported type for field "' . $name . '" specified')); 657 } 658 } else { 659 $value = $fields[$name]['Value']; 660 } 661 } 662 $values .= $value; 663 if (isset($fields[$name]['Key']) && $fields[$name]['Key']) { 664 if ($value === 'NULL') { 665 return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL, 666 $name.': key values may not be NULL')); 667 } 668 $keys++; 669 } 670 } 671 if ($keys == 0) { 672 return($this->raiseError(MDB_ERROR_CANNOT_REPLACE, NULL, NULL, 673 'not specified which fields are keys')); 674 } 675 return($this->query("REPLACE INTO $table ($query) VALUES ($values)")); 676 } 677 678 // }}} 679 // {{{ getColumnNames() 680 681 /** 682 * Retrieve the names of columns returned by the DBMS in a query result. 683 * 684 * @param resource $result result identifier 685 * @return mixed an associative array variable 686 * that will hold the names of columns. The 687 * indexes of the array are the column names 688 * mapped to lower case and the values are the 689 * respective numbers of the columns starting 690 * from 0. Some DBMS may not return any 691 * columns when the result set does not 692 * contain any rows. 693 * 694 * a MDB error on failure 695 * @access public 696 */ 697 function getColumnNames($result) 698 { 699 $result_value = intval($result); 700 if (!isset($this->highest_fetched_row[$result_value])) { 701 return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL, 702 'Get column names: it was specified an inexisting result set')); 703 } 704 if (!isset($this->columns[$result_value])) { 705 $this->columns[$result_value] = array(); 706 $columns = @mysql_num_fields($result); 707 for($column = 0; $column < $columns; $column++) { 708 $field_name = @mysql_field_name($result, $column); 709 if ($this->options['optimize'] == 'portability') { 710 $field_name = strtolower($field_name); 711 } 712 $this->columns[$result_value][$field_name] = $column; 713 } 714 } 715 return($this->columns[$result_value]); 716 } 717 718 // }}} 719 // {{{ numCols() 720 721 /** 722 * Count the number of columns returned by the DBMS in a query result. 723 * 724 * @param resource $result result identifier 725 * @access public 726 * @return mixed integer value with the number of columns, a MDB error 727 * on failure 728 */ 729 function numCols($result) 730 { 731 $result_value = intval($result); 732 if (!isset($this->highest_fetched_row[$result_value])) { 733 return($this->raiseError(MDB_ERROR_INVALID, NULL, NULL, 734 'numCols: it was specified an inexisting result set')); 735 } 736 return(@mysql_num_fields($result)); 737 } 738 739 // }}} 740 // {{{ endOfResult() 741 742 /** 743 * check if the end of the result set has been reached 744 * 745 * @param resource $result result identifier 746 * @return mixed TRUE or FALSE on sucess, a MDB error on failure 747 * @access public 748 */ 749 function endOfResult($result) 750 { 751 $result_value = intval($result); 752 if (!isset($this->highest_fetched_row[$result_value])) { 753 return($this->raiseError(MDB_ERROR, NULL, NULL, 754 'End of result: attempted to check the end of an unknown result')); 755 } 756 return($this->highest_fetched_row[$result_value] >= $this->numRows($result)-1); 757 } 758 759 // }}} 760 // {{{ fetch() 761 762 /** 763 * fetch value from a result set 764 * 765 * @param resource $result result identifier 766 * @param int $row number of the row where the data can be found 767 * @param int $field field number where the data can be found 768 * @return mixed string on success, a MDB error on failure 769 * @access public 770 */ 771 function fetch($result, $row, $field) 772 { 773 $result_value = intval($result); 774 $this->highest_fetched_row[$result_value] = 775 max($this->highest_fetched_row[$result_value], $row); 776 $res = @mysql_result($result, $row, $field); 777 if ($res === FALSE && $res != NULL) { 778 return($this->mysqlRaiseError()); 779 } 780 return($res); 781 } 782 783 // }}} 784 // {{{ fetchClob() 785 786 /** 787 * fetch a clob value from a result set 788 * 789 * @param resource $result result identifier 790 * @param int $row number of the row where the data can be found 791 * @param int $field field number where the data can be found 792 * @return mixed content of the specified data cell, a MDB error on failure, 793 * a MDB error on failure 794 * @access public 795 */ 796 function fetchClob($result, $row, $field) 797 { 798 return($this->fetchLob($result, $row, $field)); 799 } 800 801 // }}} 802 // {{{ fetchBlob() 803 804 /** 805 * fetch a blob value from a result set 806 * 807 * @param resource $result result identifier 808 * @param int $row number of the row where the data can be found 809 * @param int $field field number where the data can be found 810 * @return mixed content of the specified data cell, a MDB error on failure 811 * @access public 812 */ 813 function fetchBlob($result, $row, $field) 814 { 815 return($this->fetchLob($result, $row, $field)); 816 } 817 818 // }}} 819 // {{{ convertResult() 820 821 /** 822 * convert a value to a RDBMS indepdenant MDB type 823 * 824 * @param mixed $value value to be converted 825 * @param int $type constant that specifies which type to convert to 826 * @return mixed converted value 827 * @access public 828 */ 829 function convertResult($value, $type) 830 { 831 switch($type) { 832 case MDB_TYPE_DECIMAL: 833 return(sprintf('%.'.$this->decimal_places.'f', doubleval($value)/$this->decimal_factor)); 834 default: 835 return($this->_baseConvertResult($value, $type)); 836 } 837 } 838 839 // }}} 840 // {{{ numRows() 841 842 /** 843 * returns the number of rows in a result object 844 * 845 * @param ressource $result a valid result ressouce pointer 846 * @return mixed MDB_Error or the number of rows 847 * @access public 848 */ 849 function numRows($result) 850 { 851 return(@mysql_num_rows($result)); 852 } 853 854 // }}} 855 // {{{ freeResult() 856 857 /** 858 * Free the internal resources associated with $result. 859 * 860 * @param $result result identifier 861 * @return boolean TRUE on success, FALSE if $result is invalid 862 * @access public 863 */ 864 function freeResult($result) 865 { 866 $result_value = intval($result); 867 if(isset($this->highest_fetched_row[$result_value])) { 868 unset($this->highest_fetched_row[$result_value]); 869 } 870 if(isset($this->columns[$result_value])) { 871 unset($this->columns[$result_value]); 872 } 873 if(isset($this->result_types[$result_value])) { 874 unset($this->result_types[$result_value]); 875 } 876 return(@mysql_free_result($result)); 877 } 878 879 // }}} 880 // {{{ getIntegerDeclaration() 881 882 /** 883 * Obtain DBMS specific SQL code portion needed to declare an integer type 884 * field to be used in statements like CREATE TABLE. 885 * 886 * @param string $name name the field to be declared. 887 * @param string $field associative array with the name of the properties 888 * of the field being declared as array indexes. 889 * Currently, the types of supported field 890 * properties are as follows: 891 * 892 * unsigned 893 * Boolean flag that indicates whether the field 894 * should be declared as unsigned integer if 895 * possible. 896 * 897 * default 898 * Integer value to be used as default for this 899 * field. 900 * 901 * notnull 902 * Boolean flag that indicates whether this field is 903 * constrained to not be set to NULL. 904 * @return string DBMS specific SQL code portion that should be used to 905 * declare the specified field. 906 * @access public 907 */ 908 function getIntegerDeclaration($name, $field) 909 { 910 return("$name INT". 911 (isset($field['unsigned']) ? ' UNSIGNED' : ''). 912 (isset($field['default']) ? ' DEFAULT '.$field['default'] : ''). 913 (isset($field['notnull']) ? ' NOT NULL' : '') 914 ); 915 } 916 917 // }}} 918 // {{{ getClobDeclaration() 919 920 /** 921 * Obtain DBMS specific SQL code portion needed to declare an character 922 * large object type field to be used in statements like CREATE TABLE. 923 * 924 * @param string $name name the field to be declared. 925 * @param string $field associative array with the name of the 926 * properties of the field being declared as array 927 * indexes. Currently, the types of supported field 928 * properties are as follows: 929 * 930 * length 931 * Integer value that determines the maximum length 932 * of the large object field. If this argument is 933 * missing the field should be declared to have the 934 * longest length allowed by the DBMS. 935 * 936 * notnull 937 * Boolean flag that indicates whether this field 938 * is constrained to not be set to NULL. 939 * @return string DBMS specific SQL code portion that should be used to 940 * declare the specified field. 941 * @access public 942 */ 943 function getClobDeclaration($name, $field) 944 { 945 if (isset($field['length'])) { 946 $length = $field['length']; 947 if ($length <= 255) { 948 $type = 'TINYTEXT'; 949 } else { 950 if ($length <= 65535) { 951 $type = 'TEXT'; 952 } else { 953 if ($length <= 16777215) { 954 $type = 'MEDIUMTEXT'; 955 } else { 956 $type = 'LONGTEXT'; 957 } 958 } 959 } 960 } else { 961 $type = 'LONGTEXT'; 962 } 963 return("$name $type". 964 (isset($field['notnull']) ? ' NOT NULL' : '')); 965 } 966 967 // }}} 968 // {{{ getBlobDeclaration() 969 970 /** 971 * Obtain DBMS specific SQL code portion needed to declare an binary large 972 * object type field to be used in statements like CREATE TABLE. 973 * 974 * @param string $name name the field to be declared. 975 * @param string $field associative array with the name of the properties 976 * of the field being declared as array indexes. 977 * Currently, the types of supported field 978 * properties are as follows: 979 * 980 * length 981 * Integer value that determines the maximum length 982 * of the large object field. If this argument is 983 * missing the field should be declared to have the 984 * longest length allowed by the DBMS. 985 * 986 * notnull 987 * Boolean flag that indicates whether this field is 988 * constrained to not be set to NULL. 989 * @return string DBMS specific SQL code portion that should be used to 990 * declare the specified field. 991 * @access public 992 */ 993 function getBlobDeclaration($name, $field) 994 { 995 if (isset($field['length'])) { 996 $length = $field['length']; 997 if ($length <= 255) { 998 $type = 'TINYBLOB'; 999 } else { 1000 if ($length <= 65535) { 1001 $type = 'BLOB'; 1002 } else { 1003 if ($length <= 16777215) { 1004 $type = 'MEDIUMBLOB'; 1005 } else { 1006 $type = 'LONGBLOB'; 1007 } 1008 } 1009 } 1010 } 1011 else { 1012 $type = 'LONGBLOB'; 1013 } 1014 return("$name $type". 1015 (isset($field['notnull']) ? ' NOT NULL' : '')); 1016 } 1017 1018 // }}} 1019 // {{{ getDateDeclaration() 1020 1021 /** 1022 * Obtain DBMS specific SQL code portion needed to declare an date type 1023 * field to be used in statements like CREATE TABLE. 1024 * 1025 * @param string $name name the field to be declared. 1026 * @param string $field associative array with the name of the properties 1027 * of the field being declared as array indexes. 1028 * Currently, the types of supported field properties 1029 * are as follows: 1030 * 1031 * default 1032 * Date value to be used as default for this field. 1033 * 1034 * notnull 1035 * Boolean flag that indicates whether this field is 1036 * constrained to not be set to NULL. 1037 * @return string DBMS specific SQL code portion that should be used to 1038 * declare the specified field. 1039 * @access public 1040 */ 1041 function getDateDeclaration($name, $field) 1042 { 1043 return("$name DATE". 1044 (isset($field['default']) ? " DEFAULT '".$field['default']."'" : ''). 1045 (isset($field['notnull']) ? ' NOT NULL' : '') 1046 ); 1047 } 1048 1049 // }}} 1050 // {{{ getTimestampDeclaration() 1051 1052 /** 1053 * Obtain DBMS specific SQL code portion needed to declare an timestamp 1054 * type field to be used in statements like CREATE TABLE. 1055 * 1056 * @param string $name name the field to be declared. 1057 * @param string $field associative array with the name of the properties 1058 * of the field being declared as array indexes. 1059 * Currently, the types of supported field 1060 * properties are as follows: 1061 * 1062 * default 1063 * Time stamp value to be used as default for this 1064 * field. 1065 * 1066 * notnull 1067 * Boolean flag that indicates whether this field is 1068 * constrained to not be set to NULL. 1069 * @return string DBMS specific SQL code portion that should be used to 1070 * declare the specified field. 1071 * @access public 1072 */ 1073 function getTimestampDeclaration($name, $field) 1074 { 1075 return("$name DATETIME". 1076 (isset($field['default']) ? " DEFAULT '".$field['default']."'" : ''). 1077 (isset($field['notnull']) ? ' NOT NULL' : '') 1078 ); 1079 } 1080 1081 // }}} 1082 // {{{ getTimeDeclaration() 1083 1084 /** 1085 * Obtain DBMS specific SQL code portion needed to declare an time type 1086 * field to be used in statements like CREATE TABLE. 1087 * 1088 * @param string $name name the field to be declared. 1089 * @param string $field associative array with the name of the properties 1090 * of the field being declared as array indexes. 1091 * Currently, the types of supported field 1092 * properties are as follows: 1093 * 1094 * default 1095 * Time value to be used as default for this field. 1096 * 1097 * notnull 1098 * Boolean flag that indicates whether this field is 1099 * constrained to not be set to NULL. 1100 * @return string DBMS specific SQL code portion that should be used to 1101 * declare the specified field. 1102 * @access public 1103 */ 1104 function getTimeDeclaration($name, $field) 1105 { 1106 return("$name TIME". 1107 (isset($field['default']) ? " DEFAULT '".$field['default']."'" : ''). 1108 (isset($field['notnull']) ? ' NOT NULL' : '') 1109 ); 1110 } 1111 1112 // }}} 1113 // {{{ getFloatDeclaration() 1114 1115 /** 1116 * Obtain DBMS specific SQL code portion needed to declare an float type 1117 * field to be used in statements like CREATE TABLE. 1118 * 1119 * @param string $name name the field to be declared. 1120 * @param string $field associative array with the name of the properties 1121 * of the field being declared as array indexes. 1122 * Currently, the types of supported field 1123 * properties are as follows: 1124 * 1125 * default 1126 * Integer value to be used as default for this 1127 * field. 1128 * 1129 * notnull 1130 * Boolean flag that indicates whether this field is 1131 * constrained to not be set to NULL. 1132 * @return string DBMS specific SQL code portion that should be used to 1133 * declare the specified field. 1134 * @access public 1135 */ 1136 function getFloatDeclaration($name, $field) 1137 { 1138 if (isset($this->options['fixedfloat'])) { 1139 $this->fixed_float = $this->options['fixedfloat']; 1140 } else { 1141 if ($this->connection == 0) { 1142 // XXX needs more checking 1143 $this->connect(); 1144 } 1145 } 1146 return("$name DOUBLE". 1147 ($this->fixed_float ? 1148 '('.($this->fixed_float + 2).','.$this->fixed_float.')' : ''). 1149 (isset($field['default']) ? 1150 ' DEFAULT '.$this->getFloatValue($field['default']) : ''). 1151 (isset($field['notnull']) ? ' NOT NULL' : '') 1152 ); 1153 } 1154 1155 // }}} 1156 // {{{ getDecimalDeclaration() 1157 1158 /** 1159 * Obtain DBMS specific SQL code portion needed to declare an decimal type 1160 * field to be used in statements like CREATE TABLE. 1161 * 1162 * @param string $name name the field to be declared. 1163 * @param string $field associative array with the name of the properties 1164 * of the field being declared as array indexes. 1165 * Currently, the types of supported field 1166 * properties are as follows: 1167 * 1168 * default 1169 * Integer value to be used as default for this 1170 * field. 1171 * 1172 * notnull 1173 * Boolean flag that indicates whether this field is 1174 * constrained to not be set to NULL. 1175 * @return string DBMS specific SQL code portion that should be used to 1176 * declare the specified field. 1177 * @access public 1178 */ 1179 function getDecimalDeclaration($name, $field) 1180 { 1181 return("$name BIGINT". 1182 (isset($field['default']) ? 1183 ' DEFAULT '.$this->getDecimalValue($field['default']) : ''). 1184 (isset($field['notnull']) ? ' NOT NULL' : '') 1185 ); 1186 } 1187 1188 // }}} 1189 // {{{ getClobValue() 1190 1191 /** 1192 * Convert a text value into a DBMS specific format that is suitable to 1193 * compose query statements. 1194 * 1195 * @param resource $prepared_query query handle from prepare() 1196 * @param $parameter 1197 * @param $clob 1198 * @return string text string that represents the given argument value in 1199 * a DBMS specific format. 1200 * @access public 1201 */ 1202 function getClobValue($prepared_query, $parameter, $clob) 1203 { 1204 $value = "'"; 1205 while(!$this->endOfLob($clob)) { 1206 if (MDB::isError($result = $this->readLob($clob, $data, $this->options['lob_buffer_length']))) { 1207 return($result); 1208 } 1209 $value .= $this->_quote($data); 1210 } 1211 $value .= "'"; 1212 return($value); 1213 } 1214 1215 // }}} 1216 // {{{ freeClobValue() 1217 1218 /** 1219 * free a character large object 1220 * 1221 * @param resource $prepared_query query handle from prepare() 1222 * @param string $clob 1223 * @return MDB_OK 1224 * @access public 1225 */ 1226 function freeClobValue($prepared_query, $clob) 1227 { 1228 unset($this->lobs[$clob]); 1229 return(MDB_OK); 1230 } 1231 1232 // }}} 1233 // {{{ getBlobValue() 1234 1235 /** 1236 * Convert a text value into a DBMS specific format that is suitable to 1237 * compose query statements. 1238 * 1239 * @param resource $prepared_query query handle from prepare() 1240 * @param $parameter 1241 * @param $blob 1242 * @return string text string that represents the given argument value in 1243 * a DBMS specific format. 1244 * @access public 1245 */ 1246 function getBlobValue($prepared_query, $parameter, $blob) 1247 { 1248 $value = "'"; 1249 while(!$this->endOfLob($blob)) { 1250 if (MDB::isError($result = $this->readLob($blob, $data, $this->options['lob_buffer_length']))) { 1251 return($result); 1252 } 1253 $value .= addslashes($data); 1254 } 1255 $value .= "'"; 1256 return($value); 1257 } 1258 1259 // }}} 1260 // {{{ freeBlobValue() 1261 1262 /** 1263 * free a binary large object 1264 * 1265 * @param resource $prepared_query query handle from prepare() 1266 * @param string $blob 1267 * @return MDB_OK 1268 * @access public 1269 */ 1270 function freeBlobValue($prepared_query, $blob) 1271 { 1272 unset($this->lobs[$blob]); 1273 return(MDB_OK); 1274 } 1275 1276 // }}} 1277 // {{{ getFloatValue() 1278 1279 /** 1280 * Convert a text value into a DBMS specific format that is suitable to 1281 * compose query statements. 1282 * 1283 * @param string $value text string value that is intended to be converted. 1284 * @return string text string that represents the given argument value in 1285 * a DBMS specific format. 1286 * @access public 1287 */ 1288 function getFloatValue($value) 1289 { 1290 return(($value === NULL) ? 'NULL' : (float)$value); 1291 } 1292 1293 // }}} 1294 // {{{ getDecimalValue() 1295 1296 /** 1297 * Convert a text value into a DBMS specific format that is suitable to 1298 * compose query statements. 1299 * 1300 * @param string $value text string value that is intended to be converted. 1301 * @return string text string that represents the given argument value in 1302 * a DBMS specific format. 1303 * @access public 1304 */ 1305 function getDecimalValue($value) 1306 { 1307 return(($value === NULL) ? 'NULL' : strval(round(doubleval($value)*$this->decimal_factor))); 1308 } 1309 1310 // }}} 1311 // {{{ nextId() 1312 1313 /** 1314 * returns the next free id of a sequence 1315 * 1316 * @param string $seq_name name of the sequence 1317 * @param boolean $ondemand when true the seqence is 1318 * automatic created, if it 1319 * not exists 1320 * 1321 * @return mixed MDB_Error or id 1322 * @access public 1323 */ 1324 function nextId($seq_name, $ondemand = TRUE) 1325 { 1326 $sequence_name = $this->getSequenceName($seq_name); 1327 $this->expectError(MDB_ERROR_NOSUCHTABLE); 1328 $result = $this->query("INSERT INTO $sequence_name (" 1329 .$this->options['sequence_col_name'].") VALUES (NULL)"); 1330 $this->popExpect(); 1331 if ($ondemand && MDB::isError($result) && 1332 $result->getCode() == MDB_ERROR_NOSUCHTABLE) 1333 { 1334 // Since we are create the sequence on demand 1335 // we know the first id = 1 so initialize the 1336 // sequence at 2 1337 $result = $this->createSequence($seq_name, 2); 1338 if (MDB::isError($result)) { 1339 return($this->raiseError(MDB_ERROR, NULL, NULL, 1340 'Next ID: on demand sequence could not be created')); 1341 } else { 1342 // First ID of a newly created sequence is 1 1343 return(1); 1344 } 1345 } 1346 $value = intval(@mysql_insert_id($this->connection)); 1347 $res = $this->query("DELETE FROM $sequence_name WHERE " 1348 .$this->options['sequence_col_name']." < $value"); 1349 if (MDB::isError($res)) { 1350 $this->warnings[] = 'Next ID: could not delete previous sequence table values'; 1351 } 1352 return($value); 1353 } 1354 1355 1356 // }}} 1357 // {{{ currId() 1358 1359 /** 1360 * returns the current id of a sequence 1361 * 1362 * @param string $seq_name name of the sequence 1363 * @return mixed MDB_Error or id 1364 * @access public 1365 */ 1366 function currId($seq_name) 1367 { 1368 $sequence_name = $this->getSequenceName($seq_name); 1369 $result = $this->query("SELECT MAX(".$this->options['sequence_col_name'].") FROM $sequence_name", 'integer'); 1370 if (MDB::isError($result)) { 1371 return($result); 1372 } 1373 1374 return($this->fetchOne($result)); 1375 } 1376 1377 // }}} 1378 // {{{ fetchInto() 1379 1380 /** 1381 * Fetch a row and insert the data into an existing array. 1382 * 1383 * @param resource $result result identifier 1384 * @param int $fetchmode how the array data should be indexed 1385 * @param int $rownum the row number to fetch 1386 * @return int data array on success, a MDB error on failure 1387 * @access public 1388 */ 1389 function fetchInto($result, $fetchmode = MDB_FETCHMODE_DEFAULT, $rownum = NULL) 1390 { 1391 $result_value = intval($result); 1392 if ($rownum == NULL) { 1393 ++$this->highest_fetched_row[$result_value]; 1394 } else { 1395 if (!@mysql_data_seek($result, $rownum)) { 1396 return(NULL); 1397 } 1398 $this->highest_fetched_row[$result_value] = 1399 max($this->highest_fetched_row[$result_value], $rownum); 1400 } 1401 if ($fetchmode == MDB_FETCHMODE_DEFAULT) { 1402 $fetchmode = $this->fetchmode; 1403 } 1404 if ($fetchmode & MDB_FETCHMODE_ASSOC) { 1405 $row = @mysql_fetch_assoc($result); 1406 if (is_array($row) && $this->options['optimize'] == 'portability') { 1407 $row = array_change_key_case($row, CASE_LOWER); 1408 } 1409 } else { 1410 $row = @mysql_fetch_row($result); 1411 } 1412 if (!$row) { 1413 if($this->options['autofree']) { 1414 $this->freeResult($result); 1415 } 1416 return(NULL); 1417 } 1418 if (isset($this->result_types[$result_value])) { 1419 $row = $this->convertResultRow($result, $row); 1420 } 1421 return($row); 1422 } 1423 1424 // }}} 1425 // {{{ nextResult() 1426 1427 /** 1428 * Move the internal mysql result pointer to the next available result 1429 * Currently not supported 1430 * 1431 * @param a valid result resource 1432 * @return true if a result is available otherwise return false 1433 * @access public 1434 */ 1435 function nextResult($result) 1436 { 1437 return(FALSE); 1438 } 1439 1440 // }}} 1441 // {{{ tableInfo() 1442 1443 /** 1444 * returns meta data about the result set 1445 * 1446 * @param resource $result result identifier 1447 * @param mixed $mode depends on implementation 1448 * @return array an nested array, or a MDB error 1449 * @access public 1450 */ 1451 function tableInfo($result, $mode = NULL) { 1452 $count = 0; 1453 $id = 0; 1454 $res = array(); 1455 1456 /* 1457 * depending on $mode, metadata returns the following values: 1458 * 1459 * - mode is false (default): 1460 * $result[]: 1461 * [0]['table'] table name 1462 * [0]['name'] field name 1463 * [0]['type'] field type 1464 * [0]['len'] field length 1465 * [0]['flags'] field flags 1466 * 1467 * - mode is MDB_TABLEINFO_ORDER 1468 * $result[]: 1469 * ['num_fields'] number of metadata records 1470 * [0]['table'] table name 1471 * [0]['name'] field name 1472 * [0]['type'] field type 1473 * [0]['len'] field length 1474 * [0]['flags'] field flags 1475 * ['order'][field name] index of field named "field name" 1476 * The last one is used, if you have a field name, but no index. 1477 * Test: if (isset($result['meta']['myfield'])) { ... 1478 * 1479 * - mode is MDB_TABLEINFO_ORDERTABLE 1480 * the same as above. but additionally 1481 * ['ordertable'][table name][field name] index of field 1482 * named 'field name' 1483 * 1484 * this is, because if you have fields from different 1485 * tables with the same field name * they override each 1486 * other with MDB_TABLEINFO_ORDER 1487 * 1488 * you can combine MDB_TABLEINFO_ORDER and 1489 * MDB_TABLEINFO_ORDERTABLE with MDB_TABLEINFO_ORDER | 1490 * MDB_TABLEINFO_ORDERTABLE * or with MDB_TABLEINFO_FULL 1491 */ 1492 1493 // if $result is a string, then we want information about a 1494 // table without a resultset 1495 if (is_string($result)) { 1496 if (MDB::isError($connect = $this->connect())) { 1497 return $connect; 1498 } 1499 $id = @mysql_list_fields($this->database_name, 1500 $result, $this->connection); 1501 if (empty($id)) { 1502 return($this->mysqlRaiseError()); 1503 } 1504 } else { // else we want information about a resultset 1505 $id = $result; 1506 if (empty($id)) { 1507 return($this->mysqlRaiseError()); 1508 } 1509 } 1510 1511 $count = @mysql_num_fields($id); 1512 1513 // made this IF due to performance (one if is faster than $count if's) 1514 if (empty($mode)) { 1515 for ($i = 0, $j = 0; $i<$count; $i++) { 1516 $name = @mysql_field_name($id, $i); 1517 if ($name != 'dummy_primary_key') { 1518 $res[$j]['table'] = @mysql_field_table($id, $i); 1519 $res[$j]['name'] = $name; 1520 $res[$j]['type'] = @mysql_field_type($id, $i); 1521 $res[$j]['len'] = @mysql_field_len($id, $i); 1522 $res[$j]['flags'] = @mysql_field_flags($id, $i); 1523 $j++; 1524 } 1525 } 1526 } else { // full 1527 $res['num_fields'] = $count; 1528 1529 for ($i = 0; $i<$count; $i++) { 1530 $name = @mysql_field_name($id, $i); 1531 if ($name != 'dummy_primary_key') { 1532 $res[$j]['table'] = @mysql_field_table($id, $i); 1533 $res[$j]['name'] = $name; 1534 $res[$j]['type'] = @mysql_field_type($id, $i); 1535 $res[$j]['len'] = @mysql_field_len($id, $i); 1536 $res[$j]['flags'] = @mysql_field_flags($id, $i); 1537 if ($mode & MDB_TABLEINFO_ORDER) { 1538 // note sure if this should be $i or $j 1539 $res['order'][$res[$j]['name']] = $i; 1540 } 1541 if ($mode & MDB_TABLEINFO_ORDERTABLE) { 1542 $res['ordertable'][$res[$j]['table']][$res[$j]['name']] = $j; 1543 } 1544 $j++; 1545 } 1546 } 1547 } 1548 1549 // free the result only if we were called on a table 1550 if (is_string($result)) { 1551 @mysql_free_result($id); 1552 } 1553 return($res); 1554 } 1555 } 1556 1557 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |