| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php // $Id: XMLDBGenerator.class.php,v 1.66 2007/10/10 05:25:25 nicolasconnault Exp $ 2 3 /////////////////////////////////////////////////////////////////////////// 4 // // 5 // NOTICE OF COPYRIGHT // 6 // // 7 // Moodle - Modular Object-Oriented Dynamic Learning Environment // 8 // http://moodle.com // 9 // // 10 // Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com // 11 // (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com // 12 // // 13 // This program is free software; you can redistribute it and/or modify // 14 // it under the terms of the GNU General Public License as published by // 15 // the Free Software Foundation; either version 2 of the License, or // 16 // (at your option) any later version. // 17 // // 18 // This program is distributed in the hope that it will be useful, // 19 // but WITHOUT ANY WARRANTY; without even the implied warranty of // 20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 21 // GNU General Public License for more details: // 22 // // 23 // http://www.gnu.org/copyleft/gpl.html // 24 // // 25 /////////////////////////////////////////////////////////////////////////// 26 27 /// This class represent the base generator class where all the 28 /// needed functions to generate proper SQL are defined. 29 30 /// The rest of classes will inherit, by default, the same logic. 31 /// Functions will be overriden as needed to generate correct SQL. 32 33 class XMLDBgenerator { 34 35 /// Please, avoid editing this defaults in this base class! 36 /// It could change the behaviour of the rest of generators 37 /// that, by default, inherit this configuration. 38 /// To change any of them, do it in extended classes instead. 39 40 var $quote_string = '"'; // String used to quote names 41 42 var $quote_all = false; // To decide if we want to quote all the names or only the reserved ones 43 44 var $statement_end = ';'; // String to be automatically added at the end of each statement 45 46 var $integer_to_number = false; // To create all the integers as NUMBER(x) (also called DECIMAL, NUMERIC...) 47 var $float_to_number = false; // To create all the floats as NUMBER(x) (also called DECIMAL, NUMERIC...) 48 49 var $number_type = 'NUMERIC'; // Proper type for NUMBER(x) in this DB 50 51 var $unsigned_allowed = true; // To define in the generator must handle unsigned information 52 var $default_for_char = null; // To define the default to set for NOT NULLs CHARs without default (null=do nothing) 53 54 var $drop_default_clause_required = false; //To specify if the generator must use some DEFAULT clause to drop defaults 55 var $drop_default_clause = ''; //The DEFAULT clause required to drop defaults 56 57 var $default_after_null = true; //To decide if the default clause of each field must go after the null clause 58 59 var $specify_nulls = false; //To force the generator if NULL clauses must be specified. It shouldn't be necessary 60 //but some mssql drivers require them or everything is created as NOT NULL :-( 61 62 var $primary_key_name = null; //To force primary key names to one string (null=no force) 63 64 var $primary_keys = true; // Does the generator build primary keys 65 var $unique_keys = false; // Does the generator build unique keys 66 var $foreign_keys = false; // Does the generator build foreign keys 67 68 var $drop_primary_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop PKs 69 // with automatic replace for TABLENAME and KEYNAME 70 71 var $drop_unique_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop UKs 72 // with automatic replace for TABLENAME and KEYNAME 73 74 var $drop_foreign_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop FKs 75 // with automatic replace for TABLENAME and KEYNAME 76 77 var $sequence_extra_code = true; //Does the generator need to add extra code to generate the sequence fields 78 var $sequence_name = 'auto_increment'; //Particular name for inline sequences in this generator 79 var $sequence_name_small = false; //Different name for small (4byte) sequences or false if same 80 var $sequence_only = false; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name variable 81 82 var $enum_inline_code = true; //Does the generator need to add inline code in the column definition 83 var $enum_extra_code = true; //Does the generator need to add extra code to generate code for the enums in the table 84 85 var $add_table_comments = true; // Does the generator need to add code for table comments 86 87 var $add_after_clause = false; // Does the generator need to add the after clause for fields 88 89 var $prefix_on_names = true; //Does the generator need to prepend the prefix to all the key/index/sequence/trigger/check names 90 91 var $names_max_length = 30; //Max length for key/index/sequence/trigger/check names (keep 30 for all!) 92 93 var $concat_character = '||'; //Characters to be used as concatenation operator. If not defined 94 //MySQL CONCAT function will be used 95 96 var $rename_table_sql = 'ALTER TABLE OLDNAME RENAME TO NEWNAME'; //SQL sentence to rename one table, both 97 //OLDNAME and NEWNAME are dinamically replaced 98 99 var $rename_table_extra_code = false; //Does the generator need to add code after table rename 100 101 var $drop_table_sql = 'DROP TABLE TABLENAME'; //SQL sentence to drop one table 102 //TABLENAME is dinamically replaced 103 104 var $drop_table_extra_code = false; //Does the generator need to add code after table drop 105 106 var $alter_column_sql = 'ALTER TABLE TABLENAME ALTER COLUMN COLUMNSPECS'; //The SQL template to alter columns 107 108 var $alter_column_skip_default = false; //The generator will skip the default clause on alter columns 109 110 var $alter_column_skip_type = false; //The generator will skip the type clause on alter columns 111 112 var $alter_column_skip_notnull = false; //The generator will skip the null/notnull clause on alter columns 113 114 var $rename_column_sql = 'ALTER TABLE TABLENAME RENAME COLUMN OLDFIELDNAME TO NEWFIELDNAME'; 115 ///TABLENAME, OLDFIELDNAME and NEWFIELDNAME are dianmically replaced 116 117 var $rename_column_extra_code = false; //Does the generator need to add code after column rename 118 119 var $drop_index_sql = 'DROP INDEX INDEXNAME'; //SQL sentence to drop one index 120 //TABLENAME, INDEXNAME are dinamically replaced 121 122 var $rename_index_sql = 'ALTER INDEX OLDINDEXNAME RENAME TO NEWINDEXNAME'; //SQL sentence to rename one index 123 //TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dinamically replaced 124 125 var $rename_key_sql = 'ALTER TABLE TABLENAME CONSTRAINT OLDKEYNAME RENAME TO NEWKEYNAME'; //SQL sentence to rename one key 126 //TABLENAME, OLDKEYNAME, NEWKEYNAME are dinamically replaced 127 128 var $prefix; // Prefix to be used for all the DB objects 129 130 var $reserved_words; // List of reserved words (in order to quote them properly) 131 132 /** 133 * Creates one new XMLDBGenerator 134 */ 135 function XMLDBgenerator() { 136 global $CFG; 137 $this->prefix = ''; 138 $this->reserved_words = $this->getReservedWords(); 139 } 140 141 /// ALL THESE FUNCTION ARE SHARED BY ALL THE XMLDGenerator classes 142 143 /** 144 * Set the prefix 145 */ 146 function setPrefix($prefix) { 147 if ($this->prefix_on_names) { // Only if we want prefix on names 148 $this->prefix = $prefix; 149 } 150 } 151 152 /** 153 * Given one XMLDBTable, returns it's correct name, depending of all the parametrization 154 * 155 * @param XMLDBTable table whose name we want 156 * @param boolean to specify if the name must be quoted (if reserved word, only!) 157 * @return string the correct name of the table 158 */ 159 function getTableName($xmldb_table, $quoted = true) { 160 161 $prefixtouse = $this->prefix; 162 /// Determinate if this table must have prefix or no 163 if (in_array($xmldb_table->getName(), $this->getTablesWithoutPrefix())) { 164 $prefixtouse = ''; 165 } 166 /// Get the name 167 $tablename = $prefixtouse . $xmldb_table->getName(); 168 /// Apply quotes conditionally 169 if ($quoted) { 170 $tablename = $this->getEncQuoted($tablename); 171 } 172 173 return $tablename; 174 } 175 176 /** 177 * Given one correct XMLDBTable, returns the SQL statements 178 * to create it (inside one array) 179 */ 180 function getCreateTableSQL($xmldb_table) { 181 182 $results = array(); //Array where all the sentences will be stored 183 184 /// Table header 185 $table = 'CREATE TABLE ' . $this->getTableName($xmldb_table) . ' ('; 186 187 if (!$xmldb_fields = $xmldb_table->getFields()) { 188 return $results; 189 } 190 191 /// Prevent tables without prefix to be duplicated (part of MDL-6614) 192 if (in_array($xmldb_table->getName(), $this->getTablesWithoutPrefix()) && 193 table_exists($xmldb_table)) { 194 return $results; // false here would break the install, empty array is better ;-) 195 } 196 197 /// Add the fields, separated by commas 198 foreach ($xmldb_fields as $xmldb_field) { 199 $table .= "\n " . $this->getFieldSQL($xmldb_field); 200 $table .= ','; 201 } 202 /// Add the keys, separated by commas 203 if ($xmldb_keys = $xmldb_table->getKeys()) { 204 foreach ($xmldb_keys as $xmldb_key) { 205 if ($keytext = $this->getKeySQL($xmldb_table, $xmldb_key)) { 206 $table .= "\nCONSTRAINT " . $keytext . ','; 207 } 208 /// If the key is XMLDB_KEY_FOREIGN_UNIQUE, create it as UNIQUE too 209 if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE) { 210 ///Duplicate the key 211 $xmldb_key->setType(XMLDB_KEY_UNIQUE); 212 if ($keytext = $this->getKeySQL($xmldb_table, $xmldb_key)) { 213 $table .= "\nCONSTRAINT " . $keytext . ','; 214 } 215 } 216 } 217 } 218 /// Add enum extra code if needed 219 if ($this->enum_extra_code) { 220 /// Iterate over fields looking for enums 221 foreach ($xmldb_fields as $xmldb_field) { 222 if ($xmldb_field->getEnum()) { 223 $table .= "\n" . $this->getEnumExtraSQL($xmldb_table, $xmldb_field) . ','; 224 } 225 } 226 } 227 /// Table footer, trim the latest comma 228 $table = trim($table,','); 229 $table .= "\n)"; 230 231 /// Add the CREATE TABLE to results 232 $results[] = $table; 233 234 /// Add comments if specified and it exists 235 if ($this->add_table_comments && $xmldb_table->getComment()) { 236 $comment = $this->getCommentSQL ($xmldb_table); 237 /// Add the COMMENT to results 238 $results = array_merge($results, $comment); 239 } 240 241 /// Add the indexes (each one, one statement) 242 if ($xmldb_indexes = $xmldb_table->getIndexes()) { 243 foreach ($xmldb_indexes as $xmldb_index) { 244 ///Only process all this if the index doesn't exist in DB 245 if (!index_exists($xmldb_table, $xmldb_index)) { 246 if ($indextext = $this->getCreateIndexSQL($xmldb_table, $xmldb_index)) { 247 $results = array_merge($results, $indextext); 248 } 249 } 250 } 251 } 252 253 /// Also, add the indexes needed from keys, based on configuration (each one, one statement) 254 if ($xmldb_keys = $xmldb_table->getKeys()) { 255 foreach ($xmldb_keys as $xmldb_key) { 256 /// If we aren't creating the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated 257 /// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists) 258 if (!$this->getKeySQL($xmldb_table, $xmldb_key) || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) { 259 /// Create the interim index 260 $index = new XMLDBIndex('anyname'); 261 $index->setFields($xmldb_key->getFields()); 262 ///Only process all this if the index doesn't exist in DB 263 if (!index_exists($xmldb_table, $index)) { 264 $createindex = false; //By default 265 switch ($xmldb_key->getType()) { 266 case XMLDB_KEY_UNIQUE: 267 case XMLDB_KEY_FOREIGN_UNIQUE: 268 $index->setUnique(true); 269 $createindex = true; 270 break; 271 case XMLDB_KEY_FOREIGN: 272 $index->setUnique(false); 273 $createindex = true; 274 break; 275 } 276 if ($createindex) { 277 if ($indextext = $this->getCreateIndexSQL($xmldb_table, $index)) { 278 /// Add the INDEX to the array 279 $results = array_merge($results, $indextext); 280 } 281 } 282 } 283 } 284 } 285 } 286 287 /// Add sequence extra code if needed 288 if ($this->sequence_extra_code) { 289 /// Iterate over fields looking for sequences 290 foreach ($xmldb_fields as $xmldb_field) { 291 if ($xmldb_field->getSequence()) { 292 /// returns an array of statements needed to create one sequence 293 $sequence_sentences = $this->getCreateSequenceSQL($xmldb_table, $xmldb_field); 294 /// Add the SEQUENCE to the array 295 $results = array_merge($results, $sequence_sentences); 296 } 297 } 298 } 299 300 return $results; 301 } 302 303 /** 304 * Given one correct XMLDBIndex, returns the SQL statements 305 * needed to create it (in array) 306 */ 307 function getCreateIndexSQL ($xmldb_table, $xmldb_index) { 308 309 $unique = ''; 310 $suffix = 'ix'; 311 if ($xmldb_index->getUnique()) { 312 $unique = ' UNIQUE'; 313 $suffix = 'uix'; 314 } 315 316 $index = 'CREATE' . $unique . ' INDEX '; 317 $index .= $this->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_index->getFields()), $suffix); 318 $index .= ' ON ' . $this->getTableName($xmldb_table); 319 $index .= ' (' . implode(', ', $this->getEncQuoted($xmldb_index->getFields())) . ')'; 320 321 return array($index); 322 } 323 324 /** 325 * Given one correct XMLDBField, returns the complete SQL line to create it 326 */ 327 function getFieldSQL($xmldb_field, $skip_type_clause = false, $skip_default_clause = false, $skip_notnull_clause = false) { 328 329 /// First of all, convert integers to numbers if defined 330 if ($this->integer_to_number) { 331 if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER) { 332 $xmldb_field->setType(XMLDB_TYPE_NUMBER); 333 } 334 } 335 /// Same for floats 336 if ($this->float_to_number) { 337 if ($xmldb_field->getType() == XMLDB_TYPE_FLOAT) { 338 $xmldb_field->setType(XMLDB_TYPE_NUMBER); 339 } 340 } 341 342 /// The name 343 $field = $this->getEncQuoted($xmldb_field->getName()); 344 /// The type and length only if we don't want to skip it 345 if (!$skip_type_clause) { 346 /// The type and length (if the field isn't enum) 347 if (!$xmldb_field->getEnum() || $this->enum_inline_code == false) { 348 $field .= ' ' . $this->getTypeSQL($xmldb_field->getType(), $xmldb_field->getLength(), $xmldb_field->getDecimals()); 349 } else { 350 /// call to custom function 351 $field .= ' ' . $this->getEnumSQL($xmldb_field); 352 } 353 } 354 /// The unsigned if supported 355 if ($this->unsigned_allowed && ($xmldb_field->getType() == XMLDB_TYPE_INTEGER || 356 $xmldb_field->getType() == XMLDB_TYPE_NUMBER || 357 $xmldb_field->getType() == XMLDB_TYPE_FLOAT)) { 358 if ($xmldb_field->getUnsigned()) { 359 $field .= ' unsigned'; 360 } 361 } 362 /// Calculate the not null clause 363 $notnull = ''; 364 /// Only if we don't want to skip it 365 if (!$skip_notnull_clause) { 366 if ($xmldb_field->getNotNull()) { 367 $notnull = ' NOT NULL'; 368 } else { 369 if ($this->specify_nulls) { 370 $notnull = ' NULL'; 371 } 372 } 373 } 374 /// Calculate the default clause 375 if (!$skip_default_clause) { //Only if we don't want to skip it 376 $default = $this->getDefaultClause($xmldb_field); 377 } else { 378 $default = ''; 379 } 380 /// Based on default_after_null, set both clauses properly 381 if ($this->default_after_null) { 382 $field .= $notnull . $default; 383 } else { 384 $field .= $default . $notnull; 385 } 386 /// The sequence 387 if ($xmldb_field->getSequence()) { 388 if($xmldb_field->getLength()<=9 && $this->sequence_name_small) { 389 $sequencename=$this->sequence_name_small; 390 } else { 391 $sequencename=$this->sequence_name; 392 } 393 $field .= ' ' . $sequencename; 394 if ($this->sequence_only) { 395 /// We only want the field name and sequence name to be printed 396 /// so, calculate it and return 397 return $this->getEncQuoted($xmldb_field->getName()) . ' ' . $sequencename; 398 } 399 } 400 return $field; 401 } 402 403 /** 404 * Given one correct XMLDBKey, returns its specs 405 */ 406 function getKeySQL ($xmldb_table, $xmldb_key) { 407 408 $key = ''; 409 410 switch ($xmldb_key->getType()) { 411 case XMLDB_KEY_PRIMARY: 412 if ($this->primary_keys) { 413 if ($this->primary_key_name !== null) { 414 $key = $this->getEncQuoted($this->primary_key_name); 415 } else { 416 $key = $this->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), 'pk'); 417 } 418 $key .= ' PRIMARY KEY (' . implode(', ', $this->getEncQuoted($xmldb_key->getFields())) . ')'; 419 } 420 break; 421 case XMLDB_KEY_UNIQUE: 422 if ($this->unique_keys) { 423 $key = $this->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), 'uk'); 424 $key .= ' UNIQUE (' . implode(', ', $this->getEncQuoted($xmldb_key->getFields())) . ')'; 425 } 426 break; 427 case XMLDB_KEY_FOREIGN: 428 case XMLDB_KEY_FOREIGN_UNIQUE: 429 if ($this->foreign_keys) { 430 $key = $this->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), 'fk'); 431 $key .= ' FOREIGN KEY (' . implode(', ', $this->getEncQuoted($xmldb_key->getFields())) . ')'; 432 $key .= ' REFERENCES ' . $this->getEncQuoted($this->prefix . $xmldb_key->getRefTable()); 433 $key .= ' (' . implode(', ', $this->getEncQuoted($xmldb_key->getRefFields())) . ')'; 434 } 435 break; 436 } 437 438 return $key; 439 } 440 441 /** 442 * Give one XMLDBField, returns the correct "default value" for the current configuration 443 */ 444 function getDefaultValue ($xmldb_field) { 445 446 $default = null; 447 448 if ($xmldb_field->getDefault() !== NULL) { 449 if ($xmldb_field->getType() == XMLDB_TYPE_CHAR || 450 $xmldb_field->getType() == XMLDB_TYPE_TEXT) { 451 $default = "'" . addslashes($xmldb_field->getDefault()) . "'"; 452 } else { 453 $default = $xmldb_field->getDefault(); 454 } 455 } else { 456 /// We force default '' for not null char columns without proper default 457 /// some day this should be out! 458 if ($this->default_for_char !== NULL && 459 $xmldb_field->getType() == XMLDB_TYPE_CHAR && 460 $xmldb_field->getNotNull()) { 461 $default = "'" . $this->default_for_char . "'"; 462 } else { 463 /// If the DB requires to explicity define some clause to drop one default, do it here 464 /// never applying defaults to TEXT and BINARY fields 465 if ($this->drop_default_clause_required && 466 $xmldb_field->getType() != XMLDB_TYPE_TEXT && 467 $xmldb_field->getType() != XMLDB_TYPE_BINARY && !$xmldb_field->getNotNull()) { 468 $default = $this->drop_default_clause; 469 } 470 } 471 } 472 return $default; 473 } 474 475 /** 476 * Given one XMLDBField, returns the correct "default clause" for the current configuration 477 */ 478 function getDefaultClause ($xmldb_field) { 479 480 $defaultvalue = $this->getDefaultValue ($xmldb_field); 481 482 if ($defaultvalue !== null) { 483 return ' DEFAULT ' . $defaultvalue; 484 } else { 485 return null; 486 } 487 } 488 489 /** 490 * Given one correct XMLDBTable and the new name, returns the SQL statements 491 * to rename it (inside one array) 492 */ 493 function getRenameTableSQL($xmldb_table, $newname) { 494 495 $results = array(); //Array where all the sentences will be stored 496 497 $newt = new XMLDBTable($newname); //Temporal table for name calculations 498 499 $rename = str_replace('OLDNAME', $this->getTableName($xmldb_table), $this->rename_table_sql); 500 $rename = str_replace('NEWNAME', $this->getTableName($newt), $rename); 501 502 $results[] = $rename; 503 504 /// Call to getRenameTableExtraSQL() if $rename_table_extra_code is enabled. It will add sequence regeneration code. 505 if ($this->rename_table_extra_code) { 506 $extra_sentences = $this->getRenameTableExtraSQL($xmldb_table, $newname); 507 $results = array_merge($results, $extra_sentences); 508 } 509 510 return $results; 511 } 512 513 /** 514 * Given one correct XMLDBTable and the new name, returns the SQL statements 515 * to drop it (inside one array) 516 */ 517 function getDropTableSQL($xmldb_table) { 518 519 $results = array(); //Array where all the sentences will be stored 520 521 $drop = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->drop_table_sql); 522 523 $results[] = $drop; 524 525 /// call to getDropTableExtraSQL() if $drop_table_extra_code is enabled. It will add sequence/trigger drop code. 526 if ($this->drop_table_extra_code) { 527 $extra_sentences = $this->getDropTableExtraSQL($xmldb_table); 528 $results = array_merge($results, $extra_sentences); 529 } 530 531 return $results; 532 } 533 534 /** 535 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add the field to the table 536 */ 537 function getAddFieldSQL($xmldb_table, $xmldb_field) { 538 539 $results = array(); 540 541 /// Get the quoted name of the table and field 542 $tablename = $this->getTableName($xmldb_table); 543 544 /// Build the standard alter table add 545 $altertable = 'ALTER TABLE ' . $tablename . ' ADD ' . 546 $this->getFieldSQL($xmldb_field, $this->alter_column_skip_type, 547 $this->alter_column_skip_default, 548 $this->alter_column_skip_notnull); 549 /// Add the after clause if necesary 550 if ($this->add_after_clause && $xmldb_field->getPrevious()) { 551 $altertable .= ' after ' . $this->getEncQuoted($xmldb_field->getPrevious()); 552 } 553 $results[] = $altertable; 554 555 /// If the DB has extra enum code 556 if ($this->enum_extra_code) { 557 /// If it's enum add the extra code 558 if ($xmldb_field->getEnum()) { 559 $results[] = 'ALTER TABLE ' . $tablename . ' ADD ' . $this->getEnumExtraSQL($xmldb_table, $xmldb_field); 560 } 561 } 562 563 return $results; 564 } 565 566 /** 567 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop the field from the table 568 */ 569 function getDropFieldSQL($xmldb_table, $xmldb_field) { 570 571 $results = array(); 572 573 /// Get the quoted name of the table and field 574 $tablename = $this->getTableName($xmldb_table); 575 $fieldname = $this->getEncQuoted($xmldb_field->getName()); 576 577 /// Build the standard alter table drop 578 $results[] = 'ALTER TABLE ' . $tablename . ' DROP COLUMN ' . $fieldname; 579 580 return $results; 581 } 582 583 /** 584 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to alter the field in the table 585 */ 586 function getAlterFieldSQL($xmldb_table, $xmldb_field) { 587 588 $results = array(); 589 590 /// Always specify NULLs in alter fields because we can change not nulls to nulls 591 $this->specify_nulls = true; 592 593 /// Get the quoted name of the table and field 594 $tablename = $this->getTableName($xmldb_table); 595 $fieldname = $this->getEncQuoted($xmldb_field->getName()); 596 597 /// Build de alter sentence using the alter_column_sql template 598 $alter = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->alter_column_sql); 599 $alter = str_replace('COLUMNSPECS', $this->getFieldSQL($xmldb_field, $this->alter_column_skip_type, 600 $this->alter_column_skip_default, 601 $this->alter_column_skip_notnull), $alter); 602 603 /// Add the after clause if necesary 604 if ($this->add_after_clause && $xmldb_field->getPrevious()) { 605 $alter .= ' after ' . $this->getEncQuoted($xmldb_field->getPrevious()); 606 } 607 608 /// Build the standard alter table modify 609 $results[] = $alter; 610 611 return $results; 612 } 613 614 /** 615 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to modify the enum of the field in the table 616 */ 617 function getModifyEnumSQL($xmldb_table, $xmldb_field) { 618 619 $results = array(); 620 621 /// Get the quoted name of the table and field 622 $tablename = $this->getTableName($xmldb_table); 623 $fieldname = $this->getEncQuoted($xmldb_field->getName()); 624 625 /// Decide if we are going to create or to drop the enum (based exclusively in the values passed!) 626 if (!$xmldb_field->getEnum()) { 627 $results = $this->getDropEnumSQL($xmldb_table, $xmldb_field); //Drop 628 } else { 629 $results = $this->getCreateEnumSQL($xmldb_table, $xmldb_field); //Create/modify 630 } 631 632 return $results; 633 } 634 635 /** 636 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to modify the default of the field in the table 637 */ 638 function getModifyDefaultSQL($xmldb_table, $xmldb_field) { 639 640 $results = array(); 641 642 /// Get the quoted name of the table and field 643 $tablename = $this->getTableName($xmldb_table); 644 $fieldname = $this->getEncQuoted($xmldb_field->getName()); 645 646 /// Decide if we are going to create/modify or to drop the default 647 if ($xmldb_field->getDefault() === null) { 648 $results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field); //Drop 649 } else { 650 $results = $this->getCreateDefaultSQL($xmldb_table, $xmldb_field); //Create/modify 651 } 652 653 return $results; 654 } 655 656 /** 657 * Given one correct XMLDBField and the new name, returns the SQL statements 658 * to rename it (inside one array) 659 */ 660 function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) { 661 662 $results = array(); //Array where all the sentences will be stored 663 664 /// Although this is checked in ddllib - rename_field() - double check 665 /// that we aren't trying to rename one "id" field. Although it could be 666 /// implemented (if adding the necessary code to rename sequences, defaults, 667 /// triggers... and so on under each getRenameFieldExtraSQL() function, it's 668 /// better to forbide it, mainly because this field is the default PK and 669 /// in the future, a lot of FKs can be pointing here. So, this field, more 670 /// or less, must be considered inmutable! 671 if ($xmldb_field->getName() == 'id') { 672 return array(); 673 } 674 675 $rename = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->rename_column_sql); 676 $rename = str_replace('OLDFIELDNAME', $this->getEncQuoted($xmldb_field->getName()), $rename); 677 $rename = str_replace('NEWFIELDNAME', $this->getEncQuoted($newname), $rename); 678 679 $results[] = $rename; 680 681 /// Call to getRenameFieldExtraSQL() if $rename_column_extra_code is enabled (will add some required sentences) 682 if ($this->rename_column_extra_code) { 683 $extra_sentences = $this->getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname); 684 $results = array_merge($results, $extra_sentences); 685 } 686 687 return $results; 688 } 689 690 /** 691 * Given one XMLDBTable and one XMLDBKey, return the SQL statements needded to add the key to the table 692 * note that undelying indexes will be added as parametrised by $xxxx_keys and $xxxx_index parameters 693 */ 694 function getAddKeySQL($xmldb_table, $xmldb_key) { 695 696 $results = array(); 697 698 /// Just use the CreateKeySQL function 699 if ($keyclause = $this->getKeySQL($xmldb_table, $xmldb_key)) { 700 $key = 'ALTER TABLE ' . $this->getTableName($xmldb_table) . 701 ' ADD CONSTRAINT ' . $keyclause; 702 $results[] = $key; 703 } 704 705 /// If we aren't creating the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated 706 /// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists) 707 if (!$keyclause || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) { 708 /// Only if they don't exist 709 if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN) { ///Calculate type of index based on type ok key 710 $indextype = XMLDB_INDEX_NOTUNIQUE; 711 } else { 712 $indextype = XMLDB_INDEX_UNIQUE; 713 } 714 $xmldb_index = new XMLDBIndex('anyname'); 715 $xmldb_index->setAttributes($indextype, $xmldb_key->getFields()); 716 if (!index_exists($xmldb_table, $xmldb_index)) { 717 $results = array_merge($results, $this->getAddIndexSQL($xmldb_table, $xmldb_index)); 718 } 719 } 720 721 /// If the key is XMLDB_KEY_FOREIGN_UNIQUE, create it as UNIQUE too 722 if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE && $this->unique_keys) { 723 ///Duplicate the key 724 $xmldb_key->setType(XMLDB_KEY_UNIQUE); 725 $results = array_merge($results, $this->getAddKeySQL($xmldb_table, $xmldb_key)); 726 } 727 728 /// Return results 729 return $results; 730 } 731 732 /** 733 * Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to drop the index from the table 734 */ 735 function getDropKeySQL($xmldb_table, $xmldb_key) { 736 737 $results = array(); 738 739 /// Get the key name (note that this doesn't introspect DB, so could cause some problems sometimes!) 740 /// TODO: We'll need to overwrite the whole getDropKeySQL() method inside each DB to do the proper queries 741 /// against the dictionary or require ADOdb to support it or change the find_key_name() method to 742 /// perform DB introspection directly. But, for now, as we aren't going to enable referential integrity 743 /// it won't be a problem at all 744 $dbkeyname = find_key_name($xmldb_table, $xmldb_key); 745 746 /// Only if such type of key generation is enabled 747 $dropkey = false; 748 switch ($xmldb_key->getType()) { 749 case XMLDB_KEY_PRIMARY: 750 if ($this->primary_keys) { 751 $template = $this->drop_primary_key; 752 $dropkey = true; 753 } 754 break; 755 case XMLDB_KEY_UNIQUE: 756 if ($this->unique_keys) { 757 $template = $this->drop_unique_key; 758 $dropkey = true; 759 } 760 break; 761 case XMLDB_KEY_FOREIGN_UNIQUE: 762 case XMLDB_KEY_FOREIGN: 763 if ($this->foreign_keys) { 764 $template = $this->drop_foreign_key; 765 $dropkey = true; 766 } 767 break; 768 } 769 /// If we have decided to drop the key, let's do it 770 if ($dropkey) { 771 /// Replace TABLENAME, CONSTRAINTTYPE and KEYNAME as needed 772 $dropsql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $template); 773 $dropsql = str_replace('KEYNAME', $dbkeyname, $dropsql); 774 775 $results[] = $dropsql; 776 } 777 778 /// If we aren't dropping the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated 779 /// automatically by the RDBMS) drop the underlying (created by us) index (if exists) 780 if (!$dropkey || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) { 781 /// Only if they exist 782 $xmldb_index = new XMLDBIndex('anyname'); 783 $xmldb_index->setAttributes(XMLDB_INDEX_UNIQUE, $xmldb_key->getFields()); 784 if (index_exists($xmldb_table, $xmldb_index)) { 785 $results = array_merge($results, $this->getDropIndexSQL($xmldb_table, $xmldb_index)); 786 } 787 } 788 789 /// If the key is XMLDB_KEY_FOREIGN_UNIQUE, drop the UNIQUE too 790 if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE && $this->unique_keys) { 791 ///Duplicate the key 792 $xmldb_key->setType(XMLDB_KEY_UNIQUE); 793 $results = array_merge($results, $this->getDropKeySQL($xmldb_table, $xmldb_key)); 794 } 795 796 /// Return results 797 return $results; 798 } 799 800 /** 801 * Given one XMLDBTable and one XMLDBKey, return the SQL statements needded to rename the key in the table 802 * Experimental! Shouldn't be used at all! 803 */ 804 805 function getRenameKeySQL($xmldb_table, $xmldb_key, $newname) { 806 807 $results = array(); 808 809 /// Get the real key name 810 $dbkeyname = find_key_name($xmldb_table, $xmldb_key); 811 812 /// Check we are really generating this type of keys 813 if (($xmldb_key->getType() == XMLDB_KEY_PRIMARY && !$this->primary_keys) || 814 ($xmldb_key->getType() == XMLDB_KEY_UNIQUE && !$this->unique_keys) || 815 ($xmldb_key->getType() == XMLDB_KEY_FOREIGN && !$this->foreign_keys) || 816 ($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE && !$this->unique_keys && !$this->foreign_keys)) { 817 /// We aren't generating this type of keys, delegate to child indexes 818 $xmldb_index = new XMLDBIndex($xmldb_key->getName()); 819 $xmldb_index->setFields($xmldb_key->getFields()); 820 return $this->getRenameIndexSQL($xmldb_table, $xmldb_index, $newname); 821 } 822 823 /// Arrived here so we are working with keys, lets rename them 824 /// Replace TABLENAME and KEYNAME as needed 825 $renamesql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->rename_key_sql); 826 $renamesql = str_replace('OLDKEYNAME', $dbkeyname, $renamesql); 827 $renamesql = str_replace('NEWKEYNAME', $newname, $renamesql); 828 829 /// Some DB doesn't support key renaming so this can be empty 830 if ($renamesql) { 831 $results[] = $renamesql; 832 } 833 834 return $results; 835 } 836 837 /** 838 * Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to add the index to the table 839 */ 840 function getAddIndexSQL($xmldb_table, $xmldb_index) { 841 842 /// Just use the CreateIndexSQL function 843 return $this->getCreateIndexSQL($xmldb_table, $xmldb_index); 844 } 845 846 /** 847 * Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to drop the index from the table 848 */ 849 function getDropIndexSQL($xmldb_table, $xmldb_index) { 850 851 $results = array(); 852 853 /// Get the real index name 854 $dbindexname = find_index_name($xmldb_table, $xmldb_index); 855 856 /// Replace TABLENAME and INDEXNAME as needed 857 $dropsql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->drop_index_sql); 858 $dropsql = str_replace('INDEXNAME', $dbindexname, $dropsql); 859 860 $results[] = $dropsql; 861 862 return $results; 863 } 864 865 /** 866 * Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to rename the index in the table 867 * Experimental! Shouldn't be used at all! 868 */ 869 870 function getRenameIndexSQL($xmldb_table, $xmldb_index, $newname) { 871 872 $results = array(); 873 874 /// Get the real index name 875 $dbindexname = find_index_name($xmldb_table, $xmldb_index); 876 877 /// Replace TABLENAME and INDEXNAME as needed 878 $renamesql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->rename_index_sql); 879 $renamesql = str_replace('OLDINDEXNAME', $dbindexname, $renamesql); 880 $renamesql = str_replace('NEWINDEXNAME', $newname, $renamesql); 881 882 /// Some DB doesn't support index renaming (MySQL) so this can be empty 883 if ($renamesql) { 884 $results[] = $renamesql; 885 } 886 887 return $results; 888 } 889 890 /** 891 * Given three strings (table name, list of fields (comma separated) and suffix), 892 * create the proper object name quoting it if necessary. 893 * 894 * IMPORTANT: This function must be used to CALCULATE NAMES of objects TO BE CREATED, 895 * NEVER TO GUESS NAMES of EXISTING objects!!! 896 */ 897 function getNameForObject($tablename, $fields, $suffix='') { 898 899 $name = ''; 900 901 /// Implement one basic cache to avoid object name duplication 902 /// and to speed up repeated queries for the same objects 903 if (!isset($used_names)) { 904 static $used_names = array(); 905 } 906 907 /// If this exact object has been requested, return it 908 if (array_key_exists($tablename.'-'.$fields.'-'.$suffix, $used_names)) { 909 return $used_names[$tablename.'-'.$fields.'-'.$suffix]; 910 } 911 912 /// Use standard naming. See http://docs.moodle.org/en/XMLDB_key_and_index_naming 913 $tablearr = explode ('_', $tablename); 914 foreach ($tablearr as $table) { 915 $name .= substr(trim($table),0,4); 916 } 917 $name .= '_'; 918 $fieldsarr = explode (',', $fields); 919 foreach ($fieldsarr as $field) { 920 $name .= substr(trim($field),0,3); 921 } 922 /// Prepend the prefix 923 $name = $this->prefix . $name; 924 925 $name = substr(trim($name), 0, $this->names_max_length - 1 - strlen($suffix)); //Max names_max_length 926 927 /// Add the suffix 928 $namewithsuffix = $name; 929 if ($suffix) { 930 $namewithsuffix = $namewithsuffix . '_' . $suffix; 931 } 932 933 /// If the calculated name is in the cache, or if we detect it by introspecting the DB let's modify if 934 if (in_array($namewithsuffix, $used_names) || $this->isNameInUse($namewithsuffix, $suffix, $tablename)) { 935 $counter = 2; 936 /// If have free space, we add 2 937 if (strlen($namewithsuffix) < $this->names_max_length) { 938 $newname = $name . $counter; 939 /// Else replace the last char by 2 940 } else { 941 $newname = substr($name, 0, strlen($name)-1) . $counter; 942 } 943 $newnamewithsuffix = $newname; 944 if ($suffix) { 945 $newnamewithsuffix = $newnamewithsuffix . '_' . $suffix; 946 } 947 /// Now iterate until not used name is found, incrementing the counter 948 while (in_array($newnamewithsuffix, $used_names) || $this->isNameInUse($newnamewithsuffix, $suffix, $tablename)) { 949 $counter++; 950 $newname = substr($name, 0, strlen($newname)-1) . $counter; 951 $newnamewithsuffix = $newname; 952 if ($suffix) { 953 $newnamewithsuffix = $newnamewithsuffix . '_' . $suffix; 954 } 955 } 956 $namewithsuffix = $newnamewithsuffix; 957 } 958 959 /// Add the name to the cache 960 $used_names[$tablename.'-'.$fields.'-'.$suffix] = $namewithsuffix; 961 962 /// Quote it if necessary (reserved words) 963 $namewithsuffix = $this->getEncQuoted($namewithsuffix); 964 965 return $namewithsuffix; 966 } 967 968 /** 969 * Given any string (or one array), enclose it by the proper quotes 970 * if it's a reserved word 971 */ 972 function getEncQuoted($input) { 973 974 if (is_array($input)) { 975 foreach ($input as $key=>$content) { 976 $input[$key] = $this->getEncQuoted($content); 977 } 978 return $input; 979 } else { 980 /// Always lowercase 981 $input = strtolower($input); 982 /// if reserved or quote_all, quote it 983 if ($this->quote_all || in_array($input, $this->reserved_words)) { 984 $input = $this->quote_string . $input . $this->quote_string; 985 } 986 return $input; 987 } 988 } 989 990 /** 991 * Given one XMLDB Statement, build the needed SQL insert sentences to execute it 992 */ 993 function getExecuteInsertSQL($statement) { 994 995 $results = array(); //Array where all the sentences will be stored 996 997 if ($sentences = $statement->getSentences()) { 998 foreach ($sentences as $sentence) { 999 /// Get the list of fields 1000 $fields = $statement->getFieldsFromInsertSentence($sentence); 1001 /// Get the values of fields 1002 $values = $statement->getValuesFromInsertSentence($sentence); 1003 /// Look if we have some CONCAT value and transform it dinamically 1004 foreach($values as $key => $value) { 1005 /// Trim single quotes 1006 $value = trim($value,"'"); 1007 if (stristr($value, 'CONCAT') !== false){ 1008 /// Look for data between parentesis 1009 preg_match("/CONCAT\s*\((.*)\)$/is", trim($value), $matches); 1010 if (isset($matches[1])) { 1011 $part = $matches[1]; 1012 /// Convert the comma separated string to an array 1013 $arr = XMLDBObject::comma2array($part); 1014 if ($arr) { 1015 $value = $this->getConcatSQL($arr); 1016 } 1017 } 1018 } 1019 /// Values to be sent to DB must be properly escaped 1020 $value = addslashes($value); 1021 /// Back trimmed quotes 1022 $value = "'" . $value . "'"; 1023 /// Back to the array 1024 $values[$key] = $value; 1025 } 1026 1027 /// Iterate over fields, escaping them if necessary 1028 foreach($fields as $key => $field) { 1029 $fields[$key] = $this->getEncQuoted($field); 1030 } 1031 /// Build the final SQL sentence and add it to the array of results 1032 $sql = 'INSERT INTO ' . $this->getEncQuoted($this->prefix . $statement->getTable()) . 1033 '(' . implode(', ', $fields) . ') ' . 1034 'VALUES (' . implode(', ', $values) . ')'; 1035 $results[] = $sql; 1036 } 1037 1038 } 1039 return $results; 1040 } 1041 1042 /** 1043 * Given one array of elements, build de proper CONCAT expresion, based 1044 * in the $concat_character setting. If such setting is empty, then 1045 * MySQL's CONCAT function will be used instead 1046 */ 1047 function getConcatSQL($elements) { 1048 1049 /// Replace double quoted elements by single quotes 1050 foreach($elements as $key => $element) { 1051 $element = trim($element); 1052 if (substr($element, 0, 1) == '"' && 1053 substr($element, -1, 1) == '"') { 1054 $elements[$key] = "'" . trim($element, '"') . "'"; 1055 } 1056 } 1057 1058 /// Now call the standard sql_concat() DML function 1059 return call_user_func_array('sql_concat', $elements); 1060 } 1061 1062 /** 1063 * Given one string (or one array), ends it with statement_end 1064 */ 1065 function getEndedStatements ($input) { 1066 1067 if (is_array($input)) { 1068 foreach ($input as $key=>$content) { 1069 $input[$key] = $this->getEndedStatements($content); 1070 } 1071 return $input; 1072 } else { 1073 $input = trim($input) . $this->statement_end; 1074 return $input; 1075 } 1076 } 1077 1078 /** 1079 * Returns the name (string) of the sequence used in the table for the autonumeric pk 1080 * Only some DB have this implemented 1081 */ 1082 function getSequenceFromDB($xmldb_table) { 1083 return false; 1084 } 1085 1086 /** 1087 * Given one object name and it's type (pk, uk, fk, ck, ix, uix, seq, trg) 1088 * return if such name is currently in use (true) or no (false) 1089 * (MySQL requires the whole XMLDBTable object to be specified, so we add it always) 1090 * (invoked from getNameForObject() 1091 * Only some DB have this implemented 1092 */ 1093 function isNameInUse($object_name, $type, $table_name) { 1094 return false; //For generators not implementing introspecion, 1095 //we always return with the name being free to be used 1096 } 1097 1098 1099 /// ALL THESE FUNCTION MUST BE CUSTOMISED BY ALL THE XMLDGenerator classes 1100 1101 /** 1102 * Given one XMLDB Type, lenght and decimals, returns the DB proper SQL type 1103 */ 1104 function getTypeSQL ($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) { 1105 return 'code for type(precision) goes to function getTypeSQL()'; 1106 } 1107 1108 /** 1109 * Given one XMLDB Field, return its enum SQL to be added inline with the column definition 1110 */ 1111 function getEnumSQL ($xmldb_field) { 1112 return 'code for inline enum declaration goes to function getEnumSQL(). Can be disabled with enum_inline_code=false'; 1113 } 1114 1115 /** 1116 * Returns the code needed to create one enum for the xmldb_table and xmldb_field passes 1117 */ 1118 function getEnumExtraSQL ($xmldb_table, $xmldb_field) { 1119 return 'Code for extra enum SQL goes to getEnumExtraSQL(). Can be disabled with enum_extra_code=false'; 1120 } 1121 1122 /** 1123 * Returns the code (array of statements) needed to execute extra statements on field rename 1124 */ 1125 function getRenameFieldExtraSQL ($xmldb_table, $xmldb_field) { 1126 return array('Code for field rename goes to getRenameFieldExtraSQL(). Can be disabled with rename_column_extra_code=false;'); 1127 } 1128 1129 /** 1130 * Returns the code (array of statements) needed 1131 * to create one sequence for the xmldb_table and xmldb_field passes 1132 */ 1133 function getCreateSequenceSQL ($xmldb_table, $xmldb_field) { 1134 return array('Code for extra sequence SQL goes to getCreateSequenceSQL(). Can be disabled with sequence_extra_code=false'); 1135 } 1136 1137 /** 1138 * Returns the code (array of statements) needed to add one comment to the table 1139 */ 1140 function getCommentSQL ($xmldb_table) { 1141 return array('Code for table comment goes to getCommentSQL(). Can be disabled with add_table_comments=false;'); 1142 } 1143 1144 /** 1145 * Returns the code (array of statements) needed to execute extra statements on table rename 1146 */ 1147 function getRenameTableExtraSQL ($xmldb_table) { 1148 return array('Code for table rename goes to getRenameTableExtraSQL(). Can be disabled with rename_table_extra_code=false;'); 1149 } 1150 1151 /** 1152 * Returns the code (array of statements) needed to execute extra statements on table drop 1153 */ 1154 function getDropTableExtraSQL ($xmldb_table) { 1155 return array('Code for table drop goes to getDropTableExtraSQL(). Can be disabled with drop_table_extra_code=false;'); 1156 } 1157 1158 /** 1159 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum 1160 * (usually invoked from getModifyEnumSQL() 1161 */ 1162 function getDropEnumSQL($xmldb_table, $xmldb_field) { 1163 return array('Code to drop one enum goes to getDropEnumSQL()'); 1164 } 1165 1166 /** 1167 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add its enum 1168 * (usually invoked from getModifyEnumSQL() 1169 */ 1170 function getCreateEnumSQL($xmldb_table, $xmldb_field) { 1171 return array('Code to create one enum goes to getCreateEnumSQL()'); 1172 } 1173 1174 /** 1175 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default 1176 * (usually invoked from getModifyDefaultSQL() 1177 */ 1178 function getDropDefaultSQL($xmldb_table, $xmldb_field) { 1179 return array('Code to drop one default goes to getDropDefaultSQL()'); 1180 } 1181 1182 /** 1183 * Given one XMLDBTable and one optional XMLDBField, return one array with all the check 1184 * constrainst found for that table (or field). Must exist for each DB supported. 1185 * (usually invoked from find_check_constraint_name) 1186 */ 1187 function getCheckConstraintsFromDB($xmldb_table, $xmldb_field=null) { 1188 return array('Code to fetch check constraints goes to getCheckConstraintsFromDB()'); 1189 } 1190 1191 /** 1192 * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add its default 1193 * (usually invoked from getModifyDefaultSQL() 1194 */ 1195 function getCreateDefaultSQL($xmldb_table, $xmldb_field) { 1196 return array('Code to create one default goes to getCreateDefaultSQL()'); 1197 } 1198 1199 /** 1200 * Returns an array of reserved words (lowercase) for this DB 1201 * You MUST provide the real list for each DB inside every XMLDB class 1202 */ 1203 function getReservedWords() { 1204 /// Some well-know reserved words 1205 $reserved_words = array ( 1206 'user', 'scale', 'type', 'comment', 'view', 'value', 'table', 'index', 'key', 'sequence', 'trigger' 1207 ); 1208 return $reserved_words; 1209 } 1210 1211 /** 1212 * Returns an array of tables to be built without prefix (lowercase) 1213 * It's enough to keep updated here this function. 1214 */ 1215 function getTablesWithoutPrefix() { 1216 /// Some well-known tables to be created without prefix 1217 $tables = array ( 1218 'adodb_logsql' 1219 ); 1220 return $tables; 1221 } 1222 } 1223 1224 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 14 11:33:29 2009 | Cross-referenced by PHPXref 0.7 |