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: Common.php,v 1.33.4.2 2004/03/09 15:43:40 lsmith Exp $ 46// 47 48if(!defined('MDB_MANAGER_COMMON_INCLUDED')) 49{ 50 define('MDB_MANAGER_COMMON_INCLUDED', 1); 51 52/** 53 * Base class for the management modules that is extended by each MDB driver 54 * 55 * @package MDB 56 * @category Database 57 * @access private 58 * @author Lukas Smith <smith@backendmedia.com> 59 */ 60 61class MDB_Manager_Common 62{ 63 // }}} 64 // {{{ getFieldDeclaration() 65 66 /** 67 * get declaration of a field 68 * 69 * @param object $dbs database object that is extended by this class 70 * @param string $field_name name of the field to be created 71 * @param string $field associative array with the name of the properties 72 * of the field being declared as array indexes. Currently, the types 73 * of supported field properties are as follows: 74 * 75 * default 76 * Boolean value to be used as default for this field. 77 * 78 * notnull 79 * Boolean flag that indicates whether this field is constrained 80 * to not be set to NULL. 81 * @return mixed string on success, a MDB error on failure 82 * @access public 83 */ 84 function getFieldDeclaration(&$db, $field_name, $field) 85 { 86 if (!strcmp($field_name, '')) { 87 return($db->raiseError(MDB_ERROR_NOSUCHFIELD, NULL, NULL, 88 'Get field: it was not specified a valid field name ("'.$field_name.'")')); 89 } 90 switch($field['type']) { 91 case 'integer': 92 return($db->getIntegerDeclaration($field_name, $field)); 93 break; 94 case 'text': 95 return($db->getTextDeclaration($field_name, $field)); 96 break; 97 case 'clob': 98 return($db->getClobDeclaration($field_name, $field)); 99 break; 100 case 'blob': 101 return($db->getBlobDeclaration($field_name, $field)); 102 break; 103 case 'boolean': 104 return($db->getBooleanDeclaration($field_name, $field)); 105 break; 106 case 'date': 107 return($db->getDateDeclaration($field_name, $field)); 108 break; 109 case 'timestamp': 110 return($db->getTimestampDeclaration($field_name, $field)); 111 break; 112 case 'time': 113 return($db->getTimeDeclaration($field_name, $field)); 114 break; 115 case 'float': 116 return($db->getFloatDeclaration($field_name, $field)); 117 break; 118 case 'decimal': 119 return($db->getDecimalDeclaration($field_name, $field)); 120 break; 121 default: 122 return($db->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 123 'Get field: type "'.$field['type'].'" is not yet supported')); 124 break; 125 } 126 } 127 128 // }}} 129 // {{{ getFieldDeclarationList() 130 131 /** 132 * get declaration of a number of field in bulk 133 * 134 * @param object $dbs database object that is extended by this class 135 * @param string $fields a multidimensional associative array. 136 The first dimension determines the field name, while the second 137 dimension is keyed with the name of the properties 138 * of the field being declared as array indexes. Currently, the types 139 * of supported field properties are as follows: 140 * 141 * default 142 * Boolean value to be used as default for this field. 143 * 144 * notnull 145 * Boolean flag that indicates whether this field is constrained 146 * to not be set to NULL. 147 * 148 * default 149 * Boolean value to be used as default for this field. 150 * 151 * notnull 152 * Boolean flag that indicates whether this field is constrained 153 * to not be set to NULL. 154 * @return mixed string on success, a MDB error on failure 155 * @access public 156 */ 157 function getFieldDeclarationList(&$db, $fields) 158 { 159 if(is_array($fields)) { 160 foreach($fields as $field_name => $field) { 161 $query = $db->getFieldDeclaration($field_name, $field); 162 if (MDB::isError($query)) { 163 return($query); 164 } 165 $query_fields[] = $query; 166 } 167 return(implode(',',$query_fields)); 168 } 169 return(PEAR::raiseError(NULL, MDB_ERROR_MANAGER, NULL, NULL, 170 'the definition of the table "'.$table_name.'" does not contain any fields', 'MDB_Error', TRUE)); 171 } 172 173 // }}} 174 // {{{ _isSequenceName() 175 /** 176 * list all tables in the current database 177 * 178 * @param object $dbs database object that is extended by this class 179 * @param string $sqn string that containts name of a potential sequence 180 * @return mixed name of the sequence if $sqn is a name of a sequence, else FALSE 181 * @access private 182 */ 183 function _isSequenceName(&$db, $sqn) 184 { 185 $seq_pattern = '/^'.preg_replace('/%s/', '([a-z0-9_]+)', $db->options['seqname_format']).'$/i'; 186 $seq_name = preg_replace($seq_pattern, '\\1', $sqn); 187 if($seq_name && $sqn == $db->getSequenceName($seq_name)) { 188 return($seq_name); 189 } 190 return(FALSE); 191 } 192 193 // }}} 194 // {{{ createDatabase() 195 196 /** 197 * create a new database 198 * 199 * @param object $dbs database object that is extended by this class 200 * @param string $name name of the database that should be created 201 * @return mixed MDB_OK on success, a MDB error on failure 202 * @access public 203 */ 204 function createDatabase(&$db, $database) 205 { 206 return($db->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 207 'Create database: database creation is not supported')); 208 } 209 210 // }}} 211 // {{{ dropDatabase() 212 213 /** 214 * drop an existing database 215 * 216 * @param object $dbs database object that is extended by this class 217 * @param string $name name of the database that should be dropped 218 * @return mixed MDB_OK on success, a MDB error on failure 219 * @access public 220 */ 221 function dropDatabase(&$db, $database) 222 { 223 return($db->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 224 'Drop database: database dropping is not supported')); 225 } 226 227 // }}} 228 // {{{ createTable() 229 230 /** 231 * create a new table 232 * 233 * @param object $dbs database object that is extended by this class 234 * @param string $name Name of the database that should be created 235 * @param array $fields Associative array that contains the definition of each field of the new table 236 * The indexes of the array entries are the names of the fields of the table an 237 * the array entry values are associative arrays like those that are meant to be 238 * passed with the field definitions to get[Type]Declaration() functions. 239 * 240 * Example 241 * array( 242 * 243 * 'id' => array( 244 * 'type' => 'integer', 245 * 'unsigned' => 1 246 * 'notnull' => 1 247 * 'default' => 0 248 * ), 249 * 'name' => array( 250 * 'type' => 'text', 251 * 'length' => 12 252 * ), 253 * 'password' => array( 254 * 'type' => 'text', 255 * 'length' => 12 256 * ) 257 * ); 258 * @return mixed MDB_OK on success, a MDB error on failure 259 * @access public 260 */ 261 function createTable(&$db, $name, $fields) 262 { 263 if (!isset($name) || !strcmp($name, '')) { 264 return($db->raiseError(MDB_ERROR_CANNOT_CREATE, NULL, NULL, 'no valid table name specified')); 265 } 266 if (count($fields) == 0) { 267 return($db->raiseError(MDB_ERROR_CANNOT_CREATE, NULL, NULL, 'no fields specified for table "'.$name.'"')); 268 } 269 if (MDB::isError($query_fields = $db->getFieldDeclarationList($fields))) { 270 return($query_fields); 271 } 272 return($db->query("CREATE TABLE $name ($query_fields)")); 273 } 274 275 // }}} 276 // {{{ dropTable() 277 278 /** 279 * drop an existing table 280 * 281 * @param object $dbs database object that is extended by this class 282 * @param string $name name of the table that should be dropped 283 * @return mixed MDB_OK on success, a MDB error on failure 284 * @access public 285 */ 286 function dropTable(&$db, $name) 287 { 288 return($db->query("DROP TABLE $name")); 289 } 290 291 // }}} 292 // {{{ alterTable() 293 294 /** 295 * alter an existing table 296 * 297 * @param object $dbs database object that is extended by this class 298 * @param string $name name of the table that is intended to be changed. 299 * @param array $changes associative array that contains the details of each type 300 * of change that is intended to be performed. The types of 301 * changes that are currently supported are defined as follows: 302 * 303 * name 304 * 305 * New name for the table. 306 * 307 * AddedFields 308 * 309 * Associative array with the names of fields to be added as 310 * indexes of the array. The value of each entry of the array 311 * should be set to another associative array with the properties 312 * of the fields to be added. The properties of the fields should 313 * be the same as defined by the Metabase parser. 314 * 315 * Additionally, there should be an entry named Declaration that 316 * is expected to contain the portion of the field declaration already 317 * in DBMS specific SQL code as it is used in the CREATE TABLE statement. 318 * 319 * RemovedFields 320 * 321 * Associative array with the names of fields to be removed as indexes 322 * of the array. Currently the values assigned to each entry are ignored. 323 * An empty array should be used for future compatibility. 324 * 325 * RenamedFields 326 * 327 * Associative array with the names of fields to be renamed as indexes 328 * of the array. The value of each entry of the array should be set to 329 * another associative array with the entry named name with the new 330 * field name and the entry named Declaration that is expected to contain 331 * the portion of the field declaration already in DBMS specific SQL code 332 * as it is used in the CREATE TABLE statement. 333 * 334 * ChangedFields 335 * 336 * Associative array with the names of the fields to be changed as indexes 337 * of the array. Keep in mind that if it is intended to change either the 338 * name of a field and any other properties, the ChangedFields array entries 339 * should have the new names of the fields as array indexes. 340 * 341 * The value of each entry of the array should be set to another associative 342 * array with the properties of the fields to that are meant to be changed as 343 * array entries. These entries should be assigned to the new values of the 344 * respective properties. The properties of the fields should be the same 345 * as defined by the Metabase parser. 346 * 347 * If the default property is meant to be added, removed or changed, there 348 * should also be an entry with index ChangedDefault assigned to 1. Similarly, 349 * if the notnull constraint is to be added or removed, there should also be 350 * an entry with index ChangedNotNull assigned to 1. 351 * 352 * Additionally, there should be an entry named Declaration that is expected 353 * to contain the portion of the field changed declaration already in DBMS 354 * specific SQL code as it is used in the CREATE TABLE statement. 355 * Example 356 * array( 357 * 'name' => 'userlist', 358 * 'AddedFields' => array( 359 * 'quota' => array( 360 * 'type' => 'integer', 361 * 'unsigned' => 1 362 * 'Declaration' => 'quota INT' 363 * ) 364 * ), 365 * 'RemovedFields' => array( 366 * 'file_limit' => array(), 367 * 'time_limit' => array() 368 * ), 369 * 'ChangedFields' => array( 370 * 'gender' => array( 371 * 'default' => 'M', 372 * 'ChangeDefault' => 1, 373 * 'Declaration' => "gender CHAR(1) DEFAULT 'M'" 374 * ) 375 * ), 376 * 'RenamedFields' => array( 377 * 'sex' => array( 378 * 'name' => 'gender', 379 * 'Declaration' => "gender CHAR(1) DEFAULT 'M'" 380 * ) 381 * ) 382 * ) 383 * @param boolean $check indicates whether the function should just check if the DBMS driver 384 * can perform the requested table alterations if the value is true or 385 * actually perform them otherwise. 386 * @return mixed MDB_OK on success, a MDB error on failure 387 * @access public 388 */ 389 function alterTable(&$db, $name, $changes, $check) 390 { 391 return($db->raiseError(MDB_ERROR_UNSUPPORTED, NULL, NULL, 392 'Alter table: database table alterations are not supported')); 393 } 394 395 // }}} 396 // {{{ listDatabases() 397 398 /** 399 * list all databases 400 * 401 * @param object $dbs database object that is extended by this class 402 * @return mixed data array on success, a MDB error on failure 403 * @access public 404 */ 405 function listDatabases(&$db) 406 { 407 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 408 'List Databases: list databases is not supported')); 409 } 410 411 // }}} 412 // {{{ listUsers() 413 414 /** 415 * list all users 416 * 417 * @param object $dbs database object that is extended by this class 418 * @return mixed data array on success, a MDB error on failure 419 * @access public 420 */ 421 function listUsers(&$db) 422 { 423 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 424 'List User: list user is not supported')); 425 } 426 427 // }}} 428 // {{{ listViews() 429 430 /** 431 * list all views in the current database 432 * 433 * @param object $dbs database object that is extended by this class 434 * @return mixed data array on success, a MDB error on failure 435 * @access public 436 */ 437 function listViews(&$db) 438 { 439 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 440 'List View: list view is not supported')); 441 } 442 443 // }}} 444 // {{{ listFunctions() 445 446 /** 447 * list all functions in the current database 448 * 449 * @param object $dbs database object that is extended by this class 450 * @return mixed data array on success, a MDB error on failure 451 * @access public 452 */ 453 function listFunctions(&$db) 454 { 455 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 456 'List Function: list function is not supported')); 457 } 458 459 // }}} 460 // {{{ listTables() 461 462 /** 463 * list all tables in the current database 464 * 465 * @param object $dbs database object that is extended by this class 466 * @return mixed data array on success, a MDB error on failure 467 * @access public 468 */ 469 function listTables(&$db) 470 { 471 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 472 'List tables: list tables is not supported')); 473 } 474 475 // }}} 476 // {{{ listTableFields() 477 478 /** 479 * list all fields in a tables in the current database 480 * 481 * @param object $dbs database object that is extended by this class 482 * @param string $table name of table that should be used in method 483 * @return mixed data array on success, a MDB error on failure 484 * @access public 485 */ 486 function listTableFields(&$db, $table) 487 { 488 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 489 'List table fields: list table fields is not supported')); 490 } 491 492 // }}} 493 // {{{ getTableFieldDefinition() 494 495 /** 496 * get the stucture of a field into an array 497 * 498 * @param object $dbs database object that is extended by this class 499 * @param string $table name of table that should be used in method 500 * @param string $fields name of field that should be used in method 501 * @return mixed data array on success, a MDB error on failure 502 * @access public 503 */ 504 function getTableFieldDefinition(&$db, $table, $field) 505 { 506 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 507 'Get table field definition: table field definition is not supported')); 508 } 509 510 // }}} 511 // {{{ createIndex() 512 513 /** 514 * get the stucture of a field into an array 515 * 516 * @param object $dbs database object that is extended by this class 517 * @param string $table name of the table on which the index is to be created 518 * @param string $name name of the index to be created 519 * @param array $definition associative array that defines properties of the index to be created. 520 * Currently, only one property named FIELDS is supported. This property 521 * is also an associative with the names of the index fields as array 522 * indexes. Each entry of this array is set to another type of associative 523 * array that specifies properties of the index that are specific to 524 * each field. 525 * 526 * Currently, only the sorting property is supported. It should be used 527 * to define the sorting direction of the index. It may be set to either 528 * ascending or descending. 529 * 530 * Not all DBMS support index sorting direction configuration. The DBMS 531 * drivers of those that do not support it ignore this property. Use the 532 * function support() to determine whether the DBMS driver can manage indexes. 533 534 * Example 535 * array( 536 * 'FIELDS' => array( 537 * 'user_name' => array( 538 * 'sorting' => 'ascending' 539 * ), 540 * 'last_login' => array() 541 * ) 542 * ) 543 * @return mixed MDB_OK on success, a MDB error on failure 544 * @access public 545 */ 546 function createIndex(&$db, $table, $name, $definition) 547 { 548 $query = 'CREATE'; 549 if (isset($definition['unique'])) { 550 $query .= ' UNIQUE'; 551 } 552 $query .= " INDEX $name ON $table ("; 553 for($field = 0,reset($definition['FIELDS']); 554 $field<count($definition['FIELDS']); $field++,next($definition['FIELDS'])) 555 { 556 if ($field>0) { 557 $query.= ', '; 558 } 559 $field_name = Key($definition['FIELDS']); 560 $query.= $field_name; 561 if ($db->support('IndexSorting') && isset($definition['FIELDS'][$field_name]['sorting'])) { 562 switch($definition['FIELDS'][$field_name]['sorting']) { 563 case 'ascending': 564 $query.= ' ASC'; 565 break; 566 case 'descending': 567 $query.= ' DESC'; 568 break; 569 } 570 } 571 } 572 $query.= ')'; 573 return($db->query($query)); 574 } 575 576 // }}} 577 // {{{ dropIndex() 578 579 /** 580 * drop existing index 581 * 582 * @param object $dbs database object that is extended by this class 583 * @param string $table name of table that should be used in method 584 * @param string $name name of the index to be dropped 585 * @return mixed MDB_OK on success, a MDB error on failure 586 * @access public 587 */ 588 function dropIndex(&$db, $table, $name) 589 { 590 return($db->query("DROP INDEX $name")); 591 } 592 593 // }}} 594 // {{{ listTableIndexes() 595 596 /** 597 * list all indexes in a table 598 * 599 * @param object $dbs database object that is extended by this class 600 * @param string $table name of table that should be used in method 601 * @return mixed data array on success, a MDB error on failure 602 * @access public 603 */ 604 function listTableIndexes(&$db, $table) 605 { 606 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 607 'List table indexes: List Indexes is not supported')); 608 } 609 610 // }}} 611 // {{{ getTableIndexDefinition() 612 613 /** 614 * get the stucture of an index into an array 615 * 616 * @param object $dbs database object that is extended by this class 617 * @param string $table name of table that should be used in method 618 * @param string $index name of index that should be used in method 619 * @return mixed data array on success, a MDB error on failure 620 * @access public 621 */ 622 function getTableIndexDefinition(&$db, $table, $index) 623 { 624 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 625 'Get table index definition: getting index definition is not supported')); 626 } 627 628 // }}} 629 // {{{ createSequence() 630 631 /** 632 * create sequence 633 * 634 * @param object $dbs database object that is extended by this class 635 * @param string $seq_name name of the sequence to be created 636 * @param string $start start value of the sequence; default is 1 637 * @return mixed MDB_OK on success, a MDB error on failure 638 * @access public 639 */ 640 function createSequence(&$db, $name, $start) 641 { 642 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 643 'Create Sequence: sequence creation not supported')); 644 } 645 646 // }}} 647 // {{{ dropSequence() 648 649 /** 650 * drop existing sequence 651 * 652 * @param object $dbs database object that is extended by this class 653 * @param string $seq_name name of the sequence to be dropped 654 * @return mixed MDB_OK on success, a MDB error on failure 655 * @access public 656 */ 657 function dropSequence(&$db, $name) 658 { 659 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 660 'Drop Sequence: sequence dropping not supported')); 661 } 662 663 // }}} 664 // {{{ listSequences() 665 666 /** 667 * list all sequences in the current database 668 * 669 * @param object $dbs database object that is extended by this class 670 * @return mixed data array on success, a MDB error on failure 671 * @access public 672 */ 673 function listSequences(&$db) 674 { 675 return($db->raiseError(MDB_ERROR_NOT_CAPABLE, NULL, NULL, 676 'List sequences: List sequences is not supported')); 677 } 678 679 // }}} 680 // {{{ getSequenceDefinition() 681 682 /** 683 * get the stucture of a sequence into an array 684 * 685 * @param object $dbs database object that is extended by this class 686 * @param string $sequence name of sequence that should be used in method 687 * @return mixed data array on success, a MDB error on failure 688 * @access public 689 */ 690 691 // }}} 692 // {{{ getSequenceDefinition() 693 694 /** 695 * get the stucture of a sequence into an array 696 * 697 * @param object $dbs database object that is extended by this class 698 * @param string $sequence name of sequence that should be used in method 699 * @return mixed data array on success, a MDB error on failure 700 * @access public 701 */ 702 function getSequenceDefinition(&$db, $sequence) 703 { 704 $start = $db->currId($sequence); 705 if (MDB::isError($start)) { 706 return($start); 707 } 708 if ($db->support('CurrId')) { 709 $start++; 710 } else { 711 $db->warnings[] = 'database does not support getting current 712 sequence value,the sequence value was incremented'; 713 } 714 $definition = array(); 715 if($start != 1) { 716 $definition = array('start' => $start); 717 } 718 return($definition); 719 } 720} 721 722}; 723?>