Loudblog PHP Cross Reference Blogging Systems

Source: /loudblog/inc/database/adodb-datadict.inc.php - 784 lines - 21043 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /**
   4    V4.92a 29 Aug 2006  (c) 2000-2006 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    Set tabs to 4 for best viewing.
  10   
  11       DOCUMENTATION:
  12      
  13          See adodb/tests/test-datadict.php for docs and examples.
  14  */
  15  
  16  /*
  17      Test script for parser
  18  */
  19  
  20  // security - hide paths
  21  if (!defined('ADODB_DIR')) die();
  22  
  23  function Lens_ParseTest()
  24  {
  25  $str = "`zcol ACOL` NUMBER(32,2) DEFAULT 'The \"cow\" (and Jim''s dog) jumps over the moon' PRIMARY, INTI INT AUTO DEFAULT 0, zcol2\"afs ds";
  26  print "<p>$str</p>";
  27  $a= Lens_ParseArgs($str);
  28  print "<pre>";
  29  print_r($a);
  30  print "</pre>";
  31  }
  32  
  33  
  34  if (!function_exists('ctype_alnum')) {
  35  	function ctype_alnum($text) {
  36          return preg_match('/^[a-z0-9]*$/i', $text);
  37      }
  38  }
  39  
  40  //Lens_ParseTest();
  41  
  42  /**
  43      Parse arguments, treat "text" (text) and 'text' as quotation marks.
  44      To escape, use "" or '' or ))
  45      
  46      Will read in "abc def" sans quotes, as: abc def
  47      Same with 'abc def'.
  48      However if `abc def`, then will read in as `abc def`
  49      
  50      @param endstmtchar    Character that indicates end of statement
  51      @param tokenchars     Include the following characters in tokens apart from A-Z and 0-9 
  52      @returns 2 dimensional array containing parsed tokens.
  53  */
  54  function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
  55  {
  56      $pos = 0;
  57      $intoken = false;
  58      $stmtno = 0;
  59      $endquote = false;
  60      $tokens = array();
  61      $tokens[$stmtno] = array();
  62      $max = strlen($args);
  63      $quoted = false;
  64      $tokarr = array();
  65      
  66      while ($pos < $max) {
  67          $ch = substr($args,$pos,1);
  68          switch($ch) {
  69          case ' ':
  70          case "\t":
  71          case "\n":
  72          case "\r":
  73              if (!$quoted) {
  74                  if ($intoken) {
  75                      $intoken = false;
  76                      $tokens[$stmtno][] = implode('',$tokarr);
  77                  }
  78                  break;
  79              }
  80              
  81              $tokarr[] = $ch;
  82              break;
  83          
  84          case '`':
  85              if ($intoken) $tokarr[] = $ch;
  86          case '(':
  87          case ')':    
  88          case '"':
  89          case "'":
  90              
  91              if ($intoken) {
  92                  if (empty($endquote)) {
  93                      $tokens[$stmtno][] = implode('',$tokarr);
  94                      if ($ch == '(') $endquote = ')';
  95                      else $endquote = $ch;
  96                      $quoted = true;
  97                      $intoken = true;
  98                      $tokarr = array();
  99                  } else if ($endquote == $ch) {
 100                      $ch2 = substr($args,$pos+1,1);
 101                      if ($ch2 == $endquote) {
 102                          $pos += 1;
 103                          $tokarr[] = $ch2;
 104                      } else {
 105                          $quoted = false;
 106                          $intoken = false;
 107                          $tokens[$stmtno][] = implode('',$tokarr);
 108                          $endquote = '';
 109                      }
 110                  } else
 111                      $tokarr[] = $ch;
 112                      
 113              }else {
 114              
 115                  if ($ch == '(') $endquote = ')';
 116                  else $endquote = $ch;
 117                  $quoted = true;
 118                  $intoken = true;
 119                  $tokarr = array();
 120                  if ($ch == '`') $tokarr[] = '`';
 121              }
 122              break;
 123              
 124          default:
 125              
 126              if (!$intoken) {
 127                  if ($ch == $endstmtchar) {
 128                      $stmtno += 1;
 129                      $tokens[$stmtno] = array();
 130                      break;
 131                  }
 132              
 133                  $intoken = true;
 134                  $quoted = false;
 135                  $endquote = false;
 136                  $tokarr = array();
 137      
 138              }
 139              
 140              if ($quoted) $tokarr[] = $ch;
 141              else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch;
 142              else {
 143                  if ($ch == $endstmtchar) {            
 144                      $tokens[$stmtno][] = implode('',$tokarr);
 145                      $stmtno += 1;
 146                      $tokens[$stmtno] = array();
 147                      $intoken = false;
 148                      $tokarr = array();
 149                      break;
 150                  }
 151                  $tokens[$stmtno][] = implode('',$tokarr);
 152                  $tokens[$stmtno][] = $ch;
 153                  $intoken = false;
 154              }
 155          }
 156          $pos += 1;
 157      }
 158      if ($intoken) $tokens[$stmtno][] = implode('',$tokarr);
 159      
 160      return $tokens;
 161  }
 162  
 163  
 164  class ADODB_DataDict {
 165      var $connection;
 166      var $debug = false;
 167      var $dropTable = 'DROP TABLE %s';
 168      var $renameTable = 'RENAME TABLE %s TO %s'; 
 169      var $dropIndex = 'DROP INDEX %s';
 170      var $addCol = ' ADD';
 171      var $alterCol = ' ALTER COLUMN';
 172      var $dropCol = ' DROP COLUMN';
 173      var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s';    // table, old-column, new-column, column-definitions (not used by default)
 174      var $nameRegex = '\w';
 175      var $nameRegexBrackets = 'a-zA-Z0-9_\(\)';
 176      var $schema = false;
 177      var $serverInfo = array();
 178      var $autoIncrement = false;
 179      var $dataProvider;
 180      var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql
 181      var $blobSize = 100;     /// any varchar/char field this size or greater is treated as a blob
 182                              /// in other words, we use a text area for editting.
 183      
 184  	function GetCommentSQL($table,$col)
 185      {
 186          return false;
 187      }
 188      
 189  	function SetCommentSQL($table,$col,$cmt)
 190      {
 191          return false;
 192      }
 193      
 194  	function MetaTables()
 195      {
 196          if (!$this->connection->IsConnected()) return array();
 197          return $this->connection->MetaTables();
 198      }
 199      
 200  	function MetaColumns($tab, $upper=true, $schema=false)
 201      {
 202          if (!$this->connection->IsConnected()) return array();
 203          return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema);
 204      }
 205      
 206  	function MetaPrimaryKeys($tab,$owner=false,$intkey=false)
 207      {
 208          if (!$this->connection->IsConnected()) return array();
 209          return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey);
 210      }
 211      
 212  	function MetaIndexes($table, $primary = false, $owner = false)
 213      {
 214          if (!$this->connection->IsConnected()) return array();
 215          return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
 216      }
 217      
 218  	function MetaType($t,$len=-1,$fieldobj=false)
 219      {
 220          return ADORecordSet::MetaType($t,$len,$fieldobj);
 221      }
 222      
 223  	function NameQuote($name = NULL,$allowBrackets=false)
 224      {
 225          if (!is_string($name)) {
 226              return FALSE;
 227          }
 228          
 229          $name = trim($name);
 230          
 231          if ( !is_object($this->connection) ) {
 232              return $name;
 233          }
 234          
 235          $quote = $this->connection->nameQuote;
 236          
 237          // if name is of the form `name`, quote it
 238          if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
 239              return $quote . $matches[1] . $quote;
 240          }
 241          
 242          // if name contains special characters, quote it
 243          $regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex;
 244          
 245          if ( !preg_match('/^[' . $regex . ']+$/', $name) ) {
 246              return $quote . $name . $quote;
 247          }
 248          
 249          return $name;
 250      }
 251      
 252  	function TableName($name)
 253      {
 254          if ( $this->schema ) {
 255              return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name);
 256          }
 257          return $this->NameQuote($name);
 258      }
 259      
 260      // Executes the sql array returned by GetTableSQL and GetIndexSQL
 261  	function ExecuteSQLArray($sql, $continueOnError = true)
 262      {
 263          $rez = 2;
 264          $conn = &$this->connection;
 265          $saved = $conn->debug;
 266          foreach($sql as $line) {
 267              
 268              if ($this->debug) $conn->debug = true;
 269              $ok = $conn->Execute($line);
 270              $conn->debug = $saved;
 271              if (!$ok) {
 272                  if ($this->debug) ADOConnection::outp($conn->ErrorMsg());
 273                  if (!$continueOnError) return 0;
 274                  $rez = 1;
 275              }
 276          }
 277          return $rez;
 278      }
 279      
 280      /*
 281           Returns the actual type given a character code.
 282          
 283          C:  varchar
 284          X:  CLOB (character large object) or largest varchar size if CLOB is not supported
 285          C2: Multibyte varchar
 286          X2: Multibyte CLOB
 287          
 288          B:  BLOB (binary large object)
 289          
 290          D:  Date
 291          T:  Date-time 
 292          L:  Integer field suitable for storing booleans (0 or 1)
 293          I:  Integer
 294          F:  Floating point number
 295          N:  Numeric or decimal number
 296      */
 297      
 298  	function ActualType($meta)
 299      {
 300          return $meta;
 301      }
 302      
 303  	function CreateDatabase($dbname,$options=false)
 304      {
 305          $options = $this->_Options($options);
 306          $sql = array();
 307          
 308          $s = 'CREATE DATABASE ' . $this->NameQuote($dbname);
 309          if (isset($options[$this->upperName]))
 310              $s .= ' '.$options[$this->upperName];
 311          
 312          $sql[] = $s;
 313          return $sql;
 314      }
 315      
 316      /*
 317       Generates the SQL to create index. Returns an array of sql strings.
 318      */
 319  	function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false)
 320      {
 321          if (!is_array($flds)) {
 322              $flds = explode(',',$flds);
 323          }
 324          
 325          foreach($flds as $key => $fld) {
 326              # some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32)
 327              $flds[$key] = $this->NameQuote($fld,$allowBrackets=true);
 328          }
 329          
 330          return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions));
 331      }
 332      
 333  	function DropIndexSQL ($idxname, $tabname = NULL)
 334      {
 335          return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname)));
 336      }
 337      
 338  	function SetSchema($schema)
 339      {
 340          $this->schema = $schema;
 341      }
 342      
 343  	function AddColumnSQL($tabname, $flds)
 344      {
 345          $tabname = $this->TableName ($tabname);
 346          $sql = array();
 347          list($lines,$pkey) = $this->_GenFields($flds);
 348          $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
 349          foreach($lines as $v) {
 350              $sql[] = $alter . $v;
 351          }
 352          return $sql;
 353      }
 354      
 355      /**
 356       * Change the definition of one column
 357       *
 358       * As some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
 359       * to allow, recreating the table and copying the content over to the new table
 360       * @param string $tabname table-name
 361       * @param string $flds column-name and type for the changed column
 362       * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
 363       * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
 364       * @return array with SQL strings
 365       */
 366  	function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
 367      {
 368          $tabname = $this->TableName ($tabname);
 369          $sql = array();
 370          list($lines,$pkey) = $this->_GenFields($flds);
 371          $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
 372          foreach($lines as $v) {
 373              $sql[] = $alter . $v;
 374          }
 375          return $sql;
 376      }
 377      
 378      /**
 379       * Rename one column
 380       *
 381       * Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql)
 382       * @param string $tabname table-name
 383       * @param string $oldcolumn column-name to be renamed
 384       * @param string $newcolumn new column-name
 385       * @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default=''
 386       * @return array with SQL strings
 387       */
 388  	function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')
 389      {
 390          $tabname = $this->TableName ($tabname);
 391          if ($flds) {
 392              list($lines,$pkey) = $this->_GenFields($flds);
 393              list(,$first) = each($lines);
 394              list(,$column_def) = split("[\t ]+",$first,2);
 395          }
 396          return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def));
 397      }
 398          
 399      /**
 400       * Drop one column
 401       *
 402       * Some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
 403       * to allow, recreating the table and copying the content over to the new table
 404       * @param string $tabname table-name
 405       * @param string $flds column-name and type for the changed column
 406       * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
 407       * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
 408       * @return array with SQL strings
 409       */
 410  	function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
 411      {
 412          $tabname = $this->TableName ($tabname);
 413          if (!is_array($flds)) $flds = explode(',',$flds);
 414          $sql = array();
 415          $alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' ';
 416          foreach($flds as $v) {
 417              $sql[] = $alter . $this->NameQuote($v);
 418          }
 419          return $sql;
 420      }
 421      
 422  	function DropTableSQL($tabname)
 423      {
 424          return array (sprintf($this->dropTable, $this->TableName($tabname)));
 425      }
 426      
 427  	function RenameTableSQL($tabname,$newname)
 428      {
 429          return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname)));
 430      }    
 431      
 432      /*
 433       Generate the SQL to create table. Returns an array of sql strings.
 434      */
 435  	function CreateTableSQL($tabname, $flds, $tableoptions=false)
 436      {
 437          if (!$tableoptions) $tableoptions = array();
 438          
 439          list($lines,$pkey) = $this->_GenFields($flds, true);
 440          
 441          $taboptions = $this->_Options($tableoptions);
 442          $tabname = $this->TableName ($tabname);
 443          $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
 444          
 445          $tsql = $this->_Triggers($tabname,$taboptions);
 446          foreach($tsql as $s) $sql[] = $s;
 447          
 448          return $sql;
 449      }
 450      
 451  	function _GenFields($flds,$widespacing=false)
 452      {
 453          if (is_string($flds)) {
 454              $padding = '     ';
 455              $txt = $flds.$padding;
 456              $flds = array();
 457              $flds0 = Lens_ParseArgs($txt,',');
 458              $hasparam = false;
 459              foreach($flds0 as $f0) {
 460                  $f1 = array();
 461                  foreach($f0 as $token) {
 462                      switch (strtoupper($token)) {
 463                      case 'CONSTRAINT':
 464                      case 'DEFAULT': 
 465                          $hasparam = $token;
 466                          break;
 467                      default:
 468                          if ($hasparam) $f1[$hasparam] = $token;
 469                          else $f1[] = $token;
 470                          $hasparam = false;
 471                          break;
 472                      }
 473                  }
 474                  $flds[] = $f1;
 475                  
 476              }
 477          }
 478          $this->autoIncrement = false;
 479          $lines = array();
 480          $pkey = array();
 481          foreach($flds as $fld) {
 482              $fld = _array_change_key_case($fld);
 483          
 484              $fname = false;
 485              $fdefault = false;
 486              $fautoinc = false;
 487              $ftype = false;
 488              $fsize = false;
 489              $fprec = false;
 490              $fprimary = false;
 491              $fnoquote = false;
 492              $fdefts = false;
 493              $fdefdate = false;
 494              $fconstraint = false;
 495              $fnotnull = false;
 496              $funsigned = false;
 497              
 498              //-----------------
 499              // Parse attributes
 500              foreach($fld as $attr => $v) {
 501                  if ($attr == 2 && is_numeric($v)) $attr = 'SIZE';
 502                  else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v);
 503                  
 504                  switch($attr) {
 505                  case '0':
 506                  case 'NAME':     $fname = $v; break;
 507                  case '1':
 508                  case 'TYPE':     $ty = $v; $ftype = $this->ActualType(strtoupper($v)); break;
 509                  
 510                  case 'SIZE':     
 511                                  $dotat = strpos($v,'.'); if ($dotat === false) $dotat = strpos($v,',');
 512                                  if ($dotat === false) $fsize = $v;
 513                                  else {
 514                                      $fsize = substr($v,0,$dotat);
 515                                      $fprec = substr($v,$dotat+1);
 516                                  }
 517                                  break;
 518                  case 'UNSIGNED': $funsigned = true; break;
 519                  case 'AUTOINCREMENT':
 520                  case 'AUTO':    $fautoinc = true; $fnotnull = true; break;
 521                  case 'KEY':
 522                  case 'PRIMARY':    $fprimary = $v; $fnotnull = true; break;
 523                  case 'DEF':
 524                  case 'DEFAULT': $fdefault = $v; break;
 525                  case 'NOTNULL': $fnotnull = $v; break;
 526                  case 'NOQUOTE': $fnoquote = $v; break;
 527                  case 'DEFDATE': $fdefdate = $v; break;
 528                  case 'DEFTIMESTAMP': $fdefts = $v; break;
 529                  case 'CONSTRAINT': $fconstraint = $v; break;
 530                  } //switch
 531              } // foreach $fld
 532              
 533              //--------------------
 534              // VALIDATE FIELD INFO
 535              if (!strlen($fname)) {
 536                  if ($this->debug) ADOConnection::outp("Undefined NAME");
 537                  return false;
 538              }
 539              
 540              $fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname));
 541              $fname = $this->NameQuote($fname);
 542              
 543              if (!strlen($ftype)) {
 544                  if ($this->debug) ADOConnection::outp("Undefined TYPE for field '$fname'");
 545                  return false;
 546              } else {
 547                  $ftype = strtoupper($ftype);
 548              }
 549              
 550              $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec);
 551              
 552              if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls
 553              
 554              if ($fprimary) $pkey[] = $fname;
 555              
 556              // some databases do not allow blobs to have defaults
 557              if ($ty == 'X') $fdefault = false;
 558              
 559              //--------------------
 560              // CONSTRUCT FIELD SQL
 561              if ($fdefts) {
 562                  if (substr($this->connection->databaseType,0,5) == 'mysql') {
 563                      $ftype = 'TIMESTAMP';
 564                  } else {
 565                      $fdefault = $this->connection->sysTimeStamp;
 566                  }
 567              } else if ($fdefdate) {
 568                  if (substr($this->connection->databaseType,0,5) == 'mysql') {
 569                      $ftype = 'TIMESTAMP';
 570                  } else {
 571                      $fdefault = $this->connection->sysDate;
 572                  }
 573              } else if ($fdefault !== false && !$fnoquote)
 574                  if ($ty == 'C' or $ty == 'X' or 
 575                      ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault)))
 576                      if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') 
 577                          $fdefault = trim($fdefault);
 578                      else if (strtolower($fdefault) != 'null')
 579                          $fdefault = $this->connection->qstr($fdefault);
 580              $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
 581              
 582              if ($widespacing) $fname = str_pad($fname,24);
 583              $lines[$fid] = $fname.' '.$ftype.$suffix;
 584              
 585              if ($fautoinc) $this->autoIncrement = true;
 586          } // foreach $flds
 587          
 588          return array($lines,$pkey);
 589      }
 590      /*
 591           GENERATE THE SIZE PART OF THE DATATYPE
 592              $ftype is the actual type
 593              $ty is the type defined originally in the DDL
 594      */
 595  	function _GetSize($ftype, $ty, $fsize, $fprec)
 596      {
 597          if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) {
 598              $ftype .= "(".$fsize;
 599              if (strlen($fprec)) $ftype .= ",".$fprec;
 600              $ftype .= ')';
 601          }
 602          return $ftype;
 603      }
 604      
 605      
 606      // return string must begin with space
 607  	function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
 608      {    
 609          $suffix = '';
 610          if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
 611          if ($fnotnull) $suffix .= ' NOT NULL';
 612          if ($fconstraint) $suffix .= ' '.$fconstraint;
 613          return $suffix;
 614      }
 615      
 616  	function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
 617      {
 618          $sql = array();
 619          
 620          if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
 621              $sql[] = sprintf ($this->dropIndex, $idxname);
 622              if ( isset($idxoptions['DROP']) )
 623                  return $sql;
 624          }
 625          
 626          if ( empty ($flds) ) {
 627              return $sql;
 628          }
 629          
 630          $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
 631      
 632          $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
 633          
 634          if ( isset($idxoptions[$this->upperName]) )
 635              $s .= $idxoptions[$this->upperName];
 636          
 637          if ( is_array($flds) )
 638              $flds = implode(', ',$flds);
 639          $s .= '(' . $flds . ')';
 640          $sql[] = $s;
 641          
 642          return $sql;
 643      }
 644      
 645  	function _DropAutoIncrement($tabname)
 646      {
 647          return false;
 648      }
 649      
 650  	function _TableSQL($tabname,$lines,$pkey,$tableoptions)
 651      {
 652          $sql = array();
 653          
 654          if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) {
 655              $sql[] = sprintf($this->dropTable,$tabname);
 656              if ($this->autoIncrement) {
 657                  $sInc = $this->_DropAutoIncrement($tabname);
 658                  if ($sInc) $sql[] = $sInc;
 659              }
 660              if ( isset ($tableoptions['DROP']) ) {
 661                  return $sql;
 662              }
 663          }
 664          $s = "CREATE TABLE $tabname (\n";
 665          $s .= implode(",\n", $lines);
 666          if (sizeof($pkey)>0) {
 667              $s .= ",\n                 PRIMARY KEY (";
 668              $s .= implode(", ",$pkey).")";
 669          }
 670          if (isset($tableoptions['CONSTRAINTS'])) 
 671              $s .= "\n".$tableoptions['CONSTRAINTS'];
 672          
 673          if (isset($tableoptions[$this->upperName.'_CONSTRAINTS'])) 
 674              $s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS'];
 675          
 676          $s .= "\n)";
 677          if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName];
 678          $sql[] = $s;
 679          
 680          return $sql;
 681      }
 682      
 683      /*
 684          GENERATE TRIGGERS IF NEEDED
 685          used when table has auto-incrementing field that is emulated using triggers
 686      */
 687  	function _Triggers($tabname,$taboptions)
 688      {
 689          return array();
 690      }
 691      
 692      /*
 693          Sanitize options, so that array elements with no keys are promoted to keys
 694      */
 695  	function _Options($opts)
 696      {
 697          if (!is_array($opts)) return array();
 698          $newopts = array();
 699          foreach($opts as $k => $v) {
 700              if (is_numeric($k)) $newopts[strtoupper($v)] = $v;
 701              else $newopts[strtoupper($k)] = $v;
 702          }
 703          return $newopts;
 704      }
 705      
 706      /*
 707      "Florian Buzin [ easywe ]" <florian.buzin#easywe.de>
 708      
 709      This function changes/adds new fields to your table. You don't
 710      have to know if the col is new or not. It will check on its own.
 711      */
 712  	function ChangeTableSQL($tablename, $flds, $tableoptions = false)
 713      {
 714      global $ADODB_FETCH_MODE;
 715      
 716          $save = $ADODB_FETCH_MODE;
 717          $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
 718          if ($this->connection->fetchMode !== false) $savem = $this->connection->SetFetchMode(false);
 719          
 720          // check table exists
 721          $save_handler = $this->connection->raiseErrorFn;
 722          $this->connection->raiseErrorFn = '';
 723          $cols = $this->MetaColumns($tablename);
 724          $this->connection->raiseErrorFn = $save_handler;
 725          
 726          if (isset($savem)) $this->connection->SetFetchMode($savem);
 727          $ADODB_FETCH_MODE = $save;
 728          
 729          if ( empty($cols)) { 
 730              return $this->CreateTableSQL($tablename, $flds, $tableoptions);
 731          }
 732          
 733          if (is_array($flds)) {
 734          // Cycle through the update fields, comparing
 735          // existing fields to fields to update.
 736          // if the Metatype and size is exactly the
 737          // same, ignore - by Mark Newham
 738              $holdflds = array();
 739              foreach($flds as $k=>$v) {
 740                  if ( isset($cols[$k]) && is_object($cols[$k]) ) {
 741                      // If already not allowing nulls, then don't change
 742                      $obj = $cols[$k];
 743                      if (isset($obj->not_null) && $obj->not_null)
 744                          $v = str_replace('NOT NULL','',$v);
 745  
 746                      $c = $cols[$k];
 747                      $ml = $c->max_length;
 748                      $mt = $this->MetaType($c->type,$ml);
 749                      if ($ml == -1) $ml = '';
 750                      if ($mt == 'X') $ml = $v['SIZE'];
 751                      if (($mt != $v['TYPE']) ||  $ml != $v['SIZE']) {
 752                          $holdflds[$k] = $v;
 753                      }
 754                  } else {
 755                      $holdflds[$k] = $v;
 756                  }        
 757              }
 758              $flds = $holdflds;
 759          }
 760      
 761  
 762          // already exists, alter table instead
 763          list($lines,$pkey) = $this->_GenFields($flds);
 764          $alter = 'ALTER TABLE ' . $this->TableName($tablename);
 765          $sql = array();
 766  
 767          foreach ( $lines as $id => $v ) {
 768              if ( isset($cols[$id]) && is_object($cols[$id]) ) {
 769              
 770                  $flds = Lens_ParseArgs($v,',');
 771                  
 772                  //  We are trying to change the size of the field, if not allowed, simply ignore the request.
 773                  if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) continue;     
 774               
 775                  $sql[] = $alter . $this->alterCol . ' ' . $v;
 776              } else {
 777                  $sql[] = $alter . $this->addCol . ' ' . $v;
 778              }
 779          }
 780          
 781          return $sql;
 782      }
 783  } // class
 784  ?>

title

Description

title

Description

title

Description

title

title

Body