[ Index ]
 

Code source de CMS made simple 1.0.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/adodb_lite/ -> adodb-datadict.inc.php (source)

   1  <?php
   2  
   3  /**
   4    V4.65 22 July 2005  (c) 2000-2005 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      Modified 3 October, 2005 for use with ADOdb Lite by Mark Dickenson
  16  */
  17  
  18  /*
  19      Test script for parser
  20  */
  21  
  22  // security - hide paths
  23  if (!defined('ADODB_DIR')) die();
  24  
  25  if (!function_exists('ctype_alnum')) {
  26  	function ctype_alnum($text) {
  27          return preg_match('/^[a-z0-9]*$/i', $text);
  28      }
  29  }
  30  
  31  function _array_change_key_case($an_array)
  32  {
  33      if (is_array($an_array)) {
  34          $new_array = array();
  35          foreach($an_array as $key=>$value)
  36              $new_array[strtoupper($key)] = $value;
  37  
  38             return $new_array;
  39     }
  40  
  41      return $an_array;
  42  }
  43  
  44  /**
  45      Parse arguments, treat "text" (text) and 'text' as quotation marks.
  46      To escape, use "" or '' or ))
  47      
  48      Will read in "abc def" sans quotes, as: abc def
  49      Same with 'abc def'.
  50      However if `abc def`, then will read in as `abc def`
  51      
  52      @param endstmtchar    Character that indicates end of statement
  53      @param tokenchars     Include the following characters in tokens apart from A-Z and 0-9 
  54      @returns 2 dimensional array containing parsed tokens.
  55  */
  56  function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
  57  {
  58      $pos = 0;
  59      $intoken = false;
  60      $stmtno = 0;
  61      $endquote = false;
  62      $tokens = array();
  63      $tokens[$stmtno] = array();
  64      $max = strlen($args);
  65      $quoted = false;
  66  
  67      while ($pos < $max) {
  68          $ch = substr($args,$pos,1);
  69          switch($ch) {
  70          case ' ':
  71          case "\t":
  72          case "\n":
  73          case "\r":
  74              if (!$quoted) {
  75                  if ($intoken) {
  76                      $intoken = false;
  77                      $tokens[$stmtno][] = implode('',$tokarr);
  78                  }
  79                  break;
  80              }
  81              $tokarr[] = $ch;
  82              break;
  83          case '`':
  84              if ($intoken) $tokarr[] = $ch;
  85          case '(':
  86          case ')':    
  87          case '"':
  88          case "'":
  89              if ($intoken) {
  90                  if (empty($endquote)) {
  91                      $tokens[$stmtno][] = implode('',$tokarr);
  92                      if ($ch == '(') $endquote = ')';
  93                      else $endquote = $ch;
  94                      $quoted = true;
  95                      $intoken = true;
  96                      $tokarr = array();
  97                  } else if ($endquote == $ch) {
  98                      $ch2 = substr($args,$pos+1,1);
  99                      if ($ch2 == $endquote) {
 100                          $pos += 1;
 101                          $tokarr[] = $ch2;
 102                      } else {
 103                          $quoted = false;
 104                          $intoken = false;
 105                          $tokens[$stmtno][] = implode('',$tokarr);
 106                          $endquote = '';
 107                      }
 108                  } else
 109                      $tokarr[] = $ch;
 110              }else {
 111                  if ($ch == '(') $endquote = ')';
 112                  else $endquote = $ch;
 113                  $quoted = true;
 114                  $intoken = true;
 115                  $tokarr = array();
 116                  if ($ch == '`') $tokarr[] = '`';
 117              }
 118              break;
 119          default:
 120              if (!$intoken) {
 121                  if ($ch == $endstmtchar) {
 122                      $stmtno += 1;
 123                      $tokens[$stmtno] = array();
 124                      break;
 125                  }
 126                  $intoken = true;
 127                  $quoted = false;
 128                  $endquote = false;
 129                  $tokarr = array();
 130              }
 131              if ($quoted) $tokarr[] = $ch;
 132              else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch;
 133              else {
 134                  if ($ch == $endstmtchar) {            
 135                      $tokens[$stmtno][] = implode('',$tokarr);
 136                      $stmtno += 1;
 137                      $tokens[$stmtno] = array();
 138                      $intoken = false;
 139                      $tokarr = array();
 140                      break;
 141                  }
 142                  $tokens[$stmtno][] = implode('',$tokarr);
 143                  $tokens[$stmtno][] = $ch;
 144                  $intoken = false;
 145              }
 146          }
 147          $pos += 1;
 148      }
 149      if ($intoken) $tokens[$stmtno][] = implode('',$tokarr);
 150  
 151      return $tokens;
 152  }
 153  
 154  
 155  class ADODB_DataDict {
 156      var $connection;
 157      var $debug = false;
 158      var $dropTable = 'DROP TABLE %s';
 159      var $renameTable = 'RENAME TABLE %s TO %s'; 
 160      var $dropIndex = 'DROP INDEX %s';
 161      var $addCol = ' ADD';
 162      var $alterCol = ' ALTER COLUMN';
 163      var $dropCol = ' DROP COLUMN';
 164      var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s';    // table, old-column, new-column, column-definitions (not used by default)
 165      var $nameRegex = '\w';
 166      var $nameRegexBrackets = 'a-zA-Z0-9_\(\)';
 167      var $schema = false;
 168      var $serverInfo = array();
 169      var $autoIncrement = false;
 170      var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql
 171      var $blobSize = 100;     /// any varchar/char field this size or greater is treated as a blob
 172                              /// in other words, we use a text area for editting.
 173      var $metaTablesSQL;
 174      var $metaColumnsSQL;
 175      var $debug_echo = true;
 176      var $fetchMode;
 177      var $raiseErrorFn;
 178  
 179  	function SetFetchMode($mode)
 180      {
 181          GLOBAL $ADODB_FETCH_MODE;
 182          $old = $ADODB_FETCH_MODE;
 183          $ADODB_FETCH_MODE = $mode;
 184          return $old;
 185      }
 186  
 187  	function outp($text)
 188      {
 189          $this->debug_output = "<br>\n(" . $this->dbtype . "): ".htmlspecialchars($text)."<br>\n";
 190          if($this->debug_echo)
 191              echo $this->debug_output;
 192      }
 193  
 194  	function GetCommentSQL($table,$col)
 195      {
 196          return false;
 197      }
 198  
 199  	function SetCommentSQL($table,$col,$cmt)
 200      {
 201          return false;
 202      }
 203  
 204      /**
 205       * @param ttype can either be 'VIEW' or 'TABLE' or false. 
 206       *         If false, both views and tables are returned.
 207       *        "VIEW" returns only views
 208       *        "TABLE" returns only tables
 209       * @param showSchema returns the schema/user with the table name, eg. USER.TABLE
 210       * @param mask  is the input mask - only supported by oci8 and postgresql
 211       *
 212       * @return  array of tables for current database.
 213       */ 
 214  
 215  	function MetaTables()
 216      {
 217          global $ADODB_FETCH_MODE;
 218  
 219          $false = false;
 220          if ($mask) {
 221              return $false;
 222          }
 223          if ($this->metaTablesSQL) {
 224              $save = $ADODB_FETCH_MODE; 
 225              $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
 226  
 227              if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
 228  
 229              $rs = $this->Execute($this->metaTablesSQL);
 230              if (isset($savem)) $this->SetFetchMode($savem);
 231              $ADODB_FETCH_MODE = $save; 
 232  
 233              if ($rs === false) return $false;
 234              $arr =& $rs->GetArray();
 235              $arr2 = array();
 236  
 237              if ($hast = ($ttype && isset($arr[0][1]))) { 
 238                  $showt = strncmp($ttype,'T',1);
 239              }
 240  
 241              for ($i=0; $i < sizeof($arr); $i++) {
 242                  if ($hast) {
 243                      if ($showt == 0) {
 244                          if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]);
 245                      } else {
 246                          if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]);
 247                      }
 248                  } else
 249                      $arr2[] = trim($arr[$i][0]);
 250              }
 251              $rs->Close();
 252              return $arr2;
 253          }
 254          return $false;
 255      }
 256  
 257      /**
 258       * List columns in a database as an array of ADOFieldObjects. 
 259       * See top of file for definition of object.
 260       *
 261       * @param table    table name to query
 262       * @param upper    uppercase table name (required by some databases)
 263       * @schema is optional database schema to use - not supported by all databases.
 264       *
 265       * @return  array of ADOFieldObjects for current table.
 266       */
 267  
 268  	function MetaColumns($table, $upper=true, $schema=false)
 269      {
 270          global $ADODB_FETCH_MODE;
 271  
 272          $false = false;
 273  
 274          if (!empty($this->metaColumnsSQL)) {
 275              $schema = false;
 276              $this->_findschema($table,$schema);
 277  
 278              $save = $ADODB_FETCH_MODE;
 279              $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 280              if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
 281              $rs = $this->connection->Execute(sprintf($this->metaColumnsSQL,($upper)?strtoupper($table):$table));
 282              if (isset($savem)) $this->SetFetchMode($savem);
 283              $ADODB_FETCH_MODE = $save;
 284              if ($rs === false || $rs->EOF) return $false;
 285  
 286              $retarr = array();
 287              while (!$rs->EOF) { //print_r($rs->fields);
 288                  $fld = new ADOFieldObject();
 289                  $fld->name = $rs->fields[0];
 290                  $fld->type = $rs->fields[1];
 291                  if (isset($rs->fields[3]) && $rs->fields[3]) {
 292                      if ($rs->fields[3]>0) $fld->max_length = $rs->fields[3];
 293                      $fld->scale = $rs->fields[4];
 294                      if ($fld->scale>0) $fld->max_length += 1;
 295                  } else
 296                      $fld->max_length = $rs->fields[2];
 297  
 298                  if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;    
 299                  else $retarr[strtoupper($fld->name)] = $fld;
 300                  $rs->MoveNext();
 301              }
 302              $rs->Close();
 303              return $retarr;    
 304          }
 305          return $false;
 306      }
 307  
 308  	function _findschema(&$table,&$schema)
 309      {
 310          if (!$schema && ($at = strpos($table,'.')) !== false) {
 311              $schema = substr($table,0,$at);
 312              $table = substr($table,$at+1);
 313          }
 314      }
 315  
 316      /**
 317       * @returns an array with the primary key columns in it.
 318       */
 319  
 320  	function MetaPrimaryKeys($tab,$owner=false,$intkey=false)
 321      {
 322          // owner not used in base class - see oci8
 323          $p = array();
 324          $objs =& $this->MetaColumns($table);
 325          if ($objs) {
 326              foreach($objs as $v) {
 327                  if (!empty($v->primary_key))
 328                      $p[] = $v->name;
 329              }
 330          }
 331          if (sizeof($p)) return $p;
 332          if (function_exists('ADODB_VIEW_PRIMARYKEYS'))
 333              return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner);
 334          return false;
 335      }
 336  
 337      /**
 338        * List indexes on a table as an array.
 339        * @param table  table name to query
 340        * @param primary true to only show primary keys. Not actually used for most databases
 341        *
 342        * @return array of indexes on current table. Each element represents an index, and is itself an associative array.
 343        
 344           Array (
 345              [name_of_index] => Array
 346                (
 347                [unique] => true or false
 348                [columns] => Array
 349                (
 350                    [0] => firstname
 351                    [1] => lastname
 352                )
 353          )        
 354        */
 355  
 356  	function MetaIndexes($table, $primary = false, $owner = false)
 357      {
 358               $false = false;
 359              return $false;
 360      }
 361  
 362  	function MetaType($t,$len=-1,$fieldobj=false)
 363      {
 364          if (is_object($t)) {
 365              $fieldobj = $t;
 366              $t = $fieldobj->type;
 367              $len = $fieldobj->max_length;
 368          }
 369          // changed in 2.32 to hashing instead of switch stmt for speed...
 370          static $typeMap = array(
 371          'VARCHAR' => 'C',
 372          'VARCHAR2' => 'C',
 373          'CHAR' => 'C',
 374          'C' => 'C',
 375          'STRING' => 'C',
 376          'NCHAR' => 'C',
 377          'NVARCHAR' => 'C',
 378          'VARYING' => 'C',
 379          'BPCHAR' => 'C',
 380          'CHARACTER' => 'C',
 381          'INTERVAL' => 'C',  # Postgres
 382          ##
 383          'LONGCHAR' => 'X',
 384          'TEXT' => 'X',
 385          'NTEXT' => 'X',
 386          'M' => 'X',
 387          'X' => 'X',
 388          'CLOB' => 'X',
 389          'NCLOB' => 'X',
 390          'LVARCHAR' => 'X',
 391          ##
 392          'BLOB' => 'B',
 393          'IMAGE' => 'B',
 394          'BINARY' => 'B',
 395          'VARBINARY' => 'B',
 396          'LONGBINARY' => 'B',
 397          'B' => 'B',
 398          ##
 399          'YEAR' => 'D', // mysql
 400          'DATE' => 'D',
 401          'D' => 'D',
 402          ##
 403          'TIME' => 'T',
 404          'TIMESTAMP' => 'T',
 405          'DATETIME' => 'T',
 406          'TIMESTAMPTZ' => 'T',
 407          'T' => 'T',
 408          ##
 409          'BOOL' => 'L',
 410          'BOOLEAN' => 'L', 
 411          'BIT' => 'L',
 412          'L' => 'L',
 413          ##
 414          'COUNTER' => 'R',
 415          'R' => 'R',
 416          'SERIAL' => 'R', // ifx
 417          'INT IDENTITY' => 'R',
 418          ##
 419          'INT' => 'I',
 420          'INT2' => 'I',
 421          'INT4' => 'I',
 422          'INT8' => 'I',
 423          'INTEGER' => 'I',
 424          'INTEGER UNSIGNED' => 'I',
 425          'SHORT' => 'I',
 426          'TINYINT' => 'I',
 427          'SMALLINT' => 'I',
 428          'I' => 'I',
 429          ##
 430          'LONG' => 'N', // interbase is numeric, oci8 is blob
 431          'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
 432          'DECIMAL' => 'N',
 433          'DEC' => 'N',
 434          'REAL' => 'N',
 435          'DOUBLE' => 'N',
 436          'DOUBLE PRECISION' => 'N',
 437          'SMALLFLOAT' => 'N',
 438          'FLOAT' => 'N',
 439          'NUMBER' => 'N',
 440          'NUM' => 'N',
 441          'NUMERIC' => 'N',
 442          'MONEY' => 'N',
 443          
 444          ## informix 9.2
 445          'SQLINT' => 'I', 
 446          'SQLSERIAL' => 'I', 
 447          'SQLSMINT' => 'I', 
 448          'SQLSMFLOAT' => 'N', 
 449          'SQLFLOAT' => 'N', 
 450          'SQLMONEY' => 'N', 
 451          'SQLDECIMAL' => 'N', 
 452          'SQLDATE' => 'D', 
 453          'SQLVCHAR' => 'C', 
 454          'SQLCHAR' => 'C', 
 455          'SQLDTIME' => 'T', 
 456          'SQLINTERVAL' => 'N', 
 457          'SQLBYTES' => 'B', 
 458          'SQLTEXT' => 'X' 
 459          );
 460  
 461          $tmap = false;
 462          $t = strtoupper($t);
 463          $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N';
 464          switch ($tmap) {
 465          case 'C':
 466              // is the char field is too long, return as text field... 
 467              if ($this->blobSize >= 0) {
 468                  if ($len > $this->blobSize) return 'X';
 469              } else if ($len > 250) {
 470                  return 'X';
 471              }
 472              return 'C';
 473          case 'I':
 474              if (!empty($fieldobj->primary_key)) return 'R';
 475              return 'I';
 476          case false:
 477              return 'N';
 478          case 'B':
 479               if (isset($fieldobj->binary)) 
 480                   return ($fieldobj->binary) ? 'B' : 'X';
 481              return 'B';
 482          case 'D':
 483              if (!empty($this->datetime)) return 'T';
 484              return 'D';
 485          default:
 486              if ($t == 'LONG' && $this->dataProvider == 'oci8') return 'B';
 487              return $tmap;
 488          }
 489      }
 490  
 491  	function NameQuote($name = NULL,$allowBrackets=false)
 492      {
 493          if (!is_string($name)) {
 494              return FALSE;
 495          }
 496  
 497          $name = trim($name);
 498  
 499          if ( !is_object($this->connection) ) {
 500              return $name;
 501          }
 502  
 503          $quote = $this->connection->nameQuote;
 504  
 505          // if name is of the form `name`, quote it
 506          if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
 507              return $quote . $matches[1] . $quote;
 508          }
 509  
 510          // if name contains special characters, quote it
 511          $regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex;
 512  
 513          if ( !preg_match('/^[' . $regex . ']+$/', $name) ) {
 514              return $quote . $name . $quote;
 515          }
 516  
 517          return $name;
 518      }
 519  
 520  	function TableName($name)
 521      {
 522          if ( $this->schema ) {
 523              return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name);
 524          }
 525          return $this->NameQuote($name);
 526      }
 527  
 528      // Executes the sql array returned by GetTableSQL and GetIndexSQL
 529  	function ExecuteSQLArray($sql, $continueOnError = true)
 530      {
 531          $rez = 2;
 532          $conn = &$this->connection;
 533          $saved = $conn->debug;
 534          foreach($sql as $line) {
 535              if ($this->debug) $conn->debug = true;
 536              $ok = $conn->Execute($line);
 537              $conn->debug = $saved;
 538              if (!$ok) {
 539                  if ($this->debug) $this->outp($conn->ErrorMsg());
 540                  if (!$continueOnError) return 0;
 541                  $rez = 1;
 542              }
 543          }
 544          return $rez;
 545      }
 546  
 547      /*
 548           Returns the actual type given a character code.
 549          
 550          C:  varchar
 551          X:  CLOB (character large object) or largest varchar size if CLOB is not supported
 552          C2: Multibyte varchar
 553          X2: Multibyte CLOB
 554          
 555          B:  BLOB (binary large object)
 556          
 557          D:  Date
 558          T:  Date-time 
 559          L:  Integer field suitable for storing booleans (0 or 1)
 560          I:  Integer
 561          F:  Floating point number
 562          N:  Numeric or decimal number
 563      */
 564  
 565  	function ActualType($meta)
 566      {
 567          return $meta;
 568      }
 569  
 570  	function CreateDatabase($dbname,$options=false)
 571      {
 572          $options = $this->_Options($options);
 573          $sql = array();
 574  
 575          $s = 'CREATE DATABASE ' . $this->NameQuote($dbname);
 576          if (isset($options[$this->upperName]))
 577              $s .= ' '.$options[$this->upperName];
 578  
 579          $sql[] = $s;
 580          return $sql;
 581      }
 582  
 583      /*
 584       Generates the SQL to create index. Returns an array of sql strings.
 585      */
 586  
 587  	function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false)
 588      {
 589          if (!is_array($flds)) {
 590              $flds = explode(',',$flds);
 591          }
 592          foreach($flds as $key => $fld) {
 593              # some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32)
 594              $flds[$key] = $this->NameQuote($fld,$allowBrackets=true);
 595          }
 596          return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions));
 597      }
 598  
 599  	function DropIndexSQL ($idxname, $tabname = NULL)
 600      {
 601          return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname)));
 602      }
 603  
 604  	function SetSchema($schema)
 605      {
 606          $this->schema = $schema;
 607      }
 608  
 609  	function AddColumnSQL($tabname, $flds)
 610      {
 611          $tabname = $this->TableName ($tabname);
 612          $sql = array();
 613          list($lines,$pkey) = $this->_GenFields($flds);
 614          $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
 615          foreach($lines as $v) {
 616              $sql[] = $alter . $v;
 617          }
 618          return $sql;
 619      }
 620  
 621      /**
 622       * Change the definition of one column
 623       *
 624       * As some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
 625       * to allow, recreating the table and copying the content over to the new table
 626       * @param string $tabname table-name
 627       * @param string $flds column-name and type for the changed column
 628       * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
 629       * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
 630       * @return array with SQL strings
 631       */
 632  
 633  	function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
 634      {
 635          $tabname = $this->TableName ($tabname);
 636          $sql = array();
 637          list($lines,$pkey) = $this->_GenFields($flds);
 638          $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
 639          foreach($lines as $v) {
 640              $sql[] = $alter . $v;
 641          }
 642          return $sql;
 643      }
 644  
 645      /**
 646       * Rename one column
 647       *
 648       * Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql)
 649       * @param string $tabname table-name
 650       * @param string $oldcolumn column-name to be renamed
 651       * @param string $newcolumn new column-name
 652       * @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default=''
 653       * @return array with SQL strings
 654       */
 655  
 656  	function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')
 657      {
 658          $tabname = $this->TableName ($tabname);
 659          if ($flds) {
 660              list($lines,$pkey) = $this->_GenFields($flds);
 661              list(,$first) = each($lines);
 662              list(,$column_def) = split("[\t ]+",$first,2);
 663          }
 664          return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def));
 665      }
 666  
 667      /**
 668       * Drop one column
 669       *
 670       * Some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
 671       * to allow, recreating the table and copying the content over to the new table
 672       * @param string $tabname table-name
 673       * @param string $flds column-name and type for the changed column
 674       * @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
 675       * @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
 676       * @return array with SQL strings
 677       */
 678  
 679  	function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
 680      {
 681          $tabname = $this->TableName ($tabname);
 682          if (!is_array($flds)) $flds = explode(',',$flds);
 683          $sql = array();
 684          $alter = 'ALTER TABLE ' . $tabname . $this->dropCol . ' ';
 685          foreach($flds as $v) {
 686              $sql[] = $alter . $this->NameQuote($v);
 687          }
 688          return $sql;
 689      }
 690  
 691  	function DropTableSQL($tabname)
 692      {
 693          return array (sprintf($this->dropTable, $this->TableName($tabname)));
 694      }
 695  
 696  	function RenameTableSQL($tabname,$newname)
 697      {
 698          return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname)));
 699      }
 700  
 701      /*
 702       Generate the SQL to create table. Returns an array of sql strings.
 703      */
 704  
 705  	function CreateTableSQL($tabname, $flds, $tableoptions=false)
 706      {
 707          if (!$tableoptions) $tableoptions = array();
 708  
 709          list($lines,$pkey) = $this->_GenFields($flds, true);
 710  
 711          $taboptions = $this->_Options($tableoptions);
 712          $tabname = $this->TableName ($tabname);
 713          $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
 714          $tsql = $this->_Triggers($tabname,$taboptions);
 715          foreach($tsql as $s) $sql[] = $s;
 716  
 717          return $sql;
 718      }
 719  
 720  	function _GenFields($flds,$widespacing=false)
 721      {
 722          if (is_string($flds)) {
 723              $padding = '     ';
 724              $txt = $flds.$padding;
 725              $flds = array();
 726              $flds0 = Lens_ParseArgs($txt,',');
 727              $hasparam = false;
 728              foreach($flds0 as $f0) {
 729                  $f1 = array();
 730                  foreach($f0 as $token) {
 731                      switch (strtoupper($token)) {
 732                      case 'CONSTRAINT':
 733                      case 'DEFAULT': 
 734                          $hasparam = $token;
 735                          break;
 736                      default:
 737                          if ($hasparam) $f1[$hasparam] = $token;
 738                          else $f1[] = $token;
 739                          $hasparam = false;
 740                          break;
 741                      }
 742                  }
 743                  $flds[] = $f1;
 744                  
 745              }
 746          }
 747          $this->autoIncrement = false;
 748          $lines = array();
 749          $pkey = array();
 750          foreach($flds as $fld) {
 751              $fld = _array_change_key_case($fld);
 752              $fname = false;
 753              $fdefault = false;
 754              $fautoinc = false;
 755              $ftype = false;
 756              $fsize = false;
 757              $fprec = false;
 758              $fprimary = false;
 759              $fnoquote = false;
 760              $fdefts = false;
 761              $fdefdate = false;
 762              $fconstraint = false;
 763              $fnotnull = false;
 764              $funsigned = false;
 765  
 766              //-----------------
 767              // Parse attributes
 768              foreach($fld as $attr => $v) {
 769                  if ($attr == 2 && is_numeric($v)) $attr = 'SIZE';
 770                  else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v);
 771                  switch($attr) {
 772                      case '0':
 773                      case 'NAME':
 774                          $fname = $v;
 775                          break;
 776                      case '1':
 777                      case 'TYPE':
 778                          $ty = $v; $ftype = $this->ActualType(strtoupper($v));
 779                          break;
 780                      case 'SIZE':
 781                          $dotat = strpos($v,'.');
 782                          if ($dotat === false) $dotat = strpos($v,',');
 783                          if ($dotat === false) $fsize = $v;
 784                          else {
 785                                  $fsize = substr($v,0,$dotat);
 786                                  $fprec = substr($v,$dotat+1);
 787                              }
 788                          break;
 789                      case 'UNSIGNED':
 790                          $funsigned = true;
 791                          break;
 792                      case 'AUTOINCREMENT':
 793                      case 'AUTO':
 794                          $fautoinc = true;
 795                          $fnotnull = true;
 796                          break;
 797                      case 'KEY':
 798                      case 'PRIMARY':
 799                          $fprimary = $v;
 800                          $fnotnull = true;
 801                          break;
 802                      case 'DEF':
 803                      case 'DEFAULT':
 804                          $fdefault = $v;
 805                          break;
 806                      case 'NOTNULL':
 807                          $fnotnull = $v;
 808                          break;
 809                      case 'NOQUOTE':
 810                          $fnoquote = $v;
 811                          break;
 812                      case 'DEFDATE':
 813                          $fdefdate = $v;
 814                          break;
 815                      case 'DEFTIMESTAMP':
 816                          $fdefts = $v;
 817                          break;
 818                      case 'CONSTRAINT':
 819                          $fconstraint = $v;
 820                          break;
 821                  }
 822              }
 823  
 824              //--------------------
 825              // VALIDATE FIELD INFO
 826              if (!strlen($fname)) {
 827                  if ($this->debug) $this->outp("Undefined NAME");
 828                  return false;
 829              }
 830  
 831              $fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname));
 832              $fname = $this->NameQuote($fname);
 833  
 834              if (!strlen($ftype)) {
 835                  if ($this->debug) $this->outp("Undefined TYPE for field '$fname'");
 836                  return false;
 837              } else {
 838                  $ftype = strtoupper($ftype);
 839              }
 840  
 841              $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec);
 842  
 843              if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls
 844  
 845              if ($fprimary) $pkey[] = $fname;
 846  
 847              // some databases do not allow blobs to have defaults
 848              if ($ty == 'X') $fdefault = false;
 849  
 850              //--------------------
 851              // CONSTRUCT FIELD SQL
 852              if ($fdefts) {
 853                  if (substr($this->dbtype,0,5) == 'mysql') {
 854                      $ftype = 'TIMESTAMP';
 855                  } else {
 856                      $fdefault = $this->connection->sysTimeStamp;
 857                  }
 858              } else if ($fdefdate) {
 859                  if (substr($this->dbtype,0,5) == 'mysql') {
 860                      $ftype = 'TIMESTAMP';
 861                  } else {
 862                      $fdefault = $this->connection->sysDate;
 863                  }
 864              } else if ($fdefault !== false && !$fnoquote)
 865                  if ($ty == 'C' or $ty == 'X' or 
 866                      ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault)))
 867                      if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') 
 868                          $fdefault = trim($fdefault);
 869                      else if (strtolower($fdefault) != 'null')
 870                          $fdefault = $this->connection->qstr($fdefault);
 871              $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
 872  
 873              if ($widespacing) $fname = str_pad($fname,24);
 874              $lines[$fid] = $fname.' '.$ftype.$suffix;
 875  
 876              if ($fautoinc) $this->autoIncrement = true;
 877          } // foreach $flds
 878          return array($lines,$pkey);
 879      }
 880  
 881      /*
 882           GENERATE THE SIZE PART OF THE DATATYPE
 883              $ftype is the actual type
 884              $ty is the type defined originally in the DDL
 885      */
 886  
 887  	function _GetSize($ftype, $ty, $fsize, $fprec)
 888      {
 889          if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) {
 890              $ftype .= "(".$fsize;
 891              if (strlen($fprec)) $ftype .= ",".$fprec;
 892              $ftype .= ')';
 893          }
 894          return $ftype;
 895      }
 896  
 897      // return string must begin with space
 898  	function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
 899      {    
 900          $suffix = '';
 901          if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
 902          if ($fnotnull) $suffix .= ' NOT NULL';
 903          if ($fconstraint) $suffix .= ' '.$fconstraint;
 904          return $suffix;
 905      }
 906  
 907  	function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
 908      {
 909          $sql = array();
 910  
 911          if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
 912              $sql[] = sprintf ($this->dropIndex, $idxname);
 913              if ( isset($idxoptions['DROP']) )
 914                  return $sql;
 915          }
 916  
 917          if ( empty ($flds) ) {
 918              return $sql;
 919          }
 920  
 921          $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
 922  
 923          $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
 924  
 925          if ( isset($idxoptions[$this->upperName]) )
 926              $s .= $idxoptions[$this->upperName];
 927  
 928          if ( is_array($flds) )
 929              $flds = implode(', ',$flds);
 930          $s .= '(' . $flds . ')';
 931          $sql[] = $s;
 932  
 933          return $sql;
 934      }
 935  
 936  	function _DropAutoIncrement($tabname)
 937      {
 938          return false;
 939      }
 940  
 941  	function _TableSQL($tabname,$lines,$pkey,$tableoptions)
 942      {
 943          $sql = array();
 944  
 945          if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) {
 946              $sql[] = sprintf($this->dropTable,$tabname);
 947              if ($this->autoIncrement) {
 948                  $sInc = $this->_DropAutoIncrement($tabname);
 949                  if ($sInc) $sql[] = $sInc;
 950              }
 951              if ( isset ($tableoptions['DROP']) ) {
 952                  return $sql;
 953              }
 954          }
 955          $s = "CREATE TABLE $tabname (\n";
 956          $s .= implode(",\n", $lines);
 957          if (sizeof($pkey)>0) {
 958              $s .= ",\n                 PRIMARY KEY (";
 959              $s .= implode(", ",$pkey).")";
 960          }
 961          if (isset($tableoptions['CONSTRAINTS'])) 
 962              $s .= "\n".$tableoptions['CONSTRAINTS'];
 963  
 964          if (isset($tableoptions[$this->upperName.'_CONSTRAINTS'])) 
 965              $s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS'];
 966  
 967          $s .= "\n)";
 968          if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName];
 969          $sql[] = $s;
 970  
 971          return $sql;
 972      }
 973  
 974      /*
 975          GENERATE TRIGGERS IF NEEDED
 976          used when table has auto-incrementing field that is emulated using triggers
 977      */
 978  
 979  	function _Triggers($tabname,$taboptions)
 980      {
 981          return array();
 982      }
 983  
 984      /*
 985          Sanitize options, so that array elements with no keys are promoted to keys
 986      */
 987  
 988  	function _Options($opts)
 989      {
 990          if (!is_array($opts)) return array();
 991          $newopts = array();
 992          foreach($opts as $k => $v) {
 993              if (is_numeric($k)) $newopts[strtoupper($v)] = $v;
 994              else $newopts[strtoupper($k)] = $v;
 995          }
 996          return $newopts;
 997      }
 998  
 999      /*
1000      "Florian Buzin [ easywe ]" <florian.buzin#easywe.de>
1001      
1002      This function changes/adds new fields to your table. You don't
1003      have to know if the col is new or not. It will check on its own.
1004      */
1005  
1006  	function ChangeTableSQL($tablename, $flds, $tableoptions = false)
1007      {
1008          global $ADODB_FETCH_MODE;
1009          $save = $ADODB_FETCH_MODE;
1010          $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
1011          if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
1012  
1013          // check table exists
1014          $save_handler = $this->raiseErrorFn;
1015          $this->raiseErrorFn = '';
1016          $cols = $this->MetaColumns($tablename);
1017          $this->raiseErrorFn = $save_handler;
1018  
1019          if (isset($savem)) $this->SetFetchMode($savem);
1020          $ADODB_FETCH_MODE = $save;
1021  
1022          if ( empty($cols)) { 
1023              return $this->CreateTableSQL($tablename, $flds, $tableoptions);
1024          }
1025  
1026          if (is_array($flds)) {
1027              // Cycle through the update fields, comparing
1028              // existing fields to fields to update.
1029              // if the Metatype and size is exactly the
1030              // same, ignore - by Mark Newham
1031              $holdflds = array();
1032              foreach($flds as $k=>$v) {
1033                  if ( isset($cols[$k]) && is_object($cols[$k]) ) {
1034                      $c = $cols[$k];
1035                      $ml = $c->max_length;
1036                      $mt = &$this->MetaType($c->type,$ml);
1037                      if ($ml == -1) $ml = '';
1038                      if ($mt == 'X') $ml = $v['SIZE'];
1039                      if (($mt != $v['TYPE']) ||  $ml != $v['SIZE']) {
1040                          $holdflds[$k] = $v;
1041                      }
1042                  } else {
1043                      $holdflds[$k] = $v;
1044                  }        
1045              }
1046              $flds = $holdflds;
1047          }
1048  
1049          // already exists, alter table instead
1050          list($lines,$pkey) = $this->_GenFields($flds);
1051          $alter = 'ALTER TABLE ' . $this->TableName($tablename);
1052          $sql = array();
1053  
1054          foreach ( $lines as $id => $v ) {
1055              if ( isset($cols[$id]) && is_object($cols[$id]) ) {
1056                  $flds = Lens_ParseArgs($v,',');
1057                  //  We are trying to change the size of the field, if not allowed, simply ignore the request.
1058                  if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) continue;     
1059  
1060                  $sql[] = $alter . $this->alterCol . ' ' . $v;
1061              } else {
1062                  $sql[] = $alter . $this->addCol . ' ' . $v;
1063              }
1064          }
1065          return $sql;
1066      }
1067  }
1068  
1069  ?>


Généré le : Tue Apr 3 18:50:37 2007 par Balluche grâce à PHPXref 0.7