Update to last ADOdb version
authorsoranzo <soranzo>
Mon, 16 Apr 2007 17:20:22 +0000 (17:20 +0000)
committersoranzo <soranzo>
Mon, 16 Apr 2007 17:20:22 +0000 (17:20 +0000)
libraries/adodb/adodb-datadict.inc.php

index edfa5a65c8f203848e5ea0237455a1c408783435..c31edd82237ada2f960b169822df3ef2f0d9a912 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.93 10 Oct 2006  (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
   the BSD license will take precedence.
@@ -277,7 +277,7 @@ class ADODB_DataDict {
                return $rez;
        }
        
-       /*
+       /**
                Returns the actual type given a character code.
                
                C:  varchar
@@ -344,11 +344,19 @@ class ADODB_DataDict {
        {
                $tabname = $this->TableName ($tabname);
                $sql = array();
-               list($lines,$pkey) = $this->_GenFields($flds);
+               list($lines,$pkey,$idxs) = $this->_GenFields($flds);
+               // genfields can return FALSE at times
+               if ($lines  == null) $lines = array();
                $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
                foreach($lines as $v) {
                        $sql[] = $alter . $v;
                }
+               if (is_array($idxs)) {
+                       foreach($idxs as $idx => $idxdef) {
+                               $sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
+                               $sql = array_merge($sql, $sql_idxs);
+                       }
+               }
                return $sql;
        }
        
@@ -367,11 +375,20 @@ class ADODB_DataDict {
        {
                $tabname = $this->TableName ($tabname);
                $sql = array();
-               list($lines,$pkey) = $this->_GenFields($flds);
+               list($lines,$pkey,$idxs) = $this->_GenFields($flds);
+               // genfields can return FALSE at times
+               if ($lines == null) $lines = array();
                $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
                foreach($lines as $v) {
                        $sql[] = $alter . $v;
                }
+               if (is_array($idxs)) {
+                       foreach($idxs as $idx => $idxdef) {
+                               $sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
+                               $sql = array_merge($sql, $sql_idxs);
+                       }
+
+               }
                return $sql;
        }
        
@@ -389,7 +406,9 @@ class ADODB_DataDict {
        {
                $tabname = $this->TableName ($tabname);
                if ($flds) {
-                       list($lines,$pkey) = $this->_GenFields($flds);
+                       list($lines,$pkey,$idxs) = $this->_GenFields($flds);
+                       // genfields can return FALSE at times
+                       if ($lines == null) $lines = array();
                        list(,$first) = each($lines);
                        list(,$column_def) = split("[\t ]+",$first,2);
                }
@@ -429,22 +448,36 @@ class ADODB_DataDict {
                return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname)));
        }       
        
-       /*
+       /**
         Generate the SQL to create table. Returns an array of sql strings.
        */
-       function CreateTableSQL($tabname, $flds, $tableoptions=false)
+       function CreateTableSQL($tabname, $flds, $tableoptions=array())
        {
-               if (!$tableoptions) $tableoptions = array();
-               
-               list($lines,$pkey) = $this->_GenFields($flds, true);
+               list($lines,$pkey,$idxs) = $this->_GenFields($flds, true);
+               // genfields can return FALSE at times
+               if ($lines == null) $lines = array();
                
                $taboptions = $this->_Options($tableoptions);
                $tabname = $this->TableName ($tabname);
                $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
                
+               // ggiunta - 2006/10/12 - KLUDGE:
+        // if we are on autoincrement, and table options includes REPLACE, the
+        // autoincrement sequence has already been dropped on table creation sql, so
+        // we avoid passing REPLACE to trigger creation code. This prevents
+        // creating sql that double-drops the sequence
+        if ($this->autoIncrement && isset($taboptions['REPLACE']))
+               unset($taboptions['REPLACE']);
                $tsql = $this->_Triggers($tabname,$taboptions);
                foreach($tsql as $s) $sql[] = $s;
                
+               if (is_array($idxs)) {
+                       foreach($idxs as $idx => $idxdef) {
+                               $sql_idxs = $this->CreateIndexSql($idx, $tabname,  $idxdef['cols'], $idxdef['opts']);
+                               $sql = array_merge($sql, $sql_idxs);
+                       }
+               }
+
                return $sql;
        }
        
@@ -460,6 +493,9 @@ class ADODB_DataDict {
                                $f1 = array();
                                foreach($f0 as $token) {
                                        switch (strtoupper($token)) {
+                                       case 'INDEX':
+                                               $f1['INDEX'] = '';
+                                               // fall through intentionally
                                        case 'CONSTRAINT':
                                        case 'DEFAULT': 
                                                $hasparam = $token;
@@ -471,6 +507,20 @@ class ADODB_DataDict {
                                                break;
                                        }
                                }
+                               // 'index' token without a name means single column index: name it after column
+                               if (array_key_exists('INDEX', $f1) && $f1['INDEX'] == '') {
+                                       $f1['INDEX'] = isset($f0['NAME']) ? $f0['NAME'] : $f0[0];
+                                       // check if column name used to create an index name was quoted
+                                       if (($f1['INDEX'][0] == '"' || $f1['INDEX'][0] == "'" || $f1['INDEX'][0] == "`") &&
+                                               ($f1['INDEX'][0] == substr($f1['INDEX'], -1))) {
+                                               $f1['INDEX'] = $f1['INDEX'][0].'idx_'.substr($f1['INDEX'], 1, -1).$f1['INDEX'][0];
+                                       }
+                                       else
+                                               $f1['INDEX'] = 'idx_'.$f1['INDEX'];
+                               }
+                               // reset it, so we don't get next field 1st token as INDEX...
+                               $hasparam = false;
+
                                $flds[] = $f1;
                                
                        }
@@ -478,9 +528,10 @@ class ADODB_DataDict {
                $this->autoIncrement = false;
                $lines = array();
                $pkey = array();
+               $idxs = array();
                foreach($flds as $fld) {
                        $fld = _array_change_key_case($fld);
-               
+                       
                        $fname = false;
                        $fdefault = false;
                        $fautoinc = false;
@@ -494,6 +545,8 @@ class ADODB_DataDict {
                        $fconstraint = false;
                        $fnotnull = false;
                        $funsigned = false;
+                       $findex = '';
+                       $funiqueindex = false;
                        
                        //-----------------
                        // Parse attributes
@@ -519,7 +572,8 @@ class ADODB_DataDict {
                                case 'AUTOINCREMENT':
                                case 'AUTO':    $fautoinc = true; $fnotnull = true; break;
                                case 'KEY':
-                               case 'PRIMARY': $fprimary = $v; $fnotnull = true; break;
+                // a primary key col can be non unique in itself (if key spans many cols...)
+                               case 'PRIMARY': $fprimary = $v; $fnotnull = true; /*$funiqueindex = true;*/ break;
                                case 'DEF':
                                case 'DEFAULT': $fdefault = $v; break;
                                case 'NOTNULL': $fnotnull = $v; break;
@@ -527,6 +581,9 @@ class ADODB_DataDict {
                                case 'DEFDATE': $fdefdate = $v; break;
                                case 'DEFTIMESTAMP': $fdefts = $v; break;
                                case 'CONSTRAINT': $fconstraint = $v; break;
+                               // let INDEX keyword create a 'very standard' index on column
+                               case 'INDEX': $findex = $v; break;
+                               case 'UNIQUE': $funiqueindex = true; break;
                                } //switch
                        } // foreach $fld
                        
@@ -556,6 +613,27 @@ class ADODB_DataDict {
                        // some databases do not allow blobs to have defaults
                        if ($ty == 'X') $fdefault = false;
                        
+                       // build list of indexes
+                       if ($findex != '') {
+                               if (array_key_exists($findex, $idxs)) {
+                                       $idxs[$findex]['cols'][] = ($fname);
+                                       if (in_array('UNIQUE', $idxs[$findex]['opts']) != $funiqueindex) {
+                                               if ($this->debug) ADOConnection::outp("Index $findex defined once UNIQUE and once not");
+                                       }
+                                       if ($funiqueindex && !in_array('UNIQUE', $idxs[$findex]['opts']))
+                                               $idxs[$findex]['opts'][] = 'UNIQUE';
+                               }
+                               else
+                               {
+                                       $idxs[$findex] = array();
+                                       $idxs[$findex]['cols'] = array($fname);
+                                       if ($funiqueindex)
+                                               $idxs[$findex]['opts'] = array('UNIQUE');
+                                       else
+                                               $idxs[$findex]['opts'] = array();
+                               }
+                       }
+
                        //--------------------
                        // CONSTRUCT FIELD SQL
                        if ($fdefts) {
@@ -570,24 +648,47 @@ class ADODB_DataDict {
                                } else {
                                        $fdefault = $this->connection->sysDate;
                                }
-                       } else if ($fdefault !== false && !$fnoquote)
+                       } else if ($fdefault !== false && !$fnoquote) {
                                if ($ty == 'C' or $ty == 'X' or 
-                                       ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault)))
+                                       ( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) {
+
+                                       if (($ty == 'D' || $ty == 'T') && strtolower($fdefault) != 'null') {
+                                               // convert default date into database-aware code
+                                               if ($ty == 'T')
+                                               {
+                                                       $fdefault = $this->connection->DBTimeStamp($fdefault);
+                                               }
+                                               else
+                                               {
+                                                       $fdefault = $this->connection->DBDate($fdefault);
+                                               }
+                                       }
+                                       else
                                        if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ') 
                                                $fdefault = trim($fdefault);
                                        else if (strtolower($fdefault) != 'null')
                                                $fdefault = $this->connection->qstr($fdefault);
+                               }
+                       }
                        $suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
                        
+                       // add index creation
                        if ($widespacing) $fname = str_pad($fname,24);
+                       
+                        // check for field names appearing twice
+            if (array_key_exists($fid, $lines)) {
+                ADOConnection::outp("Field '$fname' defined twice");
+            }
+                       
                        $lines[$fid] = $fname.' '.$ftype.$suffix;
                        
                        if ($fautoinc) $this->autoIncrement = true;
                } // foreach $flds
                
-               return array($lines,$pkey);
+               return array($lines,$pkey,$idxs);
        }
-       /*
+
+       /**
                 GENERATE THE SIZE PART OF THE DATATYPE
                        $ftype is the actual type
                        $ty is the type defined originally in the DDL
@@ -680,7 +781,7 @@ class ADODB_DataDict {
                return $sql;
        }
        
-       /*
+       /**
                GENERATE TRIGGERS IF NEEDED
                used when table has auto-incrementing field that is emulated using triggers
        */
@@ -689,7 +790,7 @@ class ADODB_DataDict {
                return array();
        }
        
-       /*
+       /**
                Sanitize options, so that array elements with no keys are promoted to keys
        */
        function _Options($opts)
@@ -703,7 +804,7 @@ class ADODB_DataDict {
                return $newopts;
        }
        
-       /*
+       /**
        "Florian Buzin [ easywe ]" <florian.buzin#easywe.de>
        
        This function changes/adds new fields to your table. You don't
@@ -760,7 +861,9 @@ class ADODB_DataDict {
        
 
                // already exists, alter table instead
-               list($lines,$pkey) = $this->_GenFields($flds);
+               list($lines,$pkey,$idxs) = $this->_GenFields($flds);
+               // genfields can return FALSE at times
+               if ($lines == null) $lines = array();
                $alter = 'ALTER TABLE ' . $this->TableName($tablename);
                $sql = array();
 
@@ -770,8 +873,10 @@ class ADODB_DataDict {
                                $flds = Lens_ParseArgs($v,',');
                                
                                //  We are trying to change the size of the field, if not allowed, simply ignore the request.
-                               if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) continue;         
-                       
+                               if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)) {
+                                       echo "<h3>$this->alterCol cannot be changed to $flds currently</h3>";
+                                       continue;        
+                               }
                                $sql[] = $alter . $this->alterCol . ' ' . $v;
                        } else {
                                $sql[] = $alter . $this->addCol . ' ' . $v;