[ Index ] |
|
Code source de LifeType 1.2.4 |
1 <?php 2 3 /** 4 V4.54 5 Nov 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved. 5 Released under both BSD license and Lesser GPL library license. 6 Whenever there is any discrepancy between the two licenses, 7 the BSD license will take precedence. 8 */ 9 10 11 12 // compatibility stuff 13 if (!function_exists('ctype_alnum')) { 14 function ctype_alnum($text) { 15 return preg_match('/^[a-z0-9]*$/i', $text); 16 } 17 } 18 19 20 /** 21 * Base class for data dictionaries. Data dictionaries allow to use a meta-language to describe a database schema, which 22 * will be processed by the data dictionary and which will allow to automatically modify a database. This meta-language 23 * is independent of the database being used, so it can be used in different database environments. 24 * 25 * Data dictionaries in PDb work in exactly the same way as in ADOdb, please see more details about data dictionaries here: 26 * http://phplens.com/lens/adodb/docs-datadict.htm. 27 * 28 * \ingroup PDb 29 */ 30 class PDbBaseDataDict 31 { 32 var $connection; 33 var $debug = false; 34 var $dropTable = 'DROP TABLE %s'; 35 var $renameTable = 'RENAME TABLE %s TO %s'; 36 var $dropIndex = 'DROP INDEX %s'; 37 var $addCol = ' ADD'; 38 var $alterCol = ' ALTER COLUMN'; 39 var $dropCol = ' DROP COLUMN'; 40 var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s'; // table, old-column, new-column, column-definitions (not used by default) 41 var $nameRegex = '\w'; 42 var $schema = false; 43 var $serverInfo = array(); 44 var $autoIncrement = false; 45 var $dataProvider; 46 var $upperName; 47 var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql 48 var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob 49 /// in other words, we use a text area for editting. 50 51 52 /** 53 * Parse arguments, treat "text" (text) and 'text' as quotation marks. 54 * To escape, use "" or '' or )) 55 * 56 * Will read in "abc def" sans quotes, as: abc def 57 * Same with 'abc def'. 58 * However if `abc def`, then will read in as `abc def` 59 * 60 * @param endstmtchar Character that indicates end of statement 61 * @param tokenchars Include the following characters in tokens apart from A-Z and 0-9 62 * @returns 2 dimensional array containing parsed tokens. 63 */ 64 function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-') 65 { 66 $pos = 0; 67 $intoken = false; 68 $stmtno = 0; 69 $endquote = false; 70 $tokens = array(); 71 $tokarr = array(); 72 $tokens[$stmtno] = array(); 73 $max = strlen($args); 74 $quoted = false; 75 76 while ($pos < $max) { 77 $ch = substr($args,$pos,1); 78 switch($ch) { 79 case ' ': 80 case "\t": 81 case "\n": 82 case "\r": 83 if (!$quoted) { 84 if ($intoken) { 85 $intoken = false; 86 $tokens[$stmtno][] = implode('',$tokarr); 87 } 88 break; 89 } 90 91 $tokarr[] = $ch; 92 break; 93 94 case '`': 95 if ($intoken) $tokarr[] = $ch; 96 case '(': 97 case ')': 98 case '"': 99 case "'": 100 101 if ($intoken) { 102 if (empty($endquote)) { 103 $tokens[$stmtno][] = implode('',$tokarr); 104 if ($ch == '(') $endquote = ')'; 105 else $endquote = $ch; 106 $quoted = true; 107 $intoken = true; 108 $tokarr = array(); 109 } else if ($endquote == $ch) { 110 $ch2 = substr($args,$pos+1,1); 111 if ($ch2 == $endquote) { 112 $pos += 1; 113 $tokarr[] = $ch2; 114 } else { 115 $quoted = false; 116 $intoken = false; 117 $tokens[$stmtno][] = implode('',$tokarr); 118 $endquote = ''; 119 } 120 } else 121 $tokarr[] = $ch; 122 123 }else { 124 125 if ($ch == '(') $endquote = ')'; 126 else $endquote = $ch; 127 $quoted = true; 128 $intoken = true; 129 $tokarr = array(); 130 if ($ch == '`') $tokarr[] = '`'; 131 } 132 break; 133 134 default: 135 136 if (!$intoken) { 137 if ($ch == $endstmtchar) { 138 $stmtno += 1; 139 $tokens[$stmtno] = array(); 140 break; 141 } 142 143 $intoken = true; 144 $quoted = false; 145 $endquote = false; 146 $tokarr = array(); 147 148 } 149 150 if ($quoted) $tokarr[] = $ch; 151 else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch; 152 else { 153 if ($ch == $endstmtchar) { 154 $tokens[$stmtno][] = implode('',$tokarr); 155 $stmtno += 1; 156 $tokens[$stmtno] = array(); 157 $intoken = false; 158 $tokarr = array(); 159 break; 160 } 161 $tokens[$stmtno][] = implode('',$tokarr); 162 $tokens[$stmtno][] = $ch; 163 $intoken = false; 164 } 165 } 166 $pos += 1; 167 } 168 if ($intoken) $tokens[$stmtno][] = implode('',$tokarr); 169 170 return $tokens; 171 } 172 173 /** 174 * Given a field, return its metatype based on its real type, i.e. 'VARCHAR' would return 'C', 175 * 'TIMESTAMP' would return 'T' and so on. This method must be implemented by child classes as each 176 * database has its own data types. 177 * 178 * @param t The type 179 * @param len the field length 180 * @param fieldobj 181 * @return Returns a string with the meta type 182 */ 183 function MetaType($t,$len=-1,$fieldobj=false) 184 { 185 // to be implemented by child classes 186 } 187 188 /** 189 * Returns information about the tables in the current connection (a list of them) 190 * 191 * @return An array with the tables 192 */ 193 function &MetaTables() 194 { 195 if (!$this->connection->IsConnected()) return array(); 196 return $this->connection->MetaTables(); 197 } 198 199 /** 200 * Returns information (the table schema) about the given table 201 * 202 * @param tab Name of the table 203 * @param upper 204 * @param schema 205 * @return An array with the table schema 206 */ 207 function &MetaColumns($tab, $upper=true, $schema=false) 208 { 209 if (!$this->connection->IsConnected()) return array(); 210 return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema); 211 } 212 213 /** 214 * Returns information about primary keys in the given table 215 * 216 * @param tab Name of the table 217 * @param upper 218 * @param schema 219 * @return An array with information about the primary keys 220 */ 221 function &MetaPrimaryKeys($tab,$owner=false,$intkey=false) 222 { 223 if (!$this->connection->IsConnected()) return array(); 224 return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey); 225 } 226 227 /** 228 * Returns information about indexes in the given table 229 * 230 * @param tab Name of the table 231 * @param upper 232 * @param schema 233 * @return An array with information about the indexes 234 */ 235 function &MetaIndexes($table, $primary = false, $owner = false) 236 { 237 if (!$this->connection->IsConnected()) return array(); 238 return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner); 239 } 240 241 /** 242 * Adds quotes around a name if necessary 243 * 244 * @param name The name that should be quoted 245 * @return The quoted name if it needed any quotes, or unquoted if it didn't 246 */ 247 function NameQuote($name = NULL) 248 { 249 if (!is_string($name)) { 250 return FALSE; 251 } 252 253 $name = trim($name); 254 255 if ( !is_object($this->connection) ) { 256 return $name; 257 } 258 259 $quote = $this->connection->nameQuote; 260 261 // if name is of the form `name`, quote it 262 if ( preg_match('/^`(.+)`$/', $name, $matches) ) { 263 return $quote . $matches[1] . $quote; 264 } 265 266 // if name contains special characters, quote it 267 if ( !preg_match('/^[' . $this->nameRegex . ']+$/', $name) ) { 268 return $quote . $name . $quote; 269 } 270 271 return $name; 272 } 273 274 /** 275 * tbd 276 */ 277 function TableName($name) 278 { 279 if ( $this->schema ) { 280 return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name); 281 } 282 return $this->NameQuote($name); 283 } 284 285 /** 286 * Executes the sql array returned by GetTableSQL and GetIndexSQL 287 * 288 * @param sql The SQL code to be executed, passed as an array of queries 289 * @param continueOnError Whether to stop after an error or not 290 * @return True if successful or false otherwise 291 */ 292 function ExecuteSQLArray($sql, $continueOnError = true) 293 { 294 $rez = 2; 295 $conn = &$this->connection; 296 //$saved = $conn->debug; 297 foreach($sql as $line) { 298 299 if ($this->debug) $conn->debug = true; 300 $ok = $conn->Execute($line); 301 //$conn->debug = $saved; 302 if (!$ok) { 303 if ($this->debug) print($conn->ErrorMsg()); 304 if (!$continueOnError) return 0; 305 $rez = 1; 306 } 307 } 308 return $rez; 309 } 310 311 /** 312 * Given a metatype, return its equivalent database type 313 * 314 * @param meta The meta-type: 315 * - C: varchar 316 * - X: CLOB (character large object) or largest varchar size if CLOB is not supported 317 * - C2: Multibyte varchar 318 * - X2: Multibyte CLOB 319 * - B: BLOB (binary large object) 320 * - D: Date 321 * - T: Date-time 322 * - L: Integer field suitable for storing booleans (0 or 1) 323 * - I: Integer 324 * - F: Floating point number 325 * - N: Numeric or decimal number 326 * @return Returns a string with the real type 327 */ 328 function ActualType($meta) 329 { 330 return $meta; 331 } 332 333 /** 334 * Returns the SQL code necessary to create the given database 335 * 336 * @param dbname Name of the new database 337 * @param options Any additional options needed to create the database, or empty as default 338 * @return An array with SQL code needed to create the database 339 */ 340 function CreateDatabase($dbname,$options=false) 341 { 342 $options = $this->_Options($options); 343 $sql = array(); 344 345 $s = 'CREATE DATABASE ' . $this->NameQuote($dbname); 346 if (isset($options[$this->upperName])) 347 $s .= ' '.$options[$this->upperName]; 348 349 $sql[] = $s; 350 return $sql; 351 } 352 353 /** 354 * Generates the SQL to create index. 355 * 356 * @param idxname Name of the index 357 * @param tabname Name of the table where the index will be created 358 * @param flds Names of the fields on which the index will work 359 * @param idxoptions Options needed to create the index 360 * @return Returns an array of sql strings. 361 */ 362 function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false) 363 { 364 if (!is_array($flds)) { 365 $flds = explode(',',$flds); 366 } 367 368 foreach($flds as $key => $fld) { 369 $flds[$key] = $this->NameQuote($fld); 370 } 371 372 return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions)); 373 } 374 375 /** 376 * Removes an index from a table 377 * 378 * @param idxname Name of the index 379 * @param tabname Name of the table in which the index exists 380 * @return Returns an array of SQL strings needed to remove an index 381 */ 382 function DropIndexSQL ($idxname, $tabname = NULL) 383 { 384 return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname))); 385 } 386 387 /** 388 * tbd 389 */ 390 function SetSchema($schema) 391 { 392 $this->schema = $schema; 393 } 394 395 /** 396 * Returns SQL code needed to add a colum to the database table 397 * 398 * @param tabname Name of the table 399 * @param flds An array with all the fields that will be added to the database 400 * @return An array with SQL code 401 function AddColumnSQL($tabname, $flds) 402 { 403 $tabname = $this->TableName ($tabname); 404 $sql = array(); 405 list($lines,$pkey) = $this->_GenFields($flds); 406 $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; 407 foreach($lines as $v) { 408 $sql[] = $alter . $v; 409 } 410 return $sql; 411 } 412 413 /** 414 * Change the definition of one column 415 * 416 * As some DBM's can't do that on there own, you need to supply the complete defintion of the new table, 417 * to allow, recreating the table and copying the content over to the new table 418 * @param string $tabname table-name 419 * @param string $flds column-name and type for the changed column 420 * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' 421 * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' 422 * @return array with SQL strings 423 */ 424 function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') 425 { 426 $tabname = $this->TableName ($tabname); 427 $sql = array(); 428 list($lines,$pkey) = $this->_GenFields($flds); 429 $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; 430 foreach($lines as $v) { 431 $sql[] = $alter . $v; 432 } 433 return $sql; 434 } 435 436 /** 437 * Rename one column 438 * 439 * Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql) 440 * @param string $tabname table-name 441 * @param string $oldcolumn column-name to be renamed 442 * @param string $newcolumn new column-name 443 * @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default='' 444 * @return array with SQL strings 445 */ 446 function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='') 447 { 448 $tabname = $this->TableName ($tabname); 449 if ($flds) { 450 list($lines,$pkey) = $this->_GenFields($flds); 451 list(,$first) = each($lines); 452 list(,$column_def) = split("[\t ]+",$first,2); 453 } 454 return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def)); 455 } 456 457 /** 458 * Drop one column 459 * 460 * Some DBM's can't do that on there own, you need to supply the complete defintion of the new table, 461 * to allow, recreating the table and copying the content over to the new table 462 * @param string $tabname table-name 463 * @param string $flds column-name and type for the changed column 464 * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default '' 465 * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default '' 466 * @return array with SQL strings 467 */ 468 function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') 469 { 470 $tabname = $this->TableName ($tabname); 471 if (!is_array($flds)) $flds = explode(',',$flds); 472 $sql = array(); 473 $alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' '; 474 foreach($flds as $v) { 475 $sql[] = $alter . $this->NameQuote($v); 476 } 477 return $sql; 478 } 479 480 /** 481 * Generate the SQL to drop a table 482 * 483 * @param tabname Name of the table 484 * @return An array with SQL code to drop the table. 485 */ 486 function DropTableSQL($tabname) 487 { 488 return array (sprintf($this->dropTable, $this->TableName($tabname))); 489 } 490 491 /** 492 * Generate the SQL to rename a table 493 * 494 * @param tabname Name of the table 495 * @return An array with SQL code to rename the table. 496 */ 497 function RenameTableSQL($tabname,$newname) 498 { 499 return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname))); 500 } 501 502 /** 503 * Generate the SQL to create table. Returns an array of sql strings. 504 * 505 * @param tabname Name of the table 506 * @param flds Table schema 507 * @param tableoptions Any extra options needed to create the table 508 * @return An array with SQL code to create the table according to the schema 509 */ 510 function CreateTableSQL($tabname, $flds, $tableoptions=false) 511 { 512 if (!$tableoptions) $tableoptions = array(); 513 514 list($lines,$pkey) = $this->_GenFields($flds, true); 515 516 $taboptions = $this->_Options($tableoptions); 517 $tabname = $this->TableName ($tabname); 518 $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions); 519 $idxs = $this->_IndexesSQL($tabname,$flds); 520 521 $tsql = $this->_Triggers($tabname,$taboptions); 522 foreach($tsql as $s) $sql[] = $s; 523 foreach($idxs as $i) $sql[] = $i; 524 525 return $sql; 526 } 527 528 /** 529 * @private 530 */ 531 function _Triggers($tabname,$taboptions) 532 { 533 return array(); 534 } 535 536 /** 537 * @private 538 */ 539 function _array_change_key_case($an_array) 540 { 541 if (is_array($an_array)) { 542 $new_array = array(); 543 foreach($an_array as $key=>$value) 544 $new_array[strtoupper($key)] = $value; 545 546 return $new_array; 547 } 548 549 return $an_array; 550 } 551 552 /** 553 * @private 554 */ 555 function _GenFields($flds,$widespacing=false) 556 { 557 if (is_string($flds)) { 558 $padding = ' '; 559 $txt = $flds.$padding; 560 $flds = array(); 561 $flds0 = PDbBaseDataDict::Lens_ParseArgs($txt,','); 562 $hasparam = false; 563 foreach($flds0 as $f0) { 564 565 // ignore index fields 566 if( in_array( $f0[0], Array( "INDEX", "FULLTEXT", "HASH", "UNIQUE", "CLUSTERED", "BITMAP", "DROP" ))) 567 continue; 568 569 $f1 = array(); 570 foreach($f0 as $token) { 571 switch (strtoupper($token)) { 572 case 'CONSTRAINT': 573 case 'DEFAULT': 574 $hasparam = $token; 575 break; 576 default: 577 if ($hasparam) $f1[$hasparam] = $token; 578 else $f1[] = $token; 579 $hasparam = false; 580 break; 581 } 582 } 583 $flds[] = $f1; 584 585 } 586 } 587 $this->autoIncrement = false; 588 $lines = array(); 589 $pkey = array(); 590 foreach($flds as $fld) { 591 592 $fld = PDbBaseDataDict::_array_change_key_case($fld); 593 594 $fname = false; 595 $fdefault = false; 596 $fautoinc = false; 597 $ftype = false; 598 $fsize = false; 599 $fprec = false; 600 $fprimary = false; 601 $fnoquote = false; 602 $fdefts = false; 603 $fdefdate = false; 604 $fconstraint = false; 605 $fnotnull = false; 606 $funsigned = false; 607 608 //----------------- 609 // Parse attributes 610 foreach($fld as $attr => $v) { 611 if ($attr == 2 && is_numeric($v)) $attr = 'SIZE'; 612 else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v); 613 614 switch($attr) { 615 case '0': 616 case 'NAME': $fname = $v; break; 617 case '1': 618 case 'TYPE': $ty = $v; $ftype = $this->ActualType(strtoupper($v)); break; 619 620 case 'SIZE': 621 $dotat = strpos($v,'.'); if ($dotat === false) $dotat = strpos($v,','); 622 if ($dotat === false) $fsize = $v; 623 else { 624 $fsize = substr($v,0,$dotat); 625 $fprec = substr($v,$dotat+1); 626 } 627 break; 628 case 'UNSIGNED': $funsigned = true; break; 629 case 'AUTOINCREMENT': 630 case 'AUTO': $fautoinc = true; $fnotnull = true; break; 631 case 'KEY': 632 case 'PRIMARY': $fprimary = $v; $fnotnull = true; break; 633 case 'DEF': 634 case 'DEFAULT': $fdefault = $v; break; 635 case 'NOTNULL': $fnotnull = $v; break; 636 case 'NOQUOTE': $fnoquote = $v; break; 637 case 'DEFDATE': $fdefdate = $v; break; 638 case 'DEFTIMESTAMP': $fdefts = $v; break; 639 case 'CONSTRAINT': $fconstraint = $v; break; 640 } //switch 641 } // foreach $fld 642 643 //-------------------- 644 // VALIDATE FIELD INFO 645 if (!strlen($fname)) { 646 if ($this->debug) print("Undefined NAME"); 647 return false; 648 } 649 650 $fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname)); 651 $fname = $this->NameQuote($fname); 652 653 if (!strlen($ftype)) { 654 if ($this->debug) print("Undefined TYPE for field '$fname'"); 655 return false; 656 } else { 657 $ftype = strtoupper($ftype); 658 } 659 660 $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec); 661 662 if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls 663 664 if ($fprimary) $pkey[] = $fname; 665 666 // some databases do not allow blobs to have defaults 667 if ($ty == 'X') $fdefault = false; 668 669 //-------------------- 670 // CONSTRUCT FIELD SQL 671 if ($fdefts) { 672 if (substr($this->connection->_type,0,5) == 'mysql') { 673 $ftype = 'TIMESTAMP'; 674 } else { 675 $fdefault = $this->connection->sysTimeStamp; 676 } 677 } else if ($fdefdate) { 678 if (substr($this->connection->_type,0,5) == 'mysql') { 679 $ftype = 'TIMESTAMP'; 680 } else { 681 $fdefault = $this->connection->sysDate; 682 } 683 } else if (strlen($fdefault) && !$fnoquote) { 684 if ($ty == 'C' or $ty == 'X' or 685 ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) 686 if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') 687 $fdefault = trim($fdefault); 688 else if (strtolower($fdefault) != 'null') { 689 //$fdefault = $this->connection->qstr($fdefault); 690 $fdefault = "'".$fdefault."'"; 691 } 692 } 693 $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned); 694 695 if ($widespacing) $fname = str_pad($fname,24); 696 $lines[$fid] = $fname.' '.$ftype.$suffix; 697 698 if ($fautoinc) $this->autoIncrement = true; 699 } // foreach $flds 700 701 return array($lines,$pkey); 702 } 703 704 /** 705 * @private 706 */ 707 function _IndexesSQL($tabname,$flds) 708 { 709 if (is_string($flds)) { 710 $padding = ' '; 711 $txt = $flds.$padding; 712 $flds = array(); 713 $flds0 = PDbBaseDataDict::Lens_ParseArgs($txt,','); 714 $hasparam = false; 715 foreach($flds0 as $f0) { 716 717 // ignore non-index fields 718 if( !in_array( $f0[0], Array( "INDEX", "FULLTEXT", "HASH", "UNIQUE", "CLUSTERED", "BITMAP", "DROP" ))) 719 continue; 720 721 $flds[] = $f0; 722 } 723 } 724 $lines = array(); 725 foreach($flds as $fld) { 726 $typeStr = $fld[0]; 727 if( $typeStr == "INDEX" ) 728 $type = false; 729 else 730 $type = Array( $typeStr ); 731 732 $fld = PDbBaseDataDict::_array_change_key_case($fld); 733 $sql = $this->CreateIndexSQL( $fld[1], $tabname, $fld[2], $type ); 734 735 foreach( $sql as $s ) 736 $lines[] = $s; 737 } 738 739 return($lines); 740 } 741 742 /** 743 * @private 744 */ 745 function _GetSize($ftype, $ty, $fsize, $fprec) 746 { 747 if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) { 748 $ftype .= "(".$fsize; 749 if (strlen($fprec)) $ftype .= ",".$fprec; 750 $ftype .= ')'; 751 } 752 return $ftype; 753 } 754 755 756 // return string must begin with space 757 function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint) 758 { 759 $suffix = ''; 760 if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault"; 761 if ($fnotnull) $suffix .= ' NOT NULL'; 762 if ($fconstraint) $suffix .= ' '.$fconstraint; 763 return $suffix; 764 } 765 766 /** 767 * @private 768 */ 769 function _IndexSQL($idxname, $tabname, $flds, $idxoptions) 770 { 771 $sql = array(); 772 773 if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) { 774 $sql[] = sprintf ($this->dropIndex, $idxname); 775 if ( isset($idxoptions['DROP']) ) 776 return $sql; 777 } 778 779 if ( empty ($flds) ) { 780 return $sql; 781 } 782 783 $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : ''; 784 785 $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' '; 786 787 if ( isset($idxoptions[$this->upperName]) ) 788 $s .= $idxoptions[$this->upperName]; 789 790 if ( is_array($flds) ) 791 $flds = implode(', ',$flds); 792 $s .= '(' . $flds . ')'; 793 $sql[] = $s; 794 795 return $sql; 796 } 797 798 /** 799 * @private 800 */ 801 function _DropAutoIncrement($tabname) 802 { 803 return false; 804 } 805 806 /** 807 * @private 808 */ 809 function _TableSQL($tabname,$lines,$pkey,$tableoptions) 810 { 811 $sql = array(); 812 813 if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) { 814 $sql[] = sprintf($this->dropTable,$tabname); 815 if ($this->autoIncrement) { 816 $sInc = $this->_DropAutoIncrement($tabname); 817 if ($sInc) $sql[] = $sInc; 818 } 819 if ( isset ($tableoptions['DROP']) ) { 820 return $sql; 821 } 822 } 823 $s = "CREATE TABLE $tabname (\n"; 824 $s .= implode(",\n", $lines); 825 if (sizeof($pkey)>0) { 826 $s .= ",\n PRIMARY KEY ("; 827 $s .= implode(", ",$pkey).")"; 828 } 829 if (isset($tableoptions['CONSTRAINTS'])) 830 $s .= "\n".$tableoptions['CONSTRAINTS']; 831 832 if (isset($tableoptions[$this->upperName.'_CONSTRAINTS'])) 833 $s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS']; 834 835 $s .= "\n) "; 836 if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName]; 837 $sql[] = $s; 838 839 return $sql; 840 } 841 842 /** 843 * Sanitize options, so that array elements with no keys are promoted to keys 844 * 845 * @private 846 */ 847 function _Options($opts) 848 { 849 if (!is_array($opts)) return array(); 850 $newopts = array(); 851 foreach($opts as $k => $v) { 852 if (is_numeric($k)) $newopts[strtoupper($v)] = $v; 853 else $newopts[strtoupper($k)] = $v; 854 } 855 return $newopts; 856 } 857 858 /** 859 * Generate the SQL to modify the schema of a table 860 * 861 * @param tabname Name of the table 862 * @param flds The new table schema 863 * @param tableoptions Any extra options needed 864 * @return An array with SQL code to modify the schema of the given table 865 */ 866 function ChangeTableSQL($tablename, $flds, $tableoptions = false) 867 { 868 // check table exists 869 $cols = &$this->MetaColumns($tablename); 870 if ( empty($cols)) { 871 return $this->CreateTableSQL($tablename, $flds, $tableoptions); 872 } 873 874 // already exists, alter table instead 875 list($lines,$pkey) = $this->_GenFields($flds); 876 $alter = 'ALTER TABLE ' . $this->TableName($tablename); 877 foreach ( $lines as $id => $v ) { 878 if ( isset($cols[$id]) && is_object($cols[$id]) ) { 879 880 $flds = PDbBaseDataDict::Lens_ParseArgs($v,','); 881 882 // We are trying to change the size of the field, if not allowed, simply ignore the request. 883 if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) continue; 884 885 $sql[] = $alter . $this->alterCol . ' ' . $v; 886 } else { 887 $sql[] = $alter . $this->addCol . ' ' . $v; 888 } 889 } 890 891 return $sql; 892 } 893 } 894 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Mon Nov 26 21:04:15 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |