[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 // +----------------------------------------------------------------------+ 3 // | PHP Version 4 | 4 // +----------------------------------------------------------------------+ 5 // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox, | 6 // | Stig. S. Bakken, Lukas Smith | 7 // | All rights reserved. | 8 // +----------------------------------------------------------------------+ 9 // | MDB is a merge of PEAR DB and Metabases that provides a unified DB | 10 // | API as well as database abstraction for PHP applications. | 11 // | This LICENSE is in the BSD license style. | 12 // | | 13 // | Redistribution and use in source and binary forms, with or without | 14 // | modification, are permitted provided that the following conditions | 15 // | are met: | 16 // | | 17 // | Redistributions of source code must retain the above copyright | 18 // | notice, this list of conditions and the following disclaimer. | 19 // | | 20 // | Redistributions in binary form must reproduce the above copyright | 21 // | notice, this list of conditions and the following disclaimer in the | 22 // | documentation and/or other materials provided with the distribution. | 23 // | | 24 // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken, | 25 // | Lukas Smith nor the names of his contributors may be used to endorse | 26 // | or promote products derived from this software without specific prior| 27 // | written permission. | 28 // | | 29 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 30 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 31 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 32 // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | 33 // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | 34 // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | 35 // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS| 36 // | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | 37 // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 38 // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY| 39 // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 40 // | POSSIBILITY OF SUCH DAMAGE. | 41 // +----------------------------------------------------------------------+ 42 // | Author: Lukas Smith <smith@backendmedia.com> | 43 // +----------------------------------------------------------------------+ 44 // 45 // $Id: mysql.php,v 1.44.4.10 2004/04/19 20:21:51 lsmith Exp $ 46 // 47 48 if(!defined('MDB_MANAGER_MYSQL_INCLUDED')) 49 { 50 define('MDB_MANAGER_MYSQL_INCLUDED', 1); 51 52 require_once ('MDB/Modules/Manager/Common.php'); 53 54 /** 55 * MDB MySQL driver for the management modules 56 * 57 * @package MDB 58 * @category Database 59 * @access private 60 * @author Lukas Smith <smith@backendmedia.com> 61 */ 62 class MDB_Manager_mysql extends MDB_Manager_Common 63 { 64 // {{{ properties 65 var $verified_table_types = array(); 66 67 // }}} 68 // {{{ _verifyTransactionalTableType() 69 70 /** 71 * verify that chosen transactional table hanlder is available in the database 72 * 73 * @param object $db database object that is extended by this class 74 * @param string $table_type name of the table handler 75 * @return mixed MDB_OK on success, a MDB error on failure 76 * @access private 77 */ 78 function _verifyTransactionalTableType(&$db, $table_type) 79 { 80 switch(strtoupper($table_type)) { 81 case 'BERKELEYDB': 82 case 'BDB': 83 $check = array('have_bdb'); 84 break; 85 case 'INNODB': 86 $check = array('have_innobase', 'have_innodb'); 87 break; 88 case 'GEMINI': 89 $check = array('have_gemini'); 90 break; 91 case 'HEAP': 92 case 'ISAM': 93 case 'MERGE': 94 case 'MRG_MYISAM': 95 case 'MYISAM': 96 case '': 97 return(MDB_OK); 98 default: 99 return($db->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 100 'Verify transactional table', 101 $table_type.' is not a supported table type')); 102 } 103 if(isset($this->verified_table_types[$table_type]) 104 && $this->verified_table_types[$table_type] == $db->connection) 105 { 106 return(MDB_OK); 107 } 108 $not_supported = FALSE; 109 for($i=0, $j=count($check); $i<$j; ++$i) { 110 $query = 'SHOW VARIABLES LIKE '.$db->getValue('text', $check[$i]); 111 $has = $db->queryRow($query, NULL, MDB_FETCHMODE_ORDERED); 112 if (MDB::isError($has)) { 113 return $has; 114 } 115 if (is_array($has)) { 116 $not_supported = TRUE; 117 if ($has[1] == 'YES') { 118 $this->verified_table_types[$table_type] = $db->connection; 119 return(MDB_OK); 120 } 121 } 122 } 123 if ($not_supported) { 124 return($db->raiseError(MDB_ERROR_UNSUPPORTED, null, null, 125 $table_type.' is not a supported table type by this MySQL database server')); 126 } 127 return($db->raiseError(MDB_ERROR_UNSUPPORTED, null, null, 128 'could not tell if '.$table_type.' is a supported table type')); 129 } 130 131 // }}} 132 // {{{ createDatabase() 133 134 /** 135 * create a new database 136 * 137 * @param object $db database object that is extended by this class 138 * @param string $name name of the database that should be created 139 * @return mixed MDB_OK on success, a MDB error on failure 140 * @access public 141 */ 142 function createDatabase(&$db, $name) 143 { 144 if (MDB::isError($result = $db->connect())) { 145 return($result); 146 } 147 $query = 'CREATE DATABASE '.$name; 148 if(MDB::isError($db->query($query))) { 149 return($db->mysqlRaiseError()); 150 } 151 152 return(MDB_OK); 153 } 154 155 // }}} 156 // {{{ dropDatabase() 157 158 /** 159 * drop an existing database 160 * 161 * @param object $db database object that is extended by this class 162 * @param string $name name of the database that should be dropped 163 * @return mixed MDB_OK on success, a MDB error on failure 164 * @access public 165 */ 166 function dropDatabase(&$db, $name) 167 { 168 if (MDB::isError($result = $db->connect())) { 169 return($result); 170 } 171 $query = 'DROP DATABASE '.$name; 172 if(MDB::isError($db->query($query))) { 173 return($db->mysqlRaiseError()); 174 } 175 return(MDB_OK); 176 } 177 178 // }}} 179 // {{{ createTable() 180 181 /** 182 * create a new table 183 * 184 * @param object $db database object that is extended by this class 185 * @param string $name Name of the database that should be created 186 * @param array $fields Associative array that contains the definition of 187 * each field of the new table. The indexes of the array 188 * entries are the names of the fields of the table an 189 * the array entry values are associative arrays like 190 * those that are meant to be passed with the field 191 * definitions to get[Type]Declaration() functions. 192 * 193 * Example 194 * array( 195 * 196 * 'id' => array( 197 * 'type' => 'integer', 198 * 'unsigned' => 1 199 * 'notnull' => 1 200 * 'default' => 0 201 * ), 202 * 'name' => array( 203 * 'type' => 'text', 204 * 'length' => 12 205 * ), 206 * 'password' => array( 207 * 'type' => 'text', 208 * 'length' => 12 209 * ) 210 * ); 211 * @return mixed MDB_OK on success, a MDB error on failure 212 * @access public 213 */ 214 function createTable(&$db, $name, $fields) 215 { 216 if (!isset($name) || !strcmp($name, '')) { 217 return($db->raiseError(MDB_ERROR_CANNOT_CREATE, NULL, NULL, 218 'no valid table name specified')); 219 } 220 if (count($fields) == 0) { 221 return($db->raiseError(MDB_ERROR_CANNOT_CREATE, NULL, NULL, 222 'no fields specified for table "'.$name.'"')); 223 } 224 $verify = $this->_verifyTransactionalTableType($db, $db->default_table_type); 225 if(MDB::isError($verify)) { 226 return($verify); 227 } 228 if (MDB::isError($query_fields = $db->getFieldDeclarationList($fields))) { 229 return($db->raiseError(MDB_ERROR_CANNOT_CREATE, NULL, NULL, 'unkown error')); 230 } 231 if (isset($db->supported['Transactions']) 232 && $db->default_table_type=='BDB' 233 ) { 234 $query_fields .= ', dummy_primary_key INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (dummy_primary_key)'; 235 } 236 $query = "CREATE TABLE $name ($query_fields)". 237 (strlen($db->default_table_type) ? ' TYPE='.$db->default_table_type : ''); 238 239 return($db->query($query)); 240 } 241 242 // }}} 243 // {{{ alterTable() 244 245 /** 246 * alter an existing table 247 * 248 * @param object $db database object that is extended by this class 249 * @param string $name name of the table that is intended to be changed. 250 * @param array $changes associative array that contains the details of each type 251 * of change that is intended to be performed. The types of 252 * changes that are currently supported are defined as follows: 253 * 254 * name 255 * 256 * New name for the table. 257 * 258 * AddedFields 259 * 260 * Associative array with the names of fields to be added as 261 * indexes of the array. The value of each entry of the array 262 * should be set to another associative array with the properties 263 * of the fields to be added. The properties of the fields should 264 * be the same as defined by the Metabase parser. 265 * 266 * Additionally, there should be an entry named Declaration that 267 * is expected to contain the portion of the field declaration already 268 * in DBMS specific SQL code as it is used in the CREATE TABLE statement. 269 * 270 * RemovedFields 271 * 272 * Associative array with the names of fields to be removed as indexes 273 * of the array. Currently the values assigned to each entry are ignored. 274 * An empty array should be used for future compatibility. 275 * 276 * RenamedFields 277 * 278 * Associative array with the names of fields to be renamed as indexes 279 * of the array. The value of each entry of the array should be set to 280 * another associative array with the entry named name with the new 281 * field name and the entry named Declaration that is expected to contain 282 * the portion of the field declaration already in DBMS specific SQL code 283 * as it is used in the CREATE TABLE statement. 284 * 285 * ChangedFields 286 * 287 * Associative array with the names of the fields to be changed as indexes 288 * of the array. Keep in mind that if it is intended to change either the 289 * name of a field and any other properties, the ChangedFields array entries 290 * should have the new names of the fields as array indexes. 291 * 292 * The value of each entry of the array should be set to another associative 293 * array with the properties of the fields to that are meant to be changed as 294 * array entries. These entries should be assigned to the new values of the 295 * respective properties. The properties of the fields should be the same 296 * as defined by the Metabase parser. 297 * 298 * If the default property is meant to be added, removed or changed, there 299 * should also be an entry with index ChangedDefault assigned to 1. Similarly, 300 * if the notnull constraint is to be added or removed, there should also be 301 * an entry with index ChangedNotNull assigned to 1. 302 * 303 * Additionally, there should be an entry named Declaration that is expected 304 * to contain the portion of the field changed declaration already in DBMS 305 * specific SQL code as it is used in the CREATE TABLE statement. 306 * Example 307 * array( 308 * 'name' => 'userlist', 309 * 'AddedFields' => array( 310 * 'quota' => array( 311 * 'type' => 'integer', 312 * 'unsigned' => 1 313 * 'Declaration' => 'quota INT' 314 * ) 315 * ), 316 * 'RemovedFields' => array( 317 * 'file_limit' => array(), 318 * 'time_limit' => array() 319 * ), 320 * 'ChangedFields' => array( 321 * 'gender' => array( 322 * 'default' => 'M', 323 * 'ChangeDefault' => 1, 324 * 'Declaration' => "gender CHAR(1) DEFAULT 'M'" 325 * ) 326 * ), 327 * 'RenamedFields' => array( 328 * 'sex' => array( 329 * 'name' => 'gender', 330 * 'Declaration' => "gender CHAR(1) DEFAULT 'M'" 331 * ) 332 * ) 333 * ) 334 * 335 * @param boolean $check indicates whether the function should just check if the DBMS driver 336 * can perform the requested table alterations if the value is true or 337 * actually perform them otherwise. 338 * @access public 339 * 340 * @return mixed MDB_OK on success, a MDB error on failure 341 */ 342 function alterTable(&$db, $name, $changes, $check) 343 { 344 if ($check) { 345 for($change = 0,reset($changes); 346 $change < count($changes); 347 next($changes), $change++) 348 { 349 switch(key($changes)) { 350 case 'AddedFields': 351 case 'RemovedFields': 352 case 'ChangedFields': 353 case 'RenamedFields': 354 case 'name': 355 break; 356 default: 357 return($db->raiseError(MDB_ERROR_CANNOT_ALTER, NULL, NULL, 358 'Alter table: change type "'.key($changes).'" not yet supported')); 359 } 360 } 361 return(MDB_OK); 362 } else { 363 $query = (isset($changes['name']) ? 'RENAME AS '.$changes['name'] : ''); 364 if (isset($changes['AddedFields'])) { 365 $fields = $changes['AddedFields']; 366 for($field = 0, reset($fields); 367 $field<count($fields); 368 next($fields), $field++) 369 { 370 if (strcmp($query, '')) { 371 $query .= ','; 372 } 373 $query .= 'ADD '.$fields[key($fields)]['Declaration']; 374 } 375 } 376 if (isset($changes['RemovedFields'])) { 377 $fields = $changes['RemovedFields']; 378 for($field = 0,reset($fields); 379 $field<count($fields); 380 next($fields), $field++) 381 { 382 if (strcmp($query, '')) { 383 $query .= ','; 384 } 385 $query .= 'DROP '.key($fields); 386 } 387 } 388 $renamed_fields = array(); 389 if (isset($changes['RenamedFields'])) { 390 $fields = $changes['RenamedFields']; 391 for($field = 0,reset($fields); 392 $field<count($fields); 393 next($fields), $field++) 394 { 395 $renamed_fields[$fields[key($fields)]['name']] = key($fields); 396 } 397 } 398 if (isset($changes['ChangedFields'])) { 399 $fields = $changes['ChangedFields']; 400 for($field = 0,reset($fields); 401 $field<count($fields); 402 next($fields), $field++) 403 { 404 if (strcmp($query, '')) { 405 $query .= ','; 406 } 407 if (isset($renamed_fields[key($fields)])) { 408 $field_name = $renamed_fields[key($fields)]; 409 unset($renamed_fields[key($fields)]); 410 } else { 411 $field_name = key($fields); 412 } 413 $query .= "CHANGE $field_name ".$fields[key($fields)]['Declaration']; 414 } 415 } 416 if (count($renamed_fields)) 417 { 418 for($field = 0,reset($renamed_fields); 419 $field<count($renamed_fields); 420 next($renamed_fields), $field++) 421 { 422 if (strcmp($query, '')) { 423 $query .= ','; 424 } 425 $old_field_name = $renamed_fields[Key($renamed_fields)]; 426 $query .= "CHANGE $old_field_name ". 427 $changes['RenamedFields'][$old_field_name]['Declaration']; 428 } 429 } 430 return($db->query("ALTER TABLE $name $query")); 431 } 432 } 433 434 // }}} 435 // {{{ listDatabases() 436 437 /** 438 * list all databases 439 * 440 * @param object $db database object that is extended by this class 441 * @return mixed data array on success, a MDB error on failure 442 * @access public 443 */ 444 function listDatabases(&$db) 445 { 446 $result = $db->queryCol('SHOW DATABASES'); 447 if(MDB::isError($result)) { 448 return($result); 449 } 450 return($result); 451 } 452 453 // }}} 454 // {{{ listUsers() 455 456 /** 457 * list all users 458 * 459 * @param object $db database object that is extended by this class 460 * @return mixed data array on success, a MDB error on failure 461 * @access public 462 */ 463 function listUsers(&$db) 464 { 465 $result = $db->queryCol('SELECT DISTINCT USER FROM USER'); 466 if(MDB::isError($result)) { 467 return($result); 468 } 469 return($result); 470 } 471 472 // }}} 473 // {{{ listTables() 474 475 /** 476 * list all tables in the current database 477 * 478 * @param object $db database object that is extended by this class 479 * @return mixed data array on success, a MDB error on failure 480 * @access public 481 */ 482 function listTables(&$db) 483 { 484 $table_names = $db->queryCol('SHOW TABLES'); 485 if(MDB::isError($table_names)) { 486 return($table_names); 487 } 488 for($i = 0, $j = count($table_names), $tables = array(); $i < $j; ++$i) 489 { 490 if (!$this->_isSequenceName($db, $table_names[$i])) 491 $tables[] = $table_names[$i]; 492 } 493 return($tables); 494 } 495 496 // }}} 497 // {{{ listTableFields() 498 499 /** 500 * list all fields in a tables in the current database 501 * 502 * @param object $db database object that is extended by this class 503 * @param string $table name of table that should be used in method 504 * @return mixed data array on success, a MDB error on failure 505 * @access public 506 */ 507 function listTableFields(&$db, $table) 508 { 509 $result = $db->query("SHOW COLUMNS FROM $table"); 510 if(MDB::isError($result)) { 511 return($result); 512 } 513 $columns = $db->getColumnNames($result); 514 if(MDB::isError($columns)) { 515 $db->freeResult($columns); 516 return($columns); 517 } 518 if ($db->options['optimize'] != 'portability') { 519 $columns = array_change_key_case($columns); 520 } 521 if(!isset($columns['field'])) { 522 $db->freeResult($result); 523 return($db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 524 'List table fields: show columns does not return the table field names')); 525 } 526 $fields = $db->fetchCol($result, $columns['field']); 527 if (!MDB::isError($fields)) { 528 $fields = array_diff($fields, array($db->dummy_primary_key)); 529 } 530 $db->freeResult($result); 531 return($fields); 532 } 533 534 // }}} 535 // {{{ getTableFieldDefinition() 536 537 /** 538 * get the stucture of a field into an array 539 * 540 * @param object $db database object that is extended by this class 541 * @param string $table name of table that should be used in method 542 * @param string $field_name name of field that should be used in method 543 * @return mixed data array on success, a MDB error on failure 544 * @access public 545 */ 546 function getTableFieldDefinition(&$db, $table, $field_name) 547 { 548 if ($field_name == $db->dummy_primary_key) { 549 return($db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 550 'Get table field definiton: '.$db->dummy_primary_key.' is an hidden column')); 551 } 552 $result = $db->query("SHOW COLUMNS FROM $table"); 553 if(MDB::isError($result)) { 554 return($result); 555 } 556 $columns = $db->getColumnNames($result); 557 if(MDB::isError($columns)) { 558 $db->freeResult($columns); 559 return($columns); 560 } 561 if ($db->options['optimize'] != 'portability') { 562 $columns = array_change_key_case($columns); 563 } 564 if (!isset($columns[$column = 'field']) 565 || !isset($columns[$column = 'type'])) 566 { 567 $db->freeResult($result); 568 return($db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 569 'Get table field definition: show columns does not return the column '.$column)); 570 } 571 $field_column = $columns['field']; 572 $type_column = $columns['type']; 573 while (is_array($row = $db->fetchInto($result))) { 574 if ($field_name == $row[$field_column]) { 575 $db_type = strtolower($row[$type_column]); 576 $db_type = strtok($db_type, '(), '); 577 if ($db_type == 'national') { 578 $db_type = strtok('(), '); 579 } 580 $length = strtok('(), '); 581 $decimal = strtok('(), '); 582 $type = array(); 583 switch($db_type) { 584 case 'tinyint': 585 case 'smallint': 586 case 'mediumint': 587 case 'int': 588 case 'integer': 589 case 'bigint': 590 $type[0] = 'integer'; 591 if($length == '1') { 592 $type[1] = 'boolean'; 593 if (preg_match('/^[is|has]/', $field_name)) { 594 $type = array_reverse($type); 595 } 596 } 597 break; 598 case 'tinytext': 599 case 'mediumtext': 600 case 'longtext': 601 case 'text': 602 case 'char': 603 case 'varchar': 604 $type[0] = 'text'; 605 if($decimal == 'binary') { 606 $type[1] = 'blob'; 607 } elseif($length == '1') { 608 $type[1] = 'boolean'; 609 if (preg_match('/[is|has]/', $field_name)) { 610 $type = array_reverse($type); 611 } 612 } elseif(strstr($db_type, 'text')) 613 $type[1] = 'clob'; 614 break; 615 case 'enum': 616 preg_match_all('/\'.+\'/U',$row[$type_column], $matches); 617 $length = 0; 618 if(is_array($matches)) { 619 foreach($matches[0] as $value) { 620 $length = max($length, strlen($value)-2); 621 } 622 } 623 unset($decimal); 624 case 'set': 625 $type[0] = 'text'; 626 $type[1] = 'integer'; 627 break; 628 case 'date': 629 $type[0] = 'date'; 630 break; 631 case 'datetime': 632 case 'timestamp': 633 $type[0] = 'timestamp'; 634 break; 635 case 'time': 636 $type[0] = 'time'; 637 break; 638 case 'float': 639 case 'double': 640 case 'real': 641 $type[0] = 'float'; 642 break; 643 case 'decimal': 644 case 'numeric': 645 $type[0] = 'decimal'; 646 break; 647 case 'tinyblob': 648 case 'mediumblob': 649 case 'longblob': 650 case 'blob': 651 $type[0] = 'blob'; 652 $type[1] = 'text'; 653 break; 654 case 'year': 655 $type[0] = 'integer'; 656 $type[1] = 'date'; 657 break; 658 default: 659 return($db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 660 'List table fields: unknown database attribute type')); 661 } 662 unset($notnull); 663 if (isset($columns['null']) 664 && $row[$columns['null']] != 'YES') 665 { 666 $notnull = 1; 667 } 668 unset($default); 669 if (isset($columns['default']) 670 && isset($row[$columns['default']])) 671 { 672 $default = $row[$columns['default']]; 673 } 674 $definition = $field_choices = array(); 675 for($datatype = 0; $datatype < count($type); $datatype++) { 676 $field_choices[$datatype] = array('type' => $type[$datatype]); 677 if(isset($notnull)) { 678 $field_choices[$datatype]['notnull'] = 1; 679 } 680 if(isset($default)) { 681 $field_choices[$datatype]['default'] = $default; 682 } 683 if($type[$datatype] != 'boolean' 684 && $type[$datatype] != 'time' 685 && $type[$datatype] != 'date' 686 && $type[$datatype] != 'timestamp') 687 { 688 if(strlen($length)) { 689 $field_choices[$datatype]['length'] = $length; 690 } 691 } 692 } 693 $definition[0] = $field_choices; 694 if (isset($columns['extra']) 695 && isset($row[$columns['extra']]) 696 && $row[$columns['extra']] == 'auto_increment') 697 { 698 $implicit_sequence = array(); 699 $implicit_sequence['on'] = array(); 700 $implicit_sequence['on']['table'] = $table; 701 $implicit_sequence['on']['field'] = $field_name; 702 $definition[1]['name'] = $table.'_'.$field_name; 703 $definition[1]['definition'] = $implicit_sequence; 704 } 705 if (isset($columns['key']) 706 && isset($row[$columns['key']]) 707 && $row[$columns['key']] == 'PRI') 708 { 709 // check that its not just a unique field 710 $query = "SHOW INDEX FROM $table"; 711 $indexes = $db->queryAll($query, NULL, MDB_FETCHMODE_ASSOC); 712 if(MDB::isError($indexes)) { 713 return($indexes); 714 } 715 $is_primary = FALSE; 716 foreach($indexes as $index) { 717 if ($db->options['optimize'] != 'portability') { 718 array_change_key_case($index); 719 } 720 if ($index['key_name'] == 'PRIMARY' 721 && $index['column_name'] == $field_name 722 ) { 723 $is_primary = TRUE; 724 break; 725 } 726 } 727 if($is_primary) { 728 $implicit_index = array(); 729 $implicit_index['unique'] = 1; 730 $implicit_index['FIELDS'][$field_name] = ''; 731 $definition[2]['name'] = $field_name; 732 $definition[2]['definition'] = $implicit_index; 733 } 734 } 735 $db->freeResult($result); 736 return($definition); 737 } 738 } 739 if(!$db->options['autofree']) { 740 $db->freeResult($result); 741 } 742 if(MDB::isError($row)) { 743 return($row); 744 } 745 return($db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 746 'Get table field definition: it was not specified an existing table column')); 747 } 748 749 // }}} 750 // {{{ createIndex() 751 752 /** 753 * get the stucture of a field into an array 754 * 755 * @param object $db database object that is extended by this class 756 * @param string $table name of the table on which the index is to be created 757 * @param string $name name of the index to be created 758 * @param array $definition associative array that defines properties of the index to be created. 759 * Currently, only one property named FIELDS is supported. This property 760 * is also an associative with the names of the index fields as array 761 * indexes. Each entry of this array is set to another type of associative 762 * array that specifies properties of the index that are specific to 763 * each field. 764 * 765 * Currently, only the sorting property is supported. It should be used 766 * to define the sorting direction of the index. It may be set to either 767 * ascending or descending. 768 * 769 * Not all DBMS support index sorting direction configuration. The DBMS 770 * drivers of those that do not support it ignore this property. Use the 771 * function support() to determine whether the DBMS driver can manage indexes. 772 773 * Example 774 * array( 775 * 'FIELDS' => array( 776 * 'user_name' => array( 777 * 'sorting' => 'ascending' 778 * ), 779 * 'last_login' => array() 780 * ) 781 * ) 782 * @return mixed MDB_OK on success, a MDB error on failure 783 * @access public 784 */ 785 function createIndex(&$db, $table, $name, $definition) 786 { 787 $query = "ALTER TABLE $table ADD ".(isset($definition['unique']) ? 'UNIQUE' : 'INDEX') 788 ." $name ("; 789 for($field = 0, reset($definition['FIELDS']); 790 $field < count($definition['FIELDS']); 791 $field++, next($definition['FIELDS'])) 792 { 793 if ($field > 0) { 794 $query .= ','; 795 } 796 $query .= key($definition['FIELDS']); 797 } 798 $query .= ')'; 799 return($db->query($query)); 800 } 801 802 // }}} 803 // {{{ dropIndex() 804 805 /** 806 * drop existing index 807 * 808 * @param object $db database object that is extended by this class 809 * @param string $table name of table that should be used in method 810 * @param string $name name of the index to be dropped 811 * @return mixed MDB_OK on success, a MDB error on failure 812 * @access public 813 */ 814 function dropIndex(&$db, $table, $name) 815 { 816 return($db->query("ALTER TABLE $table DROP INDEX $name")); 817 } 818 819 // }}} 820 // {{{ listTableIndexes() 821 822 /** 823 * list all indexes in a table 824 * 825 * @param object $db database object that is extended by this class 826 * @param string $table name of table that should be used in method 827 * @return mixed data array on success, a MDB error on failure 828 * @access public 829 */ 830 function listTableIndexes(&$db, $table) 831 { 832 if(MDB::isError($result = $db->query("SHOW INDEX FROM $table"))) { 833 return($result); 834 } 835 $key_name = 'Key_name'; 836 if ($db->options['optimize'] != 'portability') { 837 $key_name = strtolower($key_name); 838 } 839 $indexes_all = $db->fetchCol($result, $key_name); 840 for($found = $indexes = array(), $index = 0, $indexes_all_cnt = count($indexes_all); 841 $index < $indexes_all_cnt; 842 $index++) 843 { 844 if ($indexes_all[$index] != 'PRIMARY' 845 && !isset($found[$indexes_all[$index]])) 846 { 847 $indexes[] = $indexes_all[$index]; 848 $found[$indexes_all[$index]] = 1; 849 } 850 } 851 return($indexes); 852 } 853 854 // }}} 855 // {{{ getTableIndexDefinition() 856 857 /** 858 * get the stucture of an index into an array 859 * 860 * @param object $db database object that is extended by this class 861 * @param string $table name of table that should be used in method 862 * @param string $index_name name of index that should be used in method 863 * @return mixed data array on success, a MDB error on failure 864 * @access public 865 */ 866 function getTableIndexDefinition(&$db, $table, $index_name) 867 { 868 if($index_name == 'PRIMARY') { 869 return($db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 870 'Get table index definition: PRIMARY is an hidden index')); 871 } 872 if(MDB::isError($result = $db->query("SHOW INDEX FROM $table"))) { 873 return($result); 874 } 875 $definition = array(); 876 while (is_array($row = $db->fetchInto($result, MDB_FETCHMODE_ASSOC))) { 877 if ($db->options['optimize'] != 'portability') { 878 $row = array_change_key_case($row); 879 } 880 $key_name = $row['key_name']; 881 if(!strcmp($index_name, $key_name)) { 882 if(!$row['non_unique']) { 883 $definition[$index_name]['unique'] = 1; 884 } 885 $column_name = $row['column_name']; 886 $definition['FIELDS'][$column_name] = array(); 887 if(isset($row['collation'])) { 888 $definition['FIELDS'][$column_name]['sorting'] = ($row['collation'] == 'A' ? 'ascending' : 'descending'); 889 } 890 } 891 } 892 $db->freeResult($result); 893 if (!isset($definition['FIELDS'])) { 894 return($db->raiseError(MDB_ERROR_MANAGER, NULL, NULL, 895 'Get table index definition: it was not specified an existing table index')); 896 } 897 return($definition); 898 } 899 900 // }}} 901 // {{{ createSequence() 902 903 /** 904 * create sequence 905 * 906 * @param object $db database object that is extended by this class 907 * @param string $seq_name name of the sequence to be created 908 * @param string $start start value of the sequence; default is 1 909 * @return mixed MDB_OK on success, a MDB error on failure 910 * @access public 911 */ 912 function createSequence(&$db, $seq_name, $start) 913 { 914 $sequence_name = $db->getSequenceName($seq_name); 915 $res = $db->query("CREATE TABLE $sequence_name 916 (".$db->options['sequence_col_name']." INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (" 917 .$db->options['sequence_col_name']."))"); 918 if (MDB::isError($res)) { 919 return($res); 920 } 921 if ($start == 1) { 922 return(MDB_OK); 923 } 924 $res = $db->query("INSERT INTO $sequence_name (".$db->options['sequence_col_name'].") VALUES (".($start-1).')'); 925 if (!MDB::isError($res)) { 926 return(MDB_OK); 927 } 928 // Handle error 929 $result = $db->query("DROP TABLE $sequence_name"); 930 if (MDB::isError($result)) { 931 return($db->raiseError(MDB_ERROR, NULL, NULL, 932 'Create sequence: could not drop inconsistent sequence table ('. 933 $result->getMessage().' ('.$result->getUserinfo().'))')); 934 } 935 return($db->raiseError(MDB_ERROR, NULL, NULL, 936 'Create sequence: could not create sequence table ('. 937 $res->getMessage().' ('.$res->getUserinfo().'))')); 938 } 939 940 // }}} 941 // {{{ dropSequence() 942 943 /** 944 * drop existing sequence 945 * 946 * @param object $db database object that is extended by this class 947 * @param string $seq_name name of the sequence to be dropped 948 * @return mixed MDB_OK on success, a MDB error on failure 949 * @access public 950 */ 951 function dropSequence(&$db, $seq_name) 952 { 953 $sequence_name = $db->getSequenceName($seq_name); 954 return($db->query("DROP TABLE $sequence_name")); 955 } 956 957 // }}} 958 // {{{ listSequences() 959 960 /** 961 * list all sequences in the current database 962 * 963 * @param object $db database object that is extended by this class 964 * @return mixed data array on success, a MDB error on failure 965 * @access public 966 */ 967 function listSequences(&$db) 968 { 969 $table_names = $db->queryCol('SHOW TABLES'); 970 if(MDB::isError($table_names)) { 971 return($table_names); 972 } 973 for($i = 0, $j = count($table_names), $sequences = array(); $i < $j; ++$i) 974 { 975 if ($sqn = $this->_isSequenceName($db, $table_names[$i])) 976 $sequences[] = $sqn; 977 } 978 return($sequences); 979 } 980 981 // }}} 982 } 983 984 }; 985 ?>
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 |