]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-14672 adodb PHP5 only version V5.04a import - yay!
authorskodak <skodak>
Fri, 2 May 2008 22:50:22 +0000 (22:50 +0000)
committerskodak <skodak>
Fri, 2 May 2008 22:50:22 +0000 (22:50 +0000)
102 files changed:
lib/adodb/adodb-active-record.inc.php
lib/adodb/adodb-csvlib.inc.php
lib/adodb/adodb-datadict.inc.php
lib/adodb/adodb-error.inc.php
lib/adodb/adodb-errorhandler.inc.php
lib/adodb/adodb-errorpear.inc.php
lib/adodb/adodb-exceptions.inc.php
lib/adodb/adodb-iterator.inc.php
lib/adodb/adodb-lib.inc.php
lib/adodb/adodb-memcache.lib.inc.php
lib/adodb/adodb-pager.inc.php
lib/adodb/adodb-pear.inc.php
lib/adodb/adodb-perf.inc.php
lib/adodb/adodb-php4.inc.php
lib/adodb/adodb-time.inc.php
lib/adodb/adodb-xmlschema.inc.php
lib/adodb/adodb-xmlschema03.inc.php
lib/adodb/adodb.inc.php
lib/adodb/datadict/datadict-access.inc.php
lib/adodb/datadict/datadict-db2.inc.php
lib/adodb/datadict/datadict-firebird.inc.php
lib/adodb/datadict/datadict-generic.inc.php
lib/adodb/datadict/datadict-ibase.inc.php
lib/adodb/datadict/datadict-informix.inc.php
lib/adodb/datadict/datadict-mssql.inc.php
lib/adodb/datadict/datadict-mysql.inc.php
lib/adodb/datadict/datadict-oci8.inc.php
lib/adodb/datadict/datadict-postgres.inc.php
lib/adodb/datadict/datadict-sybase.inc.php
lib/adodb/drivers/adodb-access.inc.php
lib/adodb/drivers/adodb-ado.inc.php
lib/adodb/drivers/adodb-ado5.inc.php
lib/adodb/drivers/adodb-ado_access.inc.php
lib/adodb/drivers/adodb-ado_mssql.inc.php
lib/adodb/drivers/adodb-borland_ibase.inc.php
lib/adodb/drivers/adodb-csv.inc.php
lib/adodb/drivers/adodb-db2.inc.php
lib/adodb/drivers/adodb-fbsql.inc.php
lib/adodb/drivers/adodb-firebird.inc.php
lib/adodb/drivers/adodb-ibase.inc.php
lib/adodb/drivers/adodb-informix.inc.php
lib/adodb/drivers/adodb-informix72.inc.php
lib/adodb/drivers/adodb-ldap.inc.php
lib/adodb/drivers/adodb-mssql.inc.php
lib/adodb/drivers/adodb-mssqlpo.inc.php
lib/adodb/drivers/adodb-mysql.inc.php
lib/adodb/drivers/adodb-mysqli.inc.php
lib/adodb/drivers/adodb-mysqlpo.inc.php [new file with mode: 0644]
lib/adodb/drivers/adodb-mysqlt.inc.php
lib/adodb/drivers/adodb-netezza.inc.php
lib/adodb/drivers/adodb-oci8.inc.php
lib/adodb/drivers/adodb-oci805.inc.php
lib/adodb/drivers/adodb-oci8po.inc.php
lib/adodb/drivers/adodb-odbc.inc.php
lib/adodb/drivers/adodb-odbc_db2.inc.php
lib/adodb/drivers/adodb-odbc_mssql.inc.php
lib/adodb/drivers/adodb-odbc_oracle.inc.php
lib/adodb/drivers/adodb-odbtp.inc.php
lib/adodb/drivers/adodb-odbtp_unicode.inc.php
lib/adodb/drivers/adodb-oracle.inc.php
lib/adodb/drivers/adodb-pdo.inc.php
lib/adodb/drivers/adodb-pdo_mssql.inc.php
lib/adodb/drivers/adodb-pdo_mysql.inc.php
lib/adodb/drivers/adodb-pdo_oci.inc.php
lib/adodb/drivers/adodb-pdo_pgsql.inc.php
lib/adodb/drivers/adodb-postgres.inc.php
lib/adodb/drivers/adodb-postgres64.inc.php
lib/adodb/drivers/adodb-postgres7.inc.php
lib/adodb/drivers/adodb-postgres8.inc.php
lib/adodb/drivers/adodb-proxy.inc.php
lib/adodb/drivers/adodb-sapdb.inc.php
lib/adodb/drivers/adodb-sqlanywhere.inc.php
lib/adodb/drivers/adodb-sqlite.inc.php
lib/adodb/drivers/adodb-sqlitepo.inc.php
lib/adodb/drivers/adodb-sybase.inc.php
lib/adodb/drivers/adodb-sybase_ase.inc.php
lib/adodb/drivers/adodb-vfp.inc.php
lib/adodb/perf/perf-db2.inc.php
lib/adodb/perf/perf-informix.inc.php
lib/adodb/perf/perf-mssql.inc.php
lib/adodb/perf/perf-mysql.inc.php
lib/adodb/perf/perf-oci8.inc.php
lib/adodb/perf/perf-postgres.inc.php
lib/adodb/readme_moodle.txt
lib/adodb/rsfilter.inc.php
lib/adodb/session/adodb-compress-bzip2.php
lib/adodb/session/adodb-compress-gzip.php
lib/adodb/session/adodb-cryptsession.php
lib/adodb/session/adodb-cryptsession2.php
lib/adodb/session/adodb-encrypt-mcrypt.php
lib/adodb/session/adodb-encrypt-md5.php
lib/adodb/session/adodb-encrypt-secret.php
lib/adodb/session/adodb-encrypt-sha1.php
lib/adodb/session/adodb-session-clob.php
lib/adodb/session/adodb-session-clob2.php
lib/adodb/session/adodb-session.php
lib/adodb/session/adodb-session2.php
lib/adodb/session/old/adodb-cryptsession.php
lib/adodb/session/old/adodb-session-clob.php
lib/adodb/session/old/adodb-session.php
lib/adodb/toexport.inc.php
lib/adodb/tohtml.inc.php

index 0654828c00d7e163c02637886149688ed85db90e..328eaa8b63322e41bcf0d1c19c327a2f361fc4d2 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-@version V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+@version V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
   Latest version is available at http://adodb.sourceforge.net
  
   Released under both BSD license and Lesser GPL library license. 
@@ -10,7 +10,7 @@
   
   Active Record implementation. Superset of Zend Framework's.
   
-  Version 0.09
+  Version 0.08
   
   See http://www-128.ibm.com/developerworks/java/library/j-cb03076/?ca=dgr-lnxw01ActiveRecord 
        for info on Ruby on Rails Active Record implementation
@@ -53,7 +53,7 @@ function ADODB_SetDatabaseAdapter(&$db)
                }
                
                $obj = new ADODB_Active_DB();
-               $obj->db =& $db;
+               $obj->db = $db;
                $obj->tables = array();
                
                $_ADODB_ACTIVE_DBS[] = $obj;
@@ -71,8 +71,7 @@ class ADODB_Active_Record {
        var $_lasterr = false; // last error message
        var $_original = false; // the original values loaded or inserted, refreshed on update
        
-       // should be static
-       function UseDefaultValues($bool=null)
+       static function UseDefaultValues($bool=null)
        {
        global $ADODB_ACTIVE_DEFVALS;
                if (isset($bool)) $ADODB_ACTIVE_DEFVALS = $bool;
@@ -80,15 +79,16 @@ class ADODB_Active_Record {
        }
 
        // should be static
-       function SetDatabaseAdapter(&$db) 
+       static function SetDatabaseAdapter(&$db) 
        {
                return ADODB_SetDatabaseAdapter($db);
        }
        
-       // php4 constructor
-       function ADODB_Active_Record($table = false, $pkeyarr=false, $db=false)
+       
+       public function __set($name, $value)
        {
-               ADODB_Active_Record::__construct($table,$pkeyarr,$db);
+               $name = str_replace(' ', '_', $name);
+               $this->$name = $value;
        }
        
        // php5 constructor
@@ -153,23 +153,24 @@ class ADODB_Active_Record {
        global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS , $ADODB_CACHE_DIR, $ADODB_ACTIVE_CACHESECS;
        global $ADODB_ACTIVE_DEFVALS;
 
-               $activedb =& $_ADODB_ACTIVE_DBS[$this->_dbat];
+               $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
 
                $table = $this->_table;
                $tables = $activedb->tables;
                $tableat = $this->_tableat;
                if (!$forceUpdate && !empty($tables[$tableat])) {
-                       $tobj =& $tables[$tableat];
+
+                       $tobj = $tables[$tableat];
                        foreach($tobj->flds as $name => $fld) {
-                               if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) 
-                                       $this->$name = $fld->default_value;
-                               else
-                                       $this->$name = null;
+                       if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value)) 
+                               $this->$name = $fld->default_value;
+                       else
+                               $this->$name = null;
                        }
                        return;
                }
                
-               $db =& $activedb->db;
+               $db = $activedb->db;
                $fname = $ADODB_CACHE_DIR . '/adodb_' . $db->databaseType . '_active_'. $table . '.cache';
                if (!$forceUpdate && $ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR && file_exists($fname)) {
                        $fp = fopen($fname,'r');
@@ -288,7 +289,7 @@ class ADODB_Active_Record {
                if ($this->_dbat < 0) $db = false;
                else {
                        $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
-                       $db =& $activedb->db;
+                       $db = $activedb->db;
                }
                
                if (function_exists('adodb_throw')) {   
@@ -322,7 +323,7 @@ class ADODB_Active_Record {
 
 
        // retrieve ADOConnection from _ADODB_Active_DBs
-       function &DB()
+       function DB()
        {
        global $_ADODB_ACTIVE_DBS;
        
@@ -332,17 +333,17 @@ class ADODB_Active_Record {
                        return $false;
                }
                $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
-               $db =& $activedb->db;
+               $db = $activedb->db;
                return $db;
        }
        
        // retrieve ADODB_Active_Table
-       function &TableInfo()
+       function TableInfo()
        {
        global $_ADODB_ACTIVE_DBS;
        
                $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
-               $table =& $activedb->tables[$this->_tableat];
+               $table = $activedb->tables[$this->_tableat];
                return $table;
        }
        
@@ -351,7 +352,7 @@ class ADODB_Active_Record {
        {
        global $ACTIVE_RECORD_SAFETY;
        
-               $db =& $this->DB();
+               $db = $this->DB();
                
                if (!$row) {
                        $this->_saved = false;          
@@ -360,8 +361,9 @@ class ADODB_Active_Record {
                
                $this->_saved = true;
                
-               $table =& $this->TableInfo();
+               $table = $this->TableInfo();
                if ($ACTIVE_RECORD_SAFETY && sizeof($table->flds) != sizeof($row)) {
+            # <AP>
             $bad_size = TRUE;
             if (sizeof($row) == 2 * sizeof($table->flds)) {
                 // Only keep string keys
@@ -370,13 +372,14 @@ class ADODB_Active_Record {
                     $bad_size = FALSE;
             }
             if ($bad_size) {
-                               $this->Error("Table structure of $this->_table has changed","Load");
-                               return false;
-                       }
+                       $this->Error("Table structure of $this->_table has changed","Load");
+                       return false;
+               }
+            # </AP>
                }
         else
-                       $keys = array_keys($row);
-      
+               $keys = array_keys($row);
+        # <AP>
         reset($keys);
         $this->_original = array();
                foreach($table->flds as $name=>$fld) {
@@ -446,7 +449,7 @@ class ADODB_Active_Record {
        
        function Load($where,$bindarr=false)
        {
-               $db =& $this->DB(); if (!$db) return false;
+               $db = $this->DB(); if (!$db) return false;
                $this->_where = $where;
                
                $save = $db->SetFetchMode(ADODB_FETCH_NUM);
@@ -468,9 +471,9 @@ class ADODB_Active_Record {
        // false on error
        function Insert()
        {
-               $db =& $this->DB(); if (!$db) return false;
+               $db = $this->DB(); if (!$db) return false;
                $cnt = 0;
-               $table =& $this->TableInfo();
+               $table = $this->TableInfo();
                
                $valarr = array();
                $names = array();
@@ -518,8 +521,8 @@ class ADODB_Active_Record {
        
        function Delete()
        {
-               $db =& $this->DB(); if (!$db) return false;
-               $table =& $this->TableInfo();
+               $db = $this->DB(); if (!$db) return false;
+               $table = $this->TableInfo();
                
                $where = $this->GenWhere($db,$table);
                $sql = 'DELETE FROM '.$this->_table.' WHERE '.$where;
@@ -529,10 +532,10 @@ class ADODB_Active_Record {
        }
        
        // returns an array of active record objects
-       function &Find($whereOrderBy,$bindarr=false,$pkeysArr=false)
+       function Find($whereOrderBy,$bindarr=false,$pkeysArr=false)
        {
-               $db =& $this->DB(); if (!$db || empty($this->_table)) return false;
-               $arr =& $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr);
+               $db = $this->DB(); if (!$db || empty($this->_table)) return false;
+               $arr = $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr);
                return $arr;
        }
        
@@ -541,8 +544,8 @@ class ADODB_Active_Record {
        {
        global $ADODB_ASSOC_CASE;
                
-               $db =& $this->DB(); if (!$db) return false;
-               $table =& $this->TableInfo();
+               $db = $this->DB(); if (!$db) return false;
+               $table = $this->TableInfo();
                
                $pkey = $table->keys;
                
@@ -593,7 +596,7 @@ class ADODB_Active_Record {
                                }
                        }
                        
-                       $this->_original =& $valarr;
+                       $this->_original = $valarr;
                } 
                return $ok;
        }
@@ -601,8 +604,8 @@ class ADODB_Active_Record {
        // returns 0 on error, 1 on update, -1 if no change in data (no update)
        function Update()
        {
-               $db =& $this->DB(); if (!$db) return false;
-               $table =& $this->TableInfo();
+               $db = $this->DB(); if (!$db) return false;
+               $table = $this->TableInfo();
                
                $where = $this->GenWhere($db, $table);
                
@@ -647,7 +650,7 @@ class ADODB_Active_Record {
                $sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where;
                $ok = $db->Execute($sql,$valarr);
                if ($ok) {
-                       $this->_original =& $neworig;
+                       $this->_original = $neworig;
                        return 1;
                }
                return 0;
@@ -655,7 +658,7 @@ class ADODB_Active_Record {
        
        function GetAttributeNames()
        {
-               $table =& $this->TableInfo();
+               $table = $this->TableInfo();
                if (!$table) return false;
                return array_keys($table->flds);
        }
index c82c965582f5f10e3b7e5eb3f4bc2e3aaa857be4..2872f2042d1155aa62a394f0a4288859290645a8 100644 (file)
@@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 1;
 
 /* 
 
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -54,7 +54,7 @@ $ADODB_INCLUDED_CSV = 1;
                $line = "====1,$tt,$sql\n";
                
                if ($rs->databaseType == 'array') {
-                       $rows =& $rs->_array;
+                       $rows = $rs->_array;
                } else {
                        $rows = array();
                        while (!$rs->EOF) {     
@@ -64,7 +64,7 @@ $ADODB_INCLUDED_CSV = 1;
                }
                
                for($i=0; $i < $max; $i++) {
-                       $o =& $rs->FetchField($i);
+                       $o = $rs->FetchField($i);
                        $flds[] = $o;
                }
        
@@ -90,7 +90,7 @@ $ADODB_INCLUDED_CSV = 1;
 *                      error occurred in sql INSERT/UPDATE/DELETE, 
 *                      empty recordset is returned
 */
-       function &csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
+       function csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
        {
                $false = false;
                $err = false;
index 86961a2bfc3472222136a3978cf7c249f5afdf44..d98d5511548fe7923616b9220bdaa89baaccc9af 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -215,7 +215,6 @@ class ADODB_DataDict {
                return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
        }
        
-
        function MetaType($t,$len=-1,$fieldobj=false)
        {               
                static $typeMap = array(
@@ -369,7 +368,7 @@ class ADODB_DataDict {
        function ExecuteSQLArray($sql, $continueOnError = true)
        {
                $rez = 2;
-               $conn = &$this->connection;
+               $conn = $this->connection;
                $saved = $conn->debug;
                foreach($sql as $line) {
                        
index f55516116b6ae33949400d9325b75373d0641a52..72779ab2cba6665f5c03fbbe4a923f3a350b545e 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008  (c) 2000-2008 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. 
index 779cf7f47330d32a80ae8cb605678664628e73fc..4b7941fd0243bfb4cb26139c05d60f6453c62a09 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 414578ac7ead56929aa3a133e69cbbab77ff3cd7..70c2f6e0beb75fb9ffd69e5b336ea6ec921170f9 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008  (c) 2000-2008 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. 
@@ -78,7 +78,7 @@ global $ADODB_Last_PEAR_Error;
 * Returns last PEAR_Error object. This error might be for an error that
 * occured several sql statements ago.
 */
-function &ADODB_PEAR_Error()
+function ADODB_PEAR_Error()
 {
 global $ADODB_Last_PEAR_Error;
 
index 1bbcea0338081f2a2cdacca172d0af21b4a21a6f..d2f589b8d07a62d065fe609f89a2b964818b2e17 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @version V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008   (c) 2000-2008 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.
index e4c6d32319a0f4719aa62d10e98d98c03139ddf2..73e89047f9880d08579933689d8611dbe4b2b2c9 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
                
                
        Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2
- */
-
- class ADODB_Iterator implements Iterator {
-
-    private $rs;
-
-    function __construct($rs) 
-       {
-        $this->rs = $rs;
-    }
-    function rewind() 
-       {
-        $this->rs->MoveFirst();
-    }
-
-       function valid() 
-       {
-        return !$this->rs->EOF;
-    }
-       
-    function key() 
-       {
-        return $this->rs->_currentRow;
-    }
        
-    function current() 
-       {
-        return $this->rs->fields;
-    }
        
-    function next() 
-       {
-        $this->rs->MoveNext();
-    }
-       
-       function __call($func, $params)
-       {
-               return call_user_func_array(array($this->rs, $func), $params);
-       }
-
-       
-       function hasMore()
-       {
-               return !$this->rs->EOF;
-       }
-
-}
+       Moved to adodb.inc.php to improve performance.
+ */
 
 
-class ADODB_BASE_RS implements IteratorAggregate {
-    function getIterator() {
-        return new ADODB_Iterator($this);
-    }
-       
-       /* this is experimental - i don't really know what to return... */
-       function __toString()
-       {
-               include_once(ADODB_DIR.'/toexport.inc.php');
-               return _adodb_export($this,',',',',false,true);
-       }
-} 
 
 
 ?>
\ No newline at end of file
index 1e1e7e3d5d25f8282edf9536d1db39bdbe634b3b..899972ea20a2fe86e51da19eb7891188f6055e20 100644 (file)
@@ -1,5 +1,8 @@
 <?php
-       
+
+
+
+
 // security - hide paths
 if (!defined('ADODB_DIR')) die();
 
@@ -7,7 +10,7 @@ global $ADODB_INCLUDED_LIB;
 $ADODB_INCLUDED_LIB = 1;
 
 /* 
- @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim\@natsoft.com.my). All rights reserved.
+ @version V5.04a 25 Mar 2008  (c) 2000-2008 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. See License.txt. 
@@ -55,7 +58,7 @@ function adodb_probetypes(&$array,&$types,$probe=8)
        
        
        for ($j=0;$j < $max; $j++) {
-               $row =& $array[$j];
+               $row = $array[$j];
                if (!$row) break;
                $i = -1;
                foreach($row as $v) {
@@ -417,9 +420,9 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
                } else if (strncmp($zthis->databaseType,'postgres',8) == 0 || strncmp($zthis->databaseType,'mysql',5) == 0)  {
                        $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
                } else {
-                       $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) ";
+                       $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
                }
-       } else {                
+       } else {
                // now replace SELECT ... FROM with SELECT COUNT(*) FROM
                $rewritesql = preg_replace(
                                        '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
@@ -431,7 +434,7 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
        
        if (isset($rewritesql) && $rewritesql != $sql) {
                if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
-
+                
                if ($secs2cache) {
                        // we only use half the time of secs2cache because the count can quickly
                        // become inaccurate if new records are added
@@ -452,7 +455,7 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
        
        if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
                
-       $rstest = &$zthis->Execute($rewritesql,$inputarr);
+       $rstest = $zthis->Execute($rewritesql,$inputarr);
        if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
        
        if ($rstest) {
@@ -486,7 +489,7 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
        data will get out of synch. use CachePageExecute() only with tables that
        rarely change.
 */
-function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, 
+function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, 
                                                $inputarr=false, $secs2cache=0) 
 {
        $atfirstpage = false;
@@ -522,9 +525,9 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
        // We get the data we want
        $offset = $nrows * ($page-1);
        if ($secs2cache > 0) 
-               $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
+               $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
        else 
-               $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
+               $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
 
        
        // Before returning the RecordSet, we set the pagination properties we need
@@ -539,8 +542,8 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
        return $rsreturn;
 }
 
-// Iván Oliva version
-function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
+// Iv�n Oliva version
+function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
 {
 
        $atfirstpage = false;
@@ -556,16 +559,16 @@ function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputar
        // the last page number.
        $pagecounter = $page + 1;
        $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
-       if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
-       else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
+       if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
+       else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
        if ($rstest) {
                while ($rstest && $rstest->EOF && $pagecounter>0) {
                        $atlastpage = true;
                        $pagecounter--;
                        $pagecounteroffset = $nrows * ($pagecounter - 1);
                        $rstest->Close();
-                       if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
-                       else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
+                       if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
+                       else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
                }
                if ($rstest) $rstest->Close();
        }
@@ -577,8 +580,8 @@ function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputar
        
        // We get the data we want
        $offset = $nrows * ($page-1);
-       if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
-       else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
+       if ($secs2cache > 0) $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
+       else $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
        
        // Before returning the RecordSet, we set the pagination properties we need
        if ($rsreturn) {
@@ -773,10 +776,10 @@ static $cacheCols;
                //php can't do a $rsclass::MetaType()
                $rsclass = $zthis->rsPrefix.$zthis->databaseType;
                $recordSet = new $rsclass(-1,$zthis->fetchMode);
-               $recordSet->connection = &$zthis;
+               $recordSet->connection = $zthis;
                
                if (is_string($cacheRS) && $cacheRS == $rs) {
-                       $columns =& $cacheCols;
+                       $columns = $cacheCols;
                } else {
                        $columns = $zthis->MetaColumns( $tableName );
                        $cacheRS = $tableName;
@@ -784,7 +787,7 @@ static $cacheCols;
                }
        } else if (is_subclass_of($rs, 'adorecordset')) {
                if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
-                       $columns =& $cacheCols;
+                       $columns = $cacheCols;
                } else {
                        for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) 
                                $columns[] = $rs->FetchField($i);
@@ -792,7 +795,7 @@ static $cacheCols;
                        $cacheCols = $columns;
                        $rs->insertSig = $cacheSig++;
                }
-               $recordSet =& $rs;
+               $recordSet = $rs;
        
        } else {
                printf(ADODB_BAD_RS,'GetInsertSQL');
@@ -993,7 +996,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
                case "D":
                        $val = $zthis->DBDate($arrFields[$fname]);
                        break;
-               
+
                case "T":
                        $val = $zthis->DBTimeStamp($arrFields[$fname]);
             break;
@@ -1002,7 +1005,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
                case "N":
                    $val = $arrFields[$fname];
                        if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
-                       break;
+                   break;
 
         case "L": //Integer field suitable for storing booleans (0 or 1)     // Moodle added
                case "I":
@@ -1178,4 +1181,4 @@ function _adodb_find_from($sql)
 }
 */
 
-?>
+?>
\ No newline at end of file
index 31a1c247f3d125aa7976523fbf4682aa3e644ce0..a4b7e7531c7710a789bf198a18e8e5ffa340ecf1 100644 (file)
@@ -18,7 +18,7 @@ $ADODB_INCLUDED_MEMCACHE = 1;
   
 */
 
-       function &getmemcache($key,&$err, $timeout=0, $host, $port)
+       function getmemcache($key,&$err, $timeout=0, $host, $port)
        {
                $false = false;
                $err = false;
index fe6bab543c73abc5e5d1026400bbdd106b36e6d9..16acee365f0cb9442e028e982e55b524dd043f3f 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-       V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+       V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -247,12 +247,12 @@ class ADODB_Pager {
                $savec = $ADODB_COUNTRECS;
                if ($this->db->pageExecuteCountRows) $ADODB_COUNTRECS = true;
                if ($this->cache)
-                       $rs = &$this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page);
+                       $rs = $this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page);
                else
-                       $rs = &$this->db->PageExecute($this->sql,$rows,$this->curr_page);
+                       $rs = $this->db->PageExecute($this->sql,$rows,$this->curr_page);
                $ADODB_COUNTRECS = $savec;
                
-               $this->rs = &$rs;
+               $this->rs = $rs;
                if (!$rs) {
                        print "<h3>Query failed: $this->sql</h3>";
                        return;
index cfdc2f8a987d140109a0905873011ab19b30aa5e..60696c5ccaad9133175aa68d5da7fa18d56d91b5 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008  (c) 2000-2008 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. 
@@ -109,11 +109,11 @@ class DB
         * error
         */
 
-       function &factory($type)
+       function factory($type)
        {
                include_once(ADODB_DIR."/drivers/adodb-$type.inc.php");
-               $obj = &NewADOConnection($type);
-               if (!is_object($obj)) $obj =& new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
+               $obj = NewADOConnection($type);
+               if (!is_object($obj)) $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
                return $obj;
        }
 
@@ -136,7 +136,7 @@ class DB
         * @see DB::parseDSN
         * @see DB::isError
         */
-       function &connect($dsn, $options = false)
+       function connect($dsn, $options = false)
        {
                if (is_array($dsn)) {
                        $dsninfo = $dsn;
@@ -157,9 +157,9 @@ class DB
                         @include_once("adodb-$type.inc.php");
                }
 
-               @$obj =& NewADOConnection($type);
+               @$obj = NewADOConnection($type);
                if (!is_object($obj)) {
-                       $obj =& new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
+                       $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
                        return $obj;
                }
                if (is_array($options)) {
index cd666dc50dfb28b90a0736d243f3aab9f183eeea..50af6e3c5b2f32ab0420df8f8c5790c45fd532ef 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -19,11 +19,12 @@ V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights rese
 if (!defined('ADODB_DIR')) include_once(dirname(__FILE__).'/adodb.inc.php');
 include_once(ADODB_DIR.'/tohtml.inc.php');
 
+define( 'ADODB_OPT_HIGH', 2);
+define( 'ADODB_OPT_LOW', 1);
+
 global $ADODB_PERF_MIN;
 $ADODB_PERF_MIN = 0.05; // log only if >= minimum number of secs to run
 
-define( 'ADODB_OPT_HIGH', 2);
-define( 'ADODB_OPT_LOW', 1);
 
 // returns in K the memory of current process, or 0 if not known
 function adodb_getmem()
@@ -65,25 +66,25 @@ function adodb_microtime()
 }
 
 /* sql code timing */
-function& adodb_log_sql(&$connx,$sql,$inputarr)
+function adodb_log_sql(&$connx,$sql,$inputarr)
 {
     $perf_table = adodb_perf::table();
        $connx->fnExecute = false;
        $t0 = microtime();
-       $rs =& $connx->Execute($sql,$inputarr);
+       $rs = $connx->Execute($sql,$inputarr);
        $t1 = microtime();
 
        if (!empty($connx->_logsql) && (empty($connx->_logsqlErrors) || !$rs)) {
        global $ADODB_LOG_CONN;
        
                if (!empty($ADODB_LOG_CONN)) {
-                       $conn = &$ADODB_LOG_CONN;
+                       $conn = $ADODB_LOG_CONN;
                        if ($conn->databaseType != $connx->databaseType)
                                $prefix = '/*dbx='.$connx->databaseType .'*/ ';
                        else
                                $prefix = '';
                } else {
-                       $conn =& $connx;
+                       $conn = $connx;
                        $prefix = '';
                }
                
@@ -168,12 +169,13 @@ function& adodb_log_sql(&$connx,$sql,$inputarr)
                        if ($dbT == 'db2') $arr['f'] = (float) $arr['f'];
                        $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)";
                }
+               
                global $ADODB_PERF_MIN;
                if ($errN != 0 || $time >= $ADODB_PERF_MIN) {
                        $ok = $conn->Execute($isql,$arr);
-               } else {
+               } else
                        $ok = true;
-               }
+               
                $conn->debug = $saved;
                
                if ($ok) {
@@ -181,7 +183,7 @@ function& adodb_log_sql(&$connx,$sql,$inputarr)
                } else {
                        $err2 = $conn->ErrorMsg();
                        $conn->_logsql = true; // enable logsql error simulation
-                       $perf =& NewPerfMonitor($conn);
+                       $perf = NewPerfMonitor($conn);
                        if ($perf) {
                                if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr);
                        } else {
@@ -235,7 +237,7 @@ class adodb_perf {
        var $maxLength = 2000;
        
     // Sets the tablename to be used            
-    function table($newtable = false)
+    static function table($newtable = false)
     {
         static $_table;
 
@@ -416,7 +418,7 @@ Committed_AS:   348732 kB
                $saveE = $this->conn->fnExecute;
                $this->conn->fnExecute = false;
         $perf_table = adodb_perf::table();
-               $rs =& $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
+               $rs = $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
                $this->conn->fnExecute = $saveE;
                if ($rs) {
                        $s .= rs2html($rs,false,false,false,false);
@@ -450,7 +452,7 @@ Committed_AS:   348732 kB
                        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                        if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
                        //$this->conn->debug=1;
-                       $rs =& $this->conn->SelectLimit(
+                       $rs = $this->conn->SelectLimit(
                        "select avg(timer) as avg_timer,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
                                from $perf_table
                                where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
@@ -529,7 +531,7 @@ Committed_AS:   348732 kB
                        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                        if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
                        
-                       $rs =& $this->conn->SelectLimit(
+                       $rs = $this->conn->SelectLimit(
                        "select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
                                from $perf_table
                                where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5))  not in ('DROP ','INSER','COMMI','CREAT')
@@ -578,7 +580,7 @@ Committed_AS:   348732 kB
        /*
                Raw function returning array of poll paramters
        */
-       function &PollParameters()
+       function PollParameters()
        {
                $arr[0] = (float)$this->DBParameter('data cache hit ratio');
                $arr[1] = (float)$this->DBParameter('data reads');
@@ -653,11 +655,10 @@ Committed_AS:   348732 kB
                $perf_table = adodb_perf::table();
                $this->conn->Execute("delete from $perf_table where created<".$this->conn->sysTimeStamp);
        }
-       
        /***********************************************************************************************/
        //                                    HIGH LEVEL UI FUNCTIONS
        /***********************************************************************************************/
-       
+
        
        function UI($pollsecs=5)
        {
@@ -719,13 +720,11 @@ Committed_AS:   348732 kB
                switch ($do) {
                default:
                case 'stats':
-               
                        if (empty($ADODB_LOG_CONN))
                                echo "<p>&nbsp; <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
                        echo $this->HealthCheck();
                        //$this->conn->debug=1;
-                       echo $this->CheckMemory();
-                       global $ADODB_LOG_CONN;
+                       echo $this->CheckMemory();              
                        break;
                case 'poll':
                        echo "<iframe width=720 height=80% 
@@ -764,13 +763,13 @@ Committed_AS:   348732 kB
                //$this->conn->debug=1;
                if ($secs <= 1) $secs = 1;
                echo "Accumulating statistics, every $secs seconds...\n";flush();
-               $arro =& $this->PollParameters();
+               $arro = $this->PollParameters();
                $cnt = 0;
                set_time_limit(0);
                sleep($secs);
                while (1) {
 
-                       $arr =& $this->PollParameters();
+                       $arr = $this->PollParameters();
                        
                        $hits   = sprintf('%2.2f',$arr[0]);
                        $reads  = sprintf('%12.4f',($arr[1]-$arro[1])/$secs);
index 140d28ae879981a1760add7b828e0e18c202065c..dca76105cba403bed01d8f693a7ccc2b25036198 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 1ae50767c67424a7209d0025296e3fbd2fa4f89a..19b22fb4feb704ac624eef24cbab174b6addfaba 100644 (file)
@@ -411,7 +411,7 @@ function adodb_date_test_date($y1,$m,$d=13)
        $t = adodb_mktime($h,0,0,$m,$d,$y1);
        $rez = adodb_date('Y-n-j H:i:s',$t);
        if ($h == 0) $h = '00';
-       else if ($h < 10) $h = '0'.$h;  
+       else if ($h < 10) $h = '0'.$h;
        if ("$y1-$m-$d $h:00:00" != $rez) {
                print "<b>$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez</b><br>";
                return false;
@@ -432,7 +432,7 @@ function adodb_date_test_strftime($fmt)
 
 /**
         Test Suite
-*/             
+*/     
 function adodb_date_test()
 {
        
@@ -1423,4 +1423,5 @@ global $ADODB_DATE_LOCALE;
        return $ret;
 }
 
+
 ?>
\ No newline at end of file
index c925f0b53d7463fa82f04bd3737e977a69d412a9..38490d7593cd271c67c9c6975fad76249956a0da 100644 (file)
-<?php
-// Copyright (c) 2004 ars Cognita Inc., 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. 
-*******************************************************************************/
-/**
- * xmlschema is a class that allows the user to quickly and easily
- * build a database on any ADOdb-supported platform using a simple
- * XML schema.
- *
- * Last Editor: $Author$
- * @author Richard Tango-Lowy & Dan Cech
- * @version $Revision$
- *
- * @package axmls
- * @tutorial getting_started.pkg
- */
-function _file_get_contents($file) 
-{
-       if (function_exists('file_get_contents')) return file_get_contents($file);
-       
-       $f = fopen($file,'r');
-       if (!$f) return '';
-       $t = '';
-       
-       while ($s = fread($f,100000)) $t .= $s;
-       fclose($f);
-       return $t;
-}
-
-
-/**
-* Debug on or off
-*/
-if( !defined( 'XMLS_DEBUG' ) ) {
-       define( 'XMLS_DEBUG', FALSE );
-}
-
-/**
-* Default prefix key
-*/
-if( !defined( 'XMLS_PREFIX' ) ) {
-       define( 'XMLS_PREFIX', '%%P' );
-}
-
-/**
-* Maximum length allowed for object prefix
-*/
-if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
-       define( 'XMLS_PREFIX_MAXLEN', 10 );
-}
-
-/**
-* Execute SQL inline as it is generated
-*/
-if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
-       define( 'XMLS_EXECUTE_INLINE', FALSE );
-}
-
-/**
-* Continue SQL Execution if an error occurs?
-*/
-if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
-       define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
-}
-
-/**
-* Current Schema Version
-*/
-if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
-       define( 'XMLS_SCHEMA_VERSION', '0.2' );
-}
-
-/**
-* Default Schema Version.  Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
-       define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
-}
-
-/**
-* Default Schema Version.  Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
-       define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
-}
-
-/**
-* Include the main ADODB library
-*/
-if( !defined( '_ADODB_LAYER' ) ) {
-       require( 'adodb.inc.php' );
-       require( 'adodb-datadict.inc.php' );
-}
-
-/**
-* Abstract DB Object. This class provides basic methods for database objects, such
-* as tables and indexes.
-*
-* @package axmls
-* @access private
-*/
-class dbObject {
-       
-       /**
-       * var object Parent
-       */
-       var $parent;
-       
-       /**
-       * var string current element
-       */
-       var $currentElement;
-       
-       /**
-       * NOP
-       */
-       function dbObject( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               
-       }
-       
-       function create() {
-               return array();
-       }
-       
-       /**
-       * Destroys the object
-       */
-       function destroy() {
-               unset( $this );
-       }
-       
-       /**
-       * Checks whether the specified RDBMS is supported by the current
-       * database object or its ranking ancestor.
-       *
-       * @param string $platform RDBMS platform name (from ADODB platform list).
-       * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
-       */
-       function supportedPlatform( $platform = NULL ) {
-               return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
-       }
-       
-       /**
-       * Returns the prefix set by the ranking ancestor of the database object.
-       *
-       * @param string $name Prefix string.
-       * @return string Prefix.
-       */
-       function prefix( $name = '' ) {
-               return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
-       }
-       
-       /**
-       * Extracts a field ID from the specified field.
-       *
-       * @param string $field Field.
-       * @return string Field ID.
-       */
-       function FieldID( $field ) {
-               return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
-       }
-}
-
-/**
-* Creates a table object in ADOdb's datadict format
-*
-* This class stores information about a database table. As charactaristics
-* of the table are loaded from the external source, methods and properties
-* of this class are used to build up the table description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbTable extends dbObject {
-       
-       /**
-       * @var string Table name
-       */
-       var $name;
-       
-       /**
-       * @var array Field specifier: Meta-information about each field
-       */
-       var $fields = array();
-       
-       /**
-       * @var array List of table indexes.
-       */
-       var $indexes = array();
-       
-       /**
-       * @var array Table options: Table-level options
-       */
-       var $opts = array();
-       
-       /**
-       * @var string Field index: Keeps track of which field is currently being processed
-       */
-       var $current_field;
-       
-       /**
-       * @var boolean Mark table for destruction
-       * @access private
-       */
-       var $drop_table;
-       
-       /**
-       * @var boolean Mark field for destruction (not yet implemented)
-       * @access private
-       */
-       var $drop_field = array();
-       
-       /**
-       * Iniitializes a new table object.
-       *
-       * @param string $prefix DB Object prefix
-       * @param array $attributes Array of table attributes.
-       */
-       function dbTable( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-               $this->name = $this->prefix($attributes['NAME']);
-       }
-       
-       /**
-       * XML Callback to process start elements. Elements currently 
-       * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT. 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'INDEX':
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       xml_set_object( $parser, $this->addIndex( $attributes ) );
-                               }
-                               break;
-                       case 'DATA':
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       xml_set_object( $parser, $this->addData( $attributes ) );
-                               }
-                               break;
-                       case 'DROP':
-                               $this->drop();
-                               break;
-                       case 'FIELD':
-                               // Add a field
-                               $fieldName = $attributes['NAME'];
-                               $fieldType = $attributes['TYPE'];
-                               $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;
-                               $fieldOpts = isset( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;
-                               
-                               $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
-                               break;
-                       case 'KEY':
-                       case 'NOTNULL':
-                       case 'AUTOINCREMENT':
-                               // Add a field option
-                               $this->addFieldOpt( $this->current_field, $this->currentElement );
-                               break;
-                       case 'DEFAULT':
-                               // Add a field option to the table object
-                               
-                               // Work around ADOdb datadict issue that misinterprets empty strings.
-                               if( $attributes['VALUE'] == '' ) {
-                                       $attributes['VALUE'] = " '' ";
-                               }
-                               
-                               $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );
-                               break;
-                       case 'DEFDATE':
-                       case 'DEFTIMESTAMP':
-                               // Add a field option to the table object
-                               $this->addFieldOpt( $this->current_field, $this->currentElement );
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Table constraint
-                       case 'CONSTRAINT':
-                               if( isset( $this->current_field ) ) {
-                                       $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
-                               } else {
-                                       $this->addTableOpt( $cdata );
-                               }
-                               break;
-                       // Table option
-                       case 'OPT':
-                               $this->addTableOpt( $cdata );
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'TABLE':
-                               $this->parent->addSQL( $this->create( $this->parent ) );
-                               xml_set_object( $parser, $this->parent );
-                               $this->destroy();
-                               break;
-                       case 'FIELD':
-                               unset($this->current_field);
-                               break;
-
-               }
-       }
-       
-       /**
-       * Adds an index to a table object
-       *
-       * @param array $attributes Index attributes
-       * @return object dbIndex object
-       */
-       function &addIndex( $attributes ) {
-               $name = strtoupper( $attributes['NAME'] );
-               $this->indexes[$name] =& new dbIndex( $this, $attributes );
-               return $this->indexes[$name];
-       }
-       
-       /**
-       * Adds data to a table object
-       *
-       * @param array $attributes Data attributes
-       * @return object dbData object
-       */
-       function &addData( $attributes ) {
-               if( !isset( $this->data ) ) {
-                       $this->data =& new dbData( $this, $attributes );
-               }
-               return $this->data;
-       }
-       
-       /**
-       * Adds a field to a table object
-       *
-       * $name is the name of the table to which the field should be added. 
-       * $type is an ADODB datadict field type. The following field types
-       * are supported as of ADODB 3.40:
-       *       - C:  varchar
-       *       - X:  CLOB (character large object) or largest varchar size
-       *          if CLOB is not supported
-       *       - C2: Multibyte varchar
-       *       - X2: Multibyte CLOB
-       *       - B:  BLOB (binary large object)
-       *       - D:  Date (some databases do not support this, and we return a datetime type)
-       *       - T:  Datetime or Timestamp
-       *       - L:  Integer field suitable for storing booleans (0 or 1)
-       *       - I:  Integer (mapped to I4)
-       *       - I1: 1-byte integer
-       *       - I2: 2-byte integer
-       *       - I4: 4-byte integer
-       *       - I8: 8-byte integer
-       *       - F:  Floating point number
-       *       - N:  Numeric or decimal number
-       *
-       * @param string $name Name of the table to which the field will be added.
-       * @param string $type   ADODB datadict field type.
-       * @param string $size   Field size
-       * @param array $opts    Field options array
-       * @return array Field specifier array
-       */
-       function addField( $name, $type, $size = NULL, $opts = NULL ) {
-               $field_id = $this->FieldID( $name );
-               
-               // Set the field index so we know where we are
-               $this->current_field = $field_id;
-               
-               // Set the field name (required)
-               $this->fields[$field_id]['NAME'] = $name;
-               
-               // Set the field type (required)
-               $this->fields[$field_id]['TYPE'] = $type;
-               
-               // Set the field size (optional)
-               if( isset( $size ) ) {
-                       $this->fields[$field_id]['SIZE'] = $size;
-               }
-               
-               // Set the field options
-               if( isset( $opts ) ) {
-                       $this->fields[$field_id]['OPTS'][] = $opts;
-               }
-       }
-       
-       /**
-       * Adds a field option to the current field specifier
-       *
-       * This method adds a field option allowed by the ADOdb datadict 
-       * and appends it to the given field.
-       *
-       * @param string $field  Field name
-       * @param string $opt ADOdb field option
-       * @param mixed $value Field option value
-       * @return array Field specifier array
-       */
-       function addFieldOpt( $field, $opt, $value = NULL ) {
-               if( !isset( $value ) ) {
-                       $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
-               // Add the option and value
-               } else {
-                       $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );
-               }
-       }
-       
-       /**
-       * Adds an option to the table
-       *
-       * This method takes a comma-separated list of table-level options
-       * and appends them to the table object.
-       *
-       * @param string $opt Table option
-       * @return array Options
-       */
-       function addTableOpt( $opt ) {
-               $this->opts[] = $opt;
-               
-               return $this->opts;
-       }
-       
-       /**
-       * Generates the SQL that will create the table in the database
-       *
-       * @param object $xmls adoSchema object
-       * @return array Array containing table creation SQL
-       */
-       function create( &$xmls ) {
-               $sql = array();
-               
-               // drop any existing indexes
-               if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
-                       foreach( $legacy_indexes as $index => $index_details ) {
-                               $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
-                       }
-               }
-               
-               // remove fields to be dropped from table object
-               foreach( $this->drop_field as $field ) {
-                       unset( $this->fields[$field] );
-               }
-               
-               // if table exists
-               if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
-                       // drop table
-                       if( $this->drop_table ) {
-                               $sql[] = $xmls->dict->DropTableSQL( $this->name );
-                               
-                               return $sql;
-                       }
-                       
-                       // drop any existing fields not in schema
-                       foreach( $legacy_fields as $field_id => $field ) {
-                               if( !isset( $this->fields[$field_id] ) ) {
-                                       $sql[] = $xmls->dict->DropColumnSQL( $this->name, '`'.$field->name.'`' );
-                               }
-                       }
-               // if table doesn't exist
-               } else {
-                       if( $this->drop_table ) {
-                               return $sql;
-                       }
-                       
-                       $legacy_fields = array();
-               }
-               
-               // Loop through the field specifier array, building the associative array for the field options
-               $fldarray = array();
-               
-               foreach( $this->fields as $field_id => $finfo ) {
-                       // Set an empty size if it isn't supplied
-                       if( !isset( $finfo['SIZE'] ) ) {
-                               $finfo['SIZE'] = '';
-                       }
-                       
-                       // Initialize the field array with the type and size
-                       $fldarray[$field_id] = array(
-                               'NAME' => $finfo['NAME'],
-                               'TYPE' => $finfo['TYPE'],
-                               'SIZE' => $finfo['SIZE']
-                       );
-                       
-                       // Loop through the options array and add the field options. 
-                       if( isset( $finfo['OPTS'] ) ) {
-                               foreach( $finfo['OPTS'] as $opt ) {
-                                       // Option has an argument.
-                                       if( is_array( $opt ) ) {
-                                               $key = key( $opt );
-                                               $value = $opt[key( $opt )];
-                                               @$fldarray[$field_id][$key] .= $value;
-                                       // Option doesn't have arguments
-                                       } else {
-                                               $fldarray[$field_id][$opt] = $opt;
-                                       }
-                               }
-                       }
-               }
-               
-               if( empty( $legacy_fields ) ) {
-                       // Create the new table
-                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
-                       logMsg( end( $sql ), 'Generated CreateTableSQL' );
-               } else {
-                       // Upgrade an existing table
-                       logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
-                       switch( $xmls->upgrade ) {
-                               // Use ChangeTableSQL
-                               case 'ALTER':
-                                       logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
-                                       $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
-                                       break;
-                               case 'REPLACE':
-                                       logMsg( 'Doing upgrade REPLACE (testing)' );
-                                       $sql[] = $xmls->dict->DropTableSQL( $this->name );
-                                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
-                                       break;
-                               // ignore table
-                               default:
-                                       return array();
-                       }
-               }
-               
-               foreach( $this->indexes as $index ) {
-                       $sql[] = $index->create( $xmls );
-               }
-               
-               if( isset( $this->data ) ) {
-                       $sql[] = $this->data->create( $xmls );
-               }
-               
-               return $sql;
-       }
-       
-       /**
-       * Marks a field or table for destruction
-       */
-       function drop() {
-               if( isset( $this->current_field ) ) {
-                       // Drop the current field
-                       logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );
-                       // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );
-                       $this->drop_field[$this->current_field] = $this->current_field;
-               } else {
-                       // Drop the current table
-                       logMsg( "Dropping table '{$this->name}'" );
-                       // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );
-                       $this->drop_table = TRUE;
-               }
-       }
-}
-
-/**
-* Creates an index object in ADOdb's datadict format
-*
-* This class stores information about a database index. As charactaristics
-* of the index are loaded from the external source, methods and properties
-* of this class are used to build up the index description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbIndex extends dbObject {
-       
-       /**
-       * @var string   Index name
-       */
-       var $name;
-       
-       /**
-       * @var array    Index options: Index-level options
-       */
-       var $opts = array();
-       
-       /**
-       * @var array    Indexed fields: Table columns included in this index
-       */
-       var $columns = array();
-       
-       /**
-       * @var boolean Mark index for destruction
-       * @access private
-       */
-       var $drop = FALSE;
-       
-       /**
-       * Initializes the new dbIndex object.
-       *
-       * @param object $parent Parent object
-       * @param array $attributes Attributes
-       *
-       * @internal
-       */
-       function dbIndex( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-               
-               $this->name = $this->prefix ($attributes['NAME']);
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * Processes XML opening tags. 
-       * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'DROP':
-                               $this->drop();
-                               break;
-                       case 'CLUSTERED':
-                       case 'BITMAP':
-                       case 'UNIQUE':
-                       case 'FULLTEXT':
-                       case 'HASH':
-                               // Add index Option
-                               $this->addIndexOpt( $this->currentElement );
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * Processes XML cdata.
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Index field name
-                       case 'COL':
-                               $this->addField( $cdata );
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'INDEX':
-                               xml_set_object( $parser, $this->parent );
-                               break;
-               }
-       }
-       
-       /**
-       * Adds a field to the index
-       *
-       * @param string $name Field name
-       * @return string Field list
-       */
-       function addField( $name ) {
-               $this->columns[$this->FieldID( $name )] = $name;
-               
-               // Return the field list
-               return $this->columns;
-       }
-       
-       /**
-       * Adds options to the index
-       *
-       * @param string $opt Comma-separated list of index options.
-       * @return string Option list
-       */
-       function addIndexOpt( $opt ) {
-               $this->opts[] = $opt;
-               
-               // Return the options list
-               return $this->opts;
-       }
-       
-       /**
-       * Generates the SQL that will create the index in the database
-       *
-       * @param object $xmls adoSchema object
-       * @return array Array containing index creation SQL
-       */
-       function create( &$xmls ) {
-               if( $this->drop ) {
-                       return NULL;
-               }
-               
-               // eliminate any columns that aren't in the table
-               foreach( $this->columns as $id => $col ) {
-                       if( !isset( $this->parent->fields[$id] ) ) {
-                               unset( $this->columns[$id] );
-                       }
-               }
-               
-               return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
-       }
-       
-       /**
-       * Marks an index for destruction
-       */
-       function drop() {
-               $this->drop = TRUE;
-       }
-}
-
-/**
-* Creates a data object in ADOdb's datadict format
-*
-* This class stores information about table data.
-*
-* @package axmls
-* @access private
-*/
-class dbData extends dbObject {
-       
-       var $data = array();
-       
-       var $row;
-       
-       /**
-       * Initializes the new dbIndex object.
-       *
-       * @param object $parent Parent object
-       * @param array $attributes Attributes
-       *
-       * @internal
-       */
-       function dbData( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * Processes XML opening tags. 
-       * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'ROW':
-                               $this->row = count( $this->data );
-                               $this->data[$this->row] = array();
-                               break;
-                       case 'F':
-                               $this->addField($attributes);
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * Processes XML cdata.
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Index field name
-                       case 'F':
-                               $this->addData( $cdata );
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'DATA':
-                               xml_set_object( $parser, $this->parent );
-                               break;
-               }
-       }
-       
-       /**
-       * Adds a field to the index
-       *
-       * @param string $name Field name
-       * @return string Field list
-       */
-       function addField( $attributes ) {
-               if( isset( $attributes['NAME'] ) ) {
-                       $name = $attributes['NAME'];
-               } else {
-                       $name = count($this->data[$this->row]);
-               }
-               
-               // Set the field index so we know where we are
-               $this->current_field = $this->FieldID( $name );
-       }
-       
-       /**
-       * Adds options to the index
-       *
-       * @param string $opt Comma-separated list of index options.
-       * @return string Option list
-       */
-       function addData( $cdata ) {
-               if( !isset( $this->data[$this->row] ) ) {
-                       $this->data[$this->row] = array();
-               }
-               
-               if( !isset( $this->data[$this->row][$this->current_field] ) ) {
-                       $this->data[$this->row][$this->current_field] = '';
-               }
-               
-               $this->data[$this->row][$this->current_field] .= $cdata;
-       }
-       
-       /**
-       * Generates the SQL that will create the index in the database
-       *
-       * @param object $xmls adoSchema object
-       * @return array Array containing index creation SQL
-       */
-       function create( &$xmls ) {
-               $table = $xmls->dict->TableName($this->parent->name);
-               $table_field_count = count($this->parent->fields);
-               $sql = array();
-               
-               // eliminate any columns that aren't in the table
-               foreach( $this->data as $row ) {
-                       $table_fields = $this->parent->fields;
-                       $fields = array();
-                       
-                       foreach( $row as $field_id => $field_data ) {
-                               if( !array_key_exists( $field_id, $table_fields ) ) {
-                                       if( is_numeric( $field_id ) ) {
-                                               $field_id = reset( array_keys( $table_fields ) );
-                                       } else {
-                                               continue;
-                                       }
-                               }
-                               
-                               $name = $table_fields[$field_id]['NAME'];
-                               
-                               switch( $table_fields[$field_id]['TYPE'] ) {
-                                       case 'C':
-                                       case 'C2':
-                                       case 'X':
-                                       case 'X2':
-                                               $fields[$name] = $xmls->db->qstr( $field_data );
-                                               break;
-                                       case 'I':
-                                       case 'I1':
-                                       case 'I2':
-                                       case 'I4':
-                                       case 'I8':
-                                               $fields[$name] = intval($field_data);
-                                               break;
-                                       default:
-                                               $fields[$name] = $field_data;
-                               }
-                               
-                               unset($table_fields[$field_id]);
-                       }
-                       
-                       // check that at least 1 column is specified
-                       if( empty( $fields ) ) {
-                               continue;
-                       }
-                       
-                       // check that no required columns are missing
-                       if( count( $fields ) < $table_field_count ) {
-                               foreach( $table_fields as $field ) {
-                                       if (isset( $field['OPTS'] ))
-                                               if( ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {
-                                                       continue(2);
-                                               }
-                               }
-                       }
-                       
-                       $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
-               }
-               
-               return $sql;
-       }
-}
-
-/**
-* Creates the SQL to execute a list of provided SQL queries
-*
-* @package axmls
-* @access private
-*/
-class dbQuerySet extends dbObject {
-       
-       /**
-       * @var array    List of SQL queries
-       */
-       var $queries = array();
-       
-       /**
-       * @var string   String used to build of a query line by line
-       */
-       var $query;
-       
-       /**
-       * @var string   Query prefix key
-       */
-       var $prefixKey = '';
-       
-       /**
-       * @var boolean  Auto prefix enable (TRUE)
-       */
-       var $prefixMethod = 'AUTO';
-       
-       /**
-       * Initializes the query set.
-       *
-       * @param object $parent Parent object
-       * @param array $attributes Attributes
-       */
-       function dbQuerySet( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-                       
-               // Overrides the manual prefix key
-               if( isset( $attributes['KEY'] ) ) {
-                       $this->prefixKey = $attributes['KEY'];
-               }
-               
-               $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';
-               
-               // Enables or disables automatic prefix prepending
-               switch( $prefixMethod ) {
-                       case 'AUTO':
-                               $this->prefixMethod = 'AUTO';
-                               break;
-                       case 'MANUAL':
-                               $this->prefixMethod = 'MANUAL';
-                               break;
-                       case 'NONE':
-                               $this->prefixMethod = 'NONE';
-                               break;
-               }
-       }
-       
-       /**
-       * XML Callback to process start elements. Elements currently 
-       * processed are: QUERY. 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'QUERY':
-                               // Create a new query in a SQL queryset.
-                               // Ignore this query set if a platform is specified and it's different than the 
-                               // current connection platform.
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       $this->newQuery();
-                               } else {
-                                       $this->discardQuery();
-                               }
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Line of queryset SQL data
-                       case 'QUERY':
-                               $this->buildQuery( $cdata );
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'QUERY':
-                               // Add the finished query to the open query set.
-                               $this->addQuery();
-                               break;
-                       case 'SQL':
-                               $this->parent->addSQL( $this->create( $this->parent ) );
-                               xml_set_object( $parser, $this->parent );
-                               $this->destroy();
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * Re-initializes the query.
-       *
-       * @return boolean TRUE
-       */
-       function newQuery() {
-               $this->query = '';
-               
-               return TRUE;
-       }
-       
-       /**
-       * Discards the existing query.
-       *
-       * @return boolean TRUE
-       */
-       function discardQuery() {
-               unset( $this->query );
-               
-               return TRUE;
-       }
-       
-       /** 
-       * Appends a line to a query that is being built line by line
-       *
-       * @param string $data Line of SQL data or NULL to initialize a new query
-       * @return string SQL query string.
-       */
-       function buildQuery( $sql = NULL ) {
-               if( !isset( $this->query ) OR empty( $sql ) ) {
-                       return FALSE;
-               }
-               
-               $this->query .= $sql;
-               
-               return $this->query;
-       }
-       
-       /**
-       * Adds a completed query to the query list
-       *
-       * @return string        SQL of added query
-       */
-       function addQuery() {
-               if( !isset( $this->query ) ) {
-                       return FALSE;
-               }
-               
-               $this->queries[] = $return = trim($this->query);
-               
-               unset( $this->query );
-               
-               return $return;
-       }
-       
-       /**
-       * Creates and returns the current query set
-       *
-       * @param object $xmls adoSchema object
-       * @return array Query set
-       */
-       function create( &$xmls ) {
-               foreach( $this->queries as $id => $query ) {
-                       switch( $this->prefixMethod ) {
-                               case 'AUTO':
-                                       // Enable auto prefix replacement
-                                       
-                                       // Process object prefix.
-                                       // Evaluate SQL statements to prepend prefix to objects
-                                       $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-                                       $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-                                       $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-                                       
-                                       // SELECT statements aren't working yet
-                                       #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
-                                       
-                               case 'MANUAL':
-                                       // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
-                                       // If prefixKey is not set, we use the default constant XMLS_PREFIX
-                                       if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
-                                               // Enable prefix override
-                                               $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
-                                       } else {
-                                               // Use default replacement
-                                               $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
-                                       }
-                       }
-                       
-                       $this->queries[$id] = trim( $query );
-               }
-               
-               // Return the query set array
-               return $this->queries;
-       }
-       
-       /**
-       * Rebuilds the query with the prefix attached to any objects
-       *
-       * @param string $regex Regex used to add prefix
-       * @param string $query SQL query string
-       * @param string $prefix Prefix to be appended to tables, indices, etc.
-       * @return string Prefixed SQL query string.
-       */
-       function prefixQuery( $regex, $query, $prefix = NULL ) {
-               if( !isset( $prefix ) ) {
-                       return $query;
-               }
-               
-               if( preg_match( $regex, $query, $match ) ) {
-                       $preamble = $match[1];
-                       $postamble = $match[5];
-                       $objectList = explode( ',', $match[3] );
-                       // $prefix = $prefix . '_';
-                       
-                       $prefixedList = '';
-                       
-                       foreach( $objectList as $object ) {
-                               if( $prefixedList !== '' ) {
-                                       $prefixedList .= ', ';
-                               }
-                               
-                               $prefixedList .= $prefix . trim( $object );
-                       }
-                       
-                       $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
-               }
-               
-               return $query;
-       }
-}
-
-/**
-* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
-* 
-* This class is used to load and parse the XML file, to create an array of SQL statements
-* that can be used to build a database, and to build the database using the SQL array.
-*
-* @tutorial getting_started.pkg
-*
-* @author Richard Tango-Lowy & Dan Cech
-* @version $Revision$
-*
-* @package axmls
-*/
-class adoSchema {
-       
-       /**
-       * @var array    Array containing SQL queries to generate all objects
-       * @access private
-       */
-       var $sqlArray;
-       
-       /**
-       * @var object   ADOdb connection object
-       * @access private
-       */
-       var $db;
-       
-       /**
-       * @var object   ADOdb Data Dictionary
-       * @access private
-       */
-       var $dict;
-       
-       /**
-       * @var string Current XML element
-       * @access private
-       */
-       var $currentElement = '';
-       
-       /**
-       * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
-       * @access private
-       */
-       var $upgrade = '';
-       
-       /**
-       * @var string Optional object prefix
-       * @access private
-       */
-       var $objectPrefix = '';
-       
-       /**
-       * @var long     Original Magic Quotes Runtime value
-       * @access private
-       */
-       var $mgq;
-       
-       /**
-       * @var long     System debug
-       * @access private
-       */
-       var $debug;
-       
-       /**
-       * @var string Regular expression to find schema version
-       * @access private
-       */
-       var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
-       
-       /**
-       * @var string Current schema version
-       * @access private
-       */
-       var $schemaVersion;
-       
-       /**
-       * @var int      Success of last Schema execution
-       */
-       var $success;
-       
-       /**
-       * @var bool     Execute SQL inline as it is generated
-       */
-       var $executeInline;
-       
-       /**
-       * @var bool     Continue SQL execution if errors occur
-       */
-       var $continueOnError;
-       
-       /**
-       * Creates an adoSchema object
-       *
-       * Creating an adoSchema object is the first step in processing an XML schema.
-       * The only parameter is an ADOdb database connection object, which must already
-       * have been created.
-       *
-       * @param object $db ADOdb database connection object.
-       */
-       function adoSchema( &$db ) {
-               // Initialize the environment
-               $this->mgq = get_magic_quotes_runtime();
-               set_magic_quotes_runtime(0);
-               
-               $this->db =& $db;
-               $this->debug = $this->db->debug;
-               $this->dict = NewDataDictionary( $this->db );
-               $this->sqlArray = array();
-               $this->schemaVersion = XMLS_SCHEMA_VERSION;
-               $this->executeInline( XMLS_EXECUTE_INLINE );
-               $this->continueOnError( XMLS_CONTINUE_ON_ERROR );
-               $this->setUpgradeMethod();
-       }
-       
-       /**
-       * Sets the method to be used for upgrading an existing database
-       *
-       * Use this method to specify how existing database objects should be upgraded.
-       * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
-       * alter each database object directly, REPLACE attempts to rebuild each object
-       * from scratch, BEST attempts to determine the best upgrade method for each
-       * object, and NONE disables upgrading.
-       *
-       * This method is not yet used by AXMLS, but exists for backward compatibility.
-       * The ALTER method is automatically assumed when the adoSchema object is
-       * instantiated; other upgrade methods are not currently supported.
-       *
-       * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
-       * @returns string Upgrade method used
-       */
-       function SetUpgradeMethod( $method = '' ) {
-               if( !is_string( $method ) ) {
-                       return FALSE;
-               }
-               
-               $method = strtoupper( $method );
-               
-               // Handle the upgrade methods
-               switch( $method ) {
-                       case 'ALTER':
-                               $this->upgrade = $method;
-                               break;
-                       case 'REPLACE':
-                               $this->upgrade = $method;
-                               break;
-                       case 'BEST':
-                               $this->upgrade = 'ALTER';
-                               break;
-                       case 'NONE':
-                               $this->upgrade = 'NONE';
-                               break;
-                       default:
-                               // Use default if no legitimate method is passed.
-                               $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
-               }
-               
-               return $this->upgrade;
-       }
-       
-       /**
-       * Enables/disables inline SQL execution.
-       *
-       * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
-       * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
-       * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
-       * to apply the schema to the database.
-       *
-       * @param bool $mode execute
-       * @return bool current execution mode
-       *
-       * @see ParseSchema(), ExecuteSchema()
-       */
-       function ExecuteInline( $mode = NULL ) {
-               if( is_bool( $mode ) ) {
-                       $this->executeInline = $mode;
-               }
-               
-               return $this->executeInline;
-       }
-       
-       /**
-       * Enables/disables SQL continue on error.
-       *
-       * Call this method to enable or disable continuation of SQL execution if an error occurs.
-       * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
-       * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
-       * of the schema will continue.
-       *
-       * @param bool $mode execute
-       * @return bool current continueOnError mode
-       *
-       * @see addSQL(), ExecuteSchema()
-       */
-       function ContinueOnError( $mode = NULL ) {
-               if( is_bool( $mode ) ) {
-                       $this->continueOnError = $mode;
-               }
-               
-               return $this->continueOnError;
-       }
-       
-       /**
-       * Loads an XML schema from a file and converts it to SQL.
-       *
-       * Call this method to load the specified schema (see the DTD for the proper format) from
-       * the filesystem and generate the SQL necessary to create the database described. 
-       * @see ParseSchemaString()
-       *
-       * @param string $file Name of XML schema file.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute
-       */
-       function ParseSchema( $filename, $returnSchema = FALSE ) {
-               return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
-       }
-       
-       /**
-       * Loads an XML schema from a file and converts it to SQL.
-       *
-       * Call this method to load the specified schema from a file (see the DTD for the proper format) 
-       * and generate the SQL necessary to create the database described by the schema.
-       *
-       * @param string $file Name of XML schema file.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute.
-       *
-       * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
-       * @see ParseSchema(), ParseSchemaString()
-       */
-       function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
-               // Open the file
-               if( !($fp = fopen( $filename, 'r' )) ) {
-                       // die( 'Unable to open file' );
-                       return FALSE;
-               }
-               
-               // do version detection here
-               if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
-                       return FALSE;
-               }
-               
-               if ( $returnSchema )
-               {
-                       $xmlstring = '';
-                       while( $data = fread( $fp, 100000 ) ) {
-                               $xmlstring .= $data;
-                       }
-                       return $xmlstring;
-               }
-               
-               $this->success = 2;
-               
-               $xmlParser = $this->create_parser();
-               
-               // Process the file
-               while( $data = fread( $fp, 4096 ) ) {
-                       if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
-                               die( sprintf(
-                                       "XML error: %s at line %d",
-                                       xml_error_string( xml_get_error_code( $xmlParser) ),
-                                       xml_get_current_line_number( $xmlParser)
-                               ) );
-                       }
-               }
-               
-               xml_parser_free( $xmlParser );
-               
-               return $this->sqlArray;
-       }
-       
-       /**
-       * Converts an XML schema string to SQL.
-       *
-       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
-       * and generate the SQL necessary to create the database described by the schema. 
-       * @see ParseSchema()
-       *
-       * @param string $xmlstring XML schema string.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute.
-       */
-       function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
-               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
-                       return FALSE;
-               }
-               
-               // do version detection here
-               if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
-                       return FALSE;
-               }
-               
-               if ( $returnSchema )
-               {
-                       return $xmlstring;
-               }
-               
-               $this->success = 2;
-               
-               $xmlParser = $this->create_parser();
-               
-               if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
-                       die( sprintf(
-                               "XML error: %s at line %d",
-                               xml_error_string( xml_get_error_code( $xmlParser) ),
-                               xml_get_current_line_number( $xmlParser)
-                       ) );
-               }
-               
-               xml_parser_free( $xmlParser );
-               
-               return $this->sqlArray;
-       }
-       
-       /**
-       * Loads an XML schema from a file and converts it to uninstallation SQL.
-       *
-       * Call this method to load the specified schema (see the DTD for the proper format) from
-       * the filesystem and generate the SQL necessary to remove the database described.
-       * @see RemoveSchemaString()
-       *
-       * @param string $file Name of XML schema file.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute
-       */
-       function RemoveSchema( $filename, $returnSchema = FALSE ) {
-               return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
-       }
-       
-       /**
-       * Converts an XML schema string to uninstallation SQL.
-       *
-       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
-       * and generate the SQL necessary to uninstall the database described by the schema. 
-       * @see RemoveSchema()
-       *
-       * @param string $schema XML schema string.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute.
-       */
-       function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
-               
-               // grab current version
-               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
-                       return FALSE;
-               }
-               
-               return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
-       }
-       
-       /**
-       * Applies the current XML schema to the database (post execution).
-       *
-       * Call this method to apply the current schema (generally created by calling 
-       * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes, 
-       * and executing other SQL specified in the schema) after parsing.
-       * @see ParseSchema(), ParseSchemaString(), ExecuteInline()
-       *
-       * @param array $sqlArray Array of SQL statements that will be applied rather than
-       *               the current schema.
-       * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
-       * @returns integer 0 if failure, 1 if errors, 2 if successful.
-       */
-       function ExecuteSchema( $sqlArray = NULL, $continueOnErr =  NULL ) {
-               if( !is_bool( $continueOnErr ) ) {
-                       $continueOnErr = $this->ContinueOnError();
-               }
-               
-               if( !isset( $sqlArray ) ) {
-                       $sqlArray = $this->sqlArray;
-               }
-               
-               if( !is_array( $sqlArray ) ) {
-                       $this->success = 0;
-               } else {
-                       $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
-               }
-               
-               return $this->success;
-       }
-       
-       /**
-       * Returns the current SQL array. 
-       *
-       * Call this method to fetch the array of SQL queries resulting from 
-       * ParseSchema() or ParseSchemaString(). 
-       *
-       * @param string $format Format: HTML, TEXT, or NONE (PHP array)
-       * @return array Array of SQL statements or FALSE if an error occurs
-       */
-       function PrintSQL( $format = 'NONE' ) {
-               $sqlArray = null;
-               return $this->getSQL( $format, $sqlArray );
-       }
-       
-       /**
-       * Saves the current SQL array to the local filesystem as a list of SQL queries.
-       *
-       * Call this method to save the array of SQL queries (generally resulting from a
-       * parsed XML schema) to the filesystem.
-       *
-       * @param string $filename Path and name where the file should be saved.
-       * @return boolean TRUE if save is successful, else FALSE. 
-       */
-       function SaveSQL( $filename = './schema.sql' ) {
-               
-               if( !isset( $sqlArray ) ) {
-                       $sqlArray = $this->sqlArray;
-               }
-               if( !isset( $sqlArray ) ) {
-                       return FALSE;
-               }
-               
-               $fp = fopen( $filename, "w" );
-               
-               foreach( $sqlArray as $key => $query ) {
-                       fwrite( $fp, $query . ";\n" );
-               }
-               fclose( $fp );
-       }
-       
-       /**
-       * Create an xml parser
-       *
-       * @return object PHP XML parser object
-       *
-       * @access private
-       */
-       function &create_parser() {
-               // Create the parser
-               $xmlParser = xml_parser_create();
-               xml_set_object( $xmlParser, $this );
-               
-               // Initialize the XML callback functions
-               xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
-               xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
-               
-               return $xmlParser;
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               switch( strtoupper( $tag ) ) {
-                       case 'TABLE':
-                               $this->obj = new dbTable( $this, $attributes );
-                               xml_set_object( $parser, $this->obj );
-                               break;
-                       case 'SQL':
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       $this->obj = new dbQuerySet( $this, $attributes );
-                                       xml_set_object( $parser, $this->obj );
-                               }
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-               
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       * @internal
-       */
-       function _tag_close( &$parser, $tag ) {
-               
-       }
-       
-       /**
-       * Converts an XML schema string to the specified DTD version.
-       *
-       * Call this method to convert a string containing an XML schema to a different AXMLS
-       * DTD version. For instance, to convert a schema created for an pre-1.0 version for 
-       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version 
-       * parameter is specified, the schema will be converted to the current DTD version. 
-       * If the newFile parameter is provided, the converted schema will be written to the specified
-       * file.
-       * @see ConvertSchemaFile()
-       *
-       * @param string $schema String containing XML schema that will be converted.
-       * @param string $newVersion DTD version to convert to.
-       * @param string $newFile File name of (converted) output file.
-       * @return string Converted XML schema or FALSE if an error occurs.
-       */
-       function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
-               
-               // grab current version
-               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
-                       return FALSE;
-               }
-               
-               if( !isset ($newVersion) ) {
-                       $newVersion = $this->schemaVersion;
-               }
-               
-               if( $version == $newVersion ) {
-                       $result = $schema;
-               } else {
-                       $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
-               }
-               
-               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
-                       fwrite( $fp, $result );
-                       fclose( $fp );
-               }
-               
-               return $result;
-       }
-       
-       // compat for pre-4.3 - jlim
-       function _file_get_contents($path)
-       {
-               if (function_exists('file_get_contents')) return file_get_contents($path);
-               return join('',file($path));
-       }
-       
-       /**
-       * Converts an XML schema file to the specified DTD version.
-       *
-       * Call this method to convert the specified XML schema file to a different AXMLS
-       * DTD version. For instance, to convert a schema created for an pre-1.0 version for 
-       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version 
-       * parameter is specified, the schema will be converted to the current DTD version. 
-       * If the newFile parameter is provided, the converted schema will be written to the specified
-       * file.
-       * @see ConvertSchemaString()
-       *
-       * @param string $filename Name of XML schema file that will be converted.
-       * @param string $newVersion DTD version to convert to.
-       * @param string $newFile File name of (converted) output file.
-       * @return string Converted XML schema or FALSE if an error occurs.
-       */
-       function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
-               
-               // grab current version
-               if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
-                       return FALSE;
-               }
-               
-               if( !isset ($newVersion) ) {
-                       $newVersion = $this->schemaVersion;
-               }
-               
-               if( $version == $newVersion ) {
-                       $result = _file_get_contents( $filename );
-                       
-                       // remove unicode BOM if present
-                       if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
-                               $result = substr( $result, 3 );
-                       }
-               } else {
-                       $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
-               }
-               
-               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
-                       fwrite( $fp, $result );
-                       fclose( $fp );
-               }
-               
-               return $result;
-       }
-       
-       function TransformSchema( $schema, $xsl, $schematype='string' )
-       {
-               // Fail if XSLT extension is not available
-               if( ! function_exists( 'xslt_create' ) ) {
-                       return FALSE;
-               }
-               
-               $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
-               
-               // look for xsl
-               if( !is_readable( $xsl_file ) ) {
-                       return FALSE;
-               }
-               
-               switch( $schematype )
-               {
-                       case 'file':
-                               if( !is_readable( $schema ) ) {
-                                       return FALSE;
-                               }
-                               
-                               $schema = _file_get_contents( $schema );
-                               break;
-                       case 'string':
-                       default:
-                               if( !is_string( $schema ) ) {
-                                       return FALSE;
-                               }
-               }
-               
-               $arguments = array (
-                       '/_xml' => $schema,
-                       '/_xsl' => _file_get_contents( $xsl_file )
-               );
-               
-               // create an XSLT processor
-               $xh = xslt_create ();
-               
-               // set error handler
-               xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
-               
-               // process the schema
-               $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); 
-               
-               xslt_free ($xh);
-               
-               return $result;
-       }
-       
-       /**
-       * Processes XSLT transformation errors
-       *
-       * @param object $parser XML parser object
-       * @param integer $errno Error number
-       * @param integer $level Error level
-       * @param array $fields Error information fields
-       *
-       * @access private
-       */
-       function xslt_error_handler( $parser, $errno, $level, $fields ) {
-               if( is_array( $fields ) ) {
-                       $msg = array(
-                               'Message Type' => ucfirst( $fields['msgtype'] ),
-                               'Message Code' => $fields['code'],
-                               'Message' => $fields['msg'],
-                               'Error Number' => $errno,
-                               'Level' => $level
-                       );
-                       
-                       switch( $fields['URI'] ) {
-                               case 'arg:/_xml':
-                                       $msg['Input'] = 'XML';
-                                       break;
-                               case 'arg:/_xsl':
-                                       $msg['Input'] = 'XSL';
-                                       break;
-                               default:
-                                       $msg['Input'] = $fields['URI'];
-                       }
-                       
-                       $msg['Line'] = $fields['line'];
-               } else {
-                       $msg = array(
-                               'Message Type' => 'Error',
-                               'Error Number' => $errno,
-                               'Level' => $level,
-                               'Fields' => var_export( $fields, TRUE )
-                       );
-               }
-               
-               $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
-                                          . '<table>' . "\n";
-               
-               foreach( $msg as $label => $details ) {
-                       $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
-               }
-               
-               $error_details .= '</table>';
-               
-               trigger_error( $error_details, E_USER_ERROR );
-       }
-       
-       /**
-       * Returns the AXMLS Schema Version of the requested XML schema file.
-       *
-       * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
-       * @see SchemaStringVersion()
-       *
-       * @param string $filename AXMLS schema file
-       * @return string Schema version number or FALSE on error
-       */
-       function SchemaFileVersion( $filename ) {
-               // Open the file
-               if( !($fp = fopen( $filename, 'r' )) ) {
-                       // die( 'Unable to open file' );
-                       return FALSE;
-               }
-               
-               // Process the file
-               while( $data = fread( $fp, 4096 ) ) {
-                       if( preg_match( $this->versionRegex, $data, $matches ) ) {
-                               return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
-                       }
-               }
-               
-               return FALSE;
-       }
-       
-       /**
-       * Returns the AXMLS Schema Version of the provided XML schema string.
-       *
-       * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
-       * @see SchemaFileVersion()
-       *
-       * @param string $xmlstring XML schema string
-       * @return string Schema version number or FALSE on error
-       */
-       function SchemaStringVersion( $xmlstring ) {
-               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
-                       return FALSE;
-               }
-               
-               if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
-                       return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
-               }
-               
-               return FALSE;
-       }
-       
-       /**
-       * Extracts an XML schema from an existing database.
-       *
-       * Call this method to create an XML schema string from an existing database.
-       * If the data parameter is set to TRUE, AXMLS will include the data from the database
-       * in the schema. 
-       *
-       * @param boolean $data Include data in schema dump
-       * @return string Generated XML schema
-       */
-       function ExtractSchema( $data = FALSE ) {
-               $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
-               
-               $schema = '<?xml version="1.0"?>' . "\n"
-                               . '<schema version="' . $this->schemaVersion . '">' . "\n";
-               
-               if( is_array( $tables = $this->db->MetaTables( 'TABLES' ) ) ) {
-                       foreach( $tables as $table ) {
-                               $schema .= '    <table name="' . $table . '">' . "\n";
-                               
-                               // grab details from database
-                               $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' );
-                               $fields = $this->db->MetaColumns( $table );
-                               $indexes = $this->db->MetaIndexes( $table );
-                               
-                               if( is_array( $fields ) ) {
-                                       foreach( $fields as $details ) {
-                                               $extra = '';
-                                               $content = array();
-                                               
-                                               if( $details->max_length > 0 ) {
-                                                       $extra .= ' size="' . $details->max_length . '"';
-                                               }
-                                               
-                                               if( $details->primary_key ) {
-                                                       $content[] = '<KEY/>';
-                                               } elseif( $details->not_null ) {
-                                                       $content[] = '<NOTNULL/>';
-                                               }
-                                               
-                                               if( $details->has_default ) {
-                                                       $content[] = '<DEFAULT value="' . $details->default_value . '"/>';
-                                               }
-                                               
-                                               if( $details->auto_increment ) {
-                                                       $content[] = '<AUTOINCREMENT/>';
-                                               }
-                                               
-                                               // this stops the creation of 'R' columns,
-                                               // AUTOINCREMENT is used to create auto columns
-                                               $details->primary_key = 0;
-                                               $type = $rs->MetaType( $details );
-                                               
-                                               $schema .= '            <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>';
-                                               
-                                               if( !empty( $content ) ) {
-                                                       $schema .= "\n                  " . implode( "\n                        ", $content ) . "\n             ";
-                                               }
-                                               
-                                               $schema .= '</field>' . "\n";
-                                       }
-                               }
-                               
-                               if( is_array( $indexes ) ) {
-                                       foreach( $indexes as $index => $details ) {
-                                               $schema .= '            <index name="' . $index . '">' . "\n";
-                                               
-                                               if( $details['unique'] ) {
-                                                       $schema .= '                    <UNIQUE/>' . "\n";
-                                               }
-                                               
-                                               foreach( $details['columns'] as $column ) {
-                                                       $schema .= '                    <col>' . $column . '</col>' . "\n";
-                                               }
-                                               
-                                               $schema .= '            </index>' . "\n";
-                                       }
-                               }
-                               
-                               if( $data ) {
-                                       $rs = $this->db->Execute( 'SELECT * FROM ' . $table );
-                                       
-                                       if( is_object( $rs ) ) {
-                                               $schema .= '            <data>' . "\n";
-                                               
-                                               while( $row = $rs->FetchRow() ) {
-                                                       foreach( $row as $key => $val ) {
-                                                               $row[$key] = htmlentities($val);
-                                                       }
-                                                       
-                                                       $schema .= '                    <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";
-                                               }
-                                               
-                                               $schema .= '            </data>' . "\n";
-                                       }
-                               }
-                               
-                               $schema .= '    </table>' . "\n";
-                       }
-               }
-               
-               $this->db->SetFetchMode( $old_mode );
-               
-               $schema .= '</schema>';
-               return $schema;
-       }
-       
-       /**
-       * Sets a prefix for database objects
-       *
-       * Call this method to set a standard prefix that will be prepended to all database tables 
-       * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
-       *
-       * @param string $prefix Prefix that will be prepended.
-       * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
-       * @return boolean TRUE if successful, else FALSE
-       */
-       function SetPrefix( $prefix = '', $underscore = TRUE ) {
-               switch( TRUE ) {
-                       // clear prefix
-                       case empty( $prefix ):
-                               logMsg( 'Cleared prefix' );
-                               $this->objectPrefix = '';
-                               return TRUE;
-                       // prefix too long
-                       case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
-                       // prefix contains invalid characters
-                       case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
-                               logMsg( 'Invalid prefix: ' . $prefix );
-                               return FALSE;
-               }
-               
-               if( $underscore AND substr( $prefix, -1 ) != '_' ) {
-                       $prefix .= '_';
-               }
-               
-               // prefix valid
-               logMsg( 'Set prefix: ' . $prefix );
-               $this->objectPrefix = $prefix;
-               return TRUE;
-       }
-       
-       /**
-       * Returns an object name with the current prefix prepended.
-       *
-       * @param string $name Name
-       * @return string        Prefixed name
-       *
-       * @access private
-       */
-       function prefix( $name = '' ) {
-               // if prefix is set
-               if( !empty( $this->objectPrefix ) ) {
-                       // Prepend the object prefix to the table name
-                       // prepend after quote if used
-                       return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
-               }
-               
-               // No prefix set. Use name provided.
-               return $name;
-       }
-       
-       /**
-       * Checks if element references a specific platform
-       *
-       * @param string $platform Requested platform
-       * @returns boolean TRUE if platform check succeeds
-       *
-       * @access private
-       */
-       function supportedPlatform( $platform = NULL ) {
-               $regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';
-               
-               if( !isset( $platform ) OR preg_match( $regex, $platform ) ) {
-                       logMsg( "Platform $platform is supported" );
-                       return TRUE;
-               } else {
-                       logMsg( "Platform $platform is NOT supported" );
-                       return FALSE;
-               }
-       }
-       
-       /**
-       * Clears the array of generated SQL.
-       *
-       * @access private
-       */
-       function clearSQL() {
-               $this->sqlArray = array();
-       }
-       
-       /**
-       * Adds SQL into the SQL array.
-       *
-       * @param mixed $sql SQL to Add
-       * @return boolean TRUE if successful, else FALSE.
-       *
-       * @access private
-       */      
-       function addSQL( $sql = NULL ) {
-               if( is_array( $sql ) ) {
-                       foreach( $sql as $line ) {
-                               $this->addSQL( $line );
-                       }
-                       
-                       return TRUE;
-               }
-               
-               if( is_string( $sql ) ) {
-                       $this->sqlArray[] = $sql;
-                       
-                       // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
-                       if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
-                               $saved = $this->db->debug;
-                               $this->db->debug = $this->debug;
-                               $ok = $this->db->Execute( $sql );
-                               $this->db->debug = $saved;
-                               
-                               if( !$ok ) {
-                                       if( $this->debug ) {
-                                               ADOConnection::outp( $this->db->ErrorMsg() );
-                                       }
-                                       
-                                       $this->success = 1;
-                               }
-                       }
-                       
-                       return TRUE;
-               }
-               
-               return FALSE;
-       }
-       
-       /**
-       * Gets the SQL array in the specified format.
-       *
-       * @param string $format Format
-       * @return mixed SQL
-       *       
-       * @access private
-       */
-       function getSQL( $format = NULL, $sqlArray = NULL ) {
-               if( !is_array( $sqlArray ) ) {
-                       $sqlArray = $this->sqlArray;
-               }
-               
-               if( !is_array( $sqlArray ) ) {
-                       return FALSE;
-               }
-               
-               switch( strtolower( $format ) ) {
-                       case 'string':
-                       case 'text':
-                               return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
-                       case'html':
-                               return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
-               }
-               
-               return $this->sqlArray;
-       }
-       
-       /**
-       * Destroys an adoSchema object.
-       *
-       * Call this method to clean up after an adoSchema object that is no longer in use.
-       * @deprecated adoSchema now cleans up automatically.
-       */
-       function Destroy() {
-               set_magic_quotes_runtime( $this->mgq );
-               unset( $this );
-       }
-}
-
-/**
-* Message logging function
-*
-* @access private
-*/
-function logMsg( $msg, $title = NULL, $force = FALSE ) {
-       if( XMLS_DEBUG or $force ) {
-               echo '<pre>';
-               
-               if( isset( $title ) ) {
-                       echo '<h3>' . htmlentities( $title ) . '</h3>';
-               }
-               
-               if( is_object( $this ) ) {
-                       echo '[' . get_class( $this ) . '] ';
-               }
-               
-               print_r( $msg );
-               
-               echo '</pre>';
-       }
-}
+<?php\r
+// Copyright (c) 2004 ars Cognita Inc., all rights reserved\r
+/* ******************************************************************************\r
+    Released under both BSD license and Lesser GPL library license. \r
+       Whenever there is any discrepancy between the two licenses, \r
+       the BSD license will take precedence. \r
+*******************************************************************************/\r
+/**\r
+ * xmlschema is a class that allows the user to quickly and easily\r
+ * build a database on any ADOdb-supported platform using a simple\r
+ * XML schema.\r
+ *\r
+ * Last Editor: $Author$\r
+ * @author Richard Tango-Lowy & Dan Cech\r
+ * @version $Revision$\r
+ *\r
+ * @package axmls\r
+ * @tutorial getting_started.pkg\r
+ */\r
\r
+function _file_get_contents($file) \r
+{\r
+       if (function_exists('file_get_contents')) return file_get_contents($file);\r
+       \r
+       $f = fopen($file,'r');\r
+       if (!$f) return '';\r
+       $t = '';\r
+       \r
+       while ($s = fread($f,100000)) $t .= $s;\r
+       fclose($f);\r
+       return $t;\r
+}\r
+\r
+\r
+/**\r
+* Debug on or off\r
+*/\r
+if( !defined( 'XMLS_DEBUG' ) ) {\r
+       define( 'XMLS_DEBUG', FALSE );\r
+}\r
+\r
+/**\r
+* Default prefix key\r
+*/\r
+if( !defined( 'XMLS_PREFIX' ) ) {\r
+       define( 'XMLS_PREFIX', '%%P' );\r
+}\r
+\r
+/**\r
+* Maximum length allowed for object prefix\r
+*/\r
+if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {\r
+       define( 'XMLS_PREFIX_MAXLEN', 10 );\r
+}\r
+\r
+/**\r
+* Execute SQL inline as it is generated\r
+*/\r
+if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {\r
+       define( 'XMLS_EXECUTE_INLINE', FALSE );\r
+}\r
+\r
+/**\r
+* Continue SQL Execution if an error occurs?\r
+*/\r
+if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {\r
+       define( 'XMLS_CONTINUE_ON_ERROR', FALSE );\r
+}\r
+\r
+/**\r
+* Current Schema Version\r
+*/\r
+if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {\r
+       define( 'XMLS_SCHEMA_VERSION', '0.2' );\r
+}\r
+\r
+/**\r
+* Default Schema Version.  Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {\r
+       define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );\r
+}\r
+\r
+/**\r
+* Default Schema Version.  Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {\r
+       define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );\r
+}\r
+\r
+/**\r
+* Include the main ADODB library\r
+*/\r
+if( !defined( '_ADODB_LAYER' ) ) {\r
+       require( 'adodb.inc.php' );\r
+       require( 'adodb-datadict.inc.php' );\r
+}\r
+\r
+/**\r
+* Abstract DB Object. This class provides basic methods for database objects, such\r
+* as tables and indexes.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbObject {\r
+       \r
+       /**\r
+       * var object Parent\r
+       */\r
+       var $parent;\r
+       \r
+       /**\r
+       * var string current element\r
+       */\r
+       var $currentElement;\r
+       \r
+       /**\r
+       * NOP\r
+       */\r
+       function dbObject( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               \r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               \r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               \r
+       }\r
+       \r
+       function create() {\r
+               return array();\r
+       }\r
+       \r
+       /**\r
+       * Destroys the object\r
+       */\r
+       function destroy() {\r
+               unset( $this );\r
+       }\r
+       \r
+       /**\r
+       * Checks whether the specified RDBMS is supported by the current\r
+       * database object or its ranking ancestor.\r
+       *\r
+       * @param string $platform RDBMS platform name (from ADODB platform list).\r
+       * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.\r
+       */\r
+       function supportedPlatform( $platform = NULL ) {\r
+               return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;\r
+       }\r
+       \r
+       /**\r
+       * Returns the prefix set by the ranking ancestor of the database object.\r
+       *\r
+       * @param string $name Prefix string.\r
+       * @return string Prefix.\r
+       */\r
+       function prefix( $name = '' ) {\r
+               return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;\r
+       }\r
+       \r
+       /**\r
+       * Extracts a field ID from the specified field.\r
+       *\r
+       * @param string $field Field.\r
+       * @return string Field ID.\r
+       */\r
+       function FieldID( $field ) {\r
+               return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );\r
+       }\r
+}\r
+\r
+/**\r
+* Creates a table object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database table. As charactaristics\r
+* of the table are loaded from the external source, methods and properties\r
+* of this class are used to build up the table description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbTable extends dbObject {\r
+       \r
+       /**\r
+       * @var string Table name\r
+       */\r
+       var $name;\r
+       \r
+       /**\r
+       * @var array Field specifier: Meta-information about each field\r
+       */\r
+       var $fields = array();\r
+       \r
+       /**\r
+       * @var array List of table indexes.\r
+       */\r
+       var $indexes = array();\r
+       \r
+       /**\r
+       * @var array Table options: Table-level options\r
+       */\r
+       var $opts = array();\r
+       \r
+       /**\r
+       * @var string Field index: Keeps track of which field is currently being processed\r
+       */\r
+       var $current_field;\r
+       \r
+       /**\r
+       * @var boolean Mark table for destruction\r
+       * @access private\r
+       */\r
+       var $drop_table;\r
+       \r
+       /**\r
+       * @var boolean Mark field for destruction (not yet implemented)\r
+       * @access private\r
+       */\r
+       var $drop_field = array();\r
+       \r
+       /**\r
+       * Iniitializes a new table object.\r
+       *\r
+       * @param string $prefix DB Object prefix\r
+       * @param array $attributes Array of table attributes.\r
+       */\r
+       function dbTable( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+               $this->name = $this->prefix($attributes['NAME']);\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements. Elements currently \r
+       * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT. \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'INDEX':\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       xml_set_object( $parser, $this->addIndex( $attributes ) );\r
+                               }\r
+                               break;\r
+                       case 'DATA':\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       xml_set_object( $parser, $this->addData( $attributes ) );\r
+                               }\r
+                               break;\r
+                       case 'DROP':\r
+                               $this->drop();\r
+                               break;\r
+                       case 'FIELD':\r
+                               // Add a field\r
+                               $fieldName = $attributes['NAME'];\r
+                               $fieldType = $attributes['TYPE'];\r
+                               $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;\r
+                               $fieldOpts = isset( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;\r
+                               \r
+                               $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );\r
+                               break;\r
+                       case 'KEY':\r
+                       case 'NOTNULL':\r
+                       case 'AUTOINCREMENT':\r
+                               // Add a field option\r
+                               $this->addFieldOpt( $this->current_field, $this->currentElement );\r
+                               break;\r
+                       case 'DEFAULT':\r
+                               // Add a field option to the table object\r
+                               \r
+                               // Work around ADOdb datadict issue that misinterprets empty strings.\r
+                               if( $attributes['VALUE'] == '' ) {\r
+                                       $attributes['VALUE'] = " '' ";\r
+                               }\r
+                               \r
+                               $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );\r
+                               break;\r
+                       case 'DEFDATE':\r
+                       case 'DEFTIMESTAMP':\r
+                               // Add a field option to the table object\r
+                               $this->addFieldOpt( $this->current_field, $this->currentElement );\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Table constraint\r
+                       case 'CONSTRAINT':\r
+                               if( isset( $this->current_field ) ) {\r
+                                       $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );\r
+                               } else {\r
+                                       $this->addTableOpt( $cdata );\r
+                               }\r
+                               break;\r
+                       // Table option\r
+                       case 'OPT':\r
+                               $this->addTableOpt( $cdata );\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'TABLE':\r
+                               $this->parent->addSQL( $this->create( $this->parent ) );\r
+                               xml_set_object( $parser, $this->parent );\r
+                               $this->destroy();\r
+                               break;\r
+                       case 'FIELD':\r
+                               unset($this->current_field);\r
+                               break;\r
+\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds an index to a table object\r
+       *\r
+       * @param array $attributes Index attributes\r
+       * @return object dbIndex object\r
+       */\r
+       function addIndex( $attributes ) {\r
+               $name = strtoupper( $attributes['NAME'] );\r
+               $this->indexes[$name] = new dbIndex( $this, $attributes );\r
+               return $this->indexes[$name];\r
+       }\r
+       \r
+       /**\r
+       * Adds data to a table object\r
+       *\r
+       * @param array $attributes Data attributes\r
+       * @return object dbData object\r
+       */\r
+       function addData( $attributes ) {\r
+               if( !isset( $this->data ) ) {\r
+                       $this->data = new dbData( $this, $attributes );\r
+               }\r
+               return $this->data;\r
+       }\r
+       \r
+       /**\r
+       * Adds a field to a table object\r
+       *\r
+       * $name is the name of the table to which the field should be added. \r
+       * $type is an ADODB datadict field type. The following field types\r
+       * are supported as of ADODB 3.40:\r
+       *       - C:  varchar\r
+       *       - X:  CLOB (character large object) or largest varchar size\r
+       *          if CLOB is not supported\r
+       *       - C2: Multibyte varchar\r
+       *       - X2: Multibyte CLOB\r
+       *       - B:  BLOB (binary large object)\r
+       *       - D:  Date (some databases do not support this, and we return a datetime type)\r
+       *       - T:  Datetime or Timestamp\r
+       *       - L:  Integer field suitable for storing booleans (0 or 1)\r
+       *       - I:  Integer (mapped to I4)\r
+       *       - I1: 1-byte integer\r
+       *       - I2: 2-byte integer\r
+       *       - I4: 4-byte integer\r
+       *       - I8: 8-byte integer\r
+       *       - F:  Floating point number\r
+       *       - N:  Numeric or decimal number\r
+       *\r
+       * @param string $name Name of the table to which the field will be added.\r
+       * @param string $type   ADODB datadict field type.\r
+       * @param string $size   Field size\r
+       * @param array $opts    Field options array\r
+       * @return array Field specifier array\r
+       */\r
+       function addField( $name, $type, $size = NULL, $opts = NULL ) {\r
+               $field_id = $this->FieldID( $name );\r
+               \r
+               // Set the field index so we know where we are\r
+               $this->current_field = $field_id;\r
+               \r
+               // Set the field name (required)\r
+               $this->fields[$field_id]['NAME'] = $name;\r
+               \r
+               // Set the field type (required)\r
+               $this->fields[$field_id]['TYPE'] = $type;\r
+               \r
+               // Set the field size (optional)\r
+               if( isset( $size ) ) {\r
+                       $this->fields[$field_id]['SIZE'] = $size;\r
+               }\r
+               \r
+               // Set the field options\r
+               if( isset( $opts ) ) {\r
+                       $this->fields[$field_id]['OPTS'][] = $opts;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds a field option to the current field specifier\r
+       *\r
+       * This method adds a field option allowed by the ADOdb datadict \r
+       * and appends it to the given field.\r
+       *\r
+       * @param string $field  Field name\r
+       * @param string $opt ADOdb field option\r
+       * @param mixed $value Field option value\r
+       * @return array Field specifier array\r
+       */\r
+       function addFieldOpt( $field, $opt, $value = NULL ) {\r
+               if( !isset( $value ) ) {\r
+                       $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;\r
+               // Add the option and value\r
+               } else {\r
+                       $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds an option to the table\r
+       *\r
+       * This method takes a comma-separated list of table-level options\r
+       * and appends them to the table object.\r
+       *\r
+       * @param string $opt Table option\r
+       * @return array Options\r
+       */\r
+       function addTableOpt( $opt ) {\r
+               $this->opts[] = $opt;\r
+               \r
+               return $this->opts;\r
+       }\r
+       \r
+       /**\r
+       * Generates the SQL that will create the table in the database\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Array containing table creation SQL\r
+       */\r
+       function create( &$xmls ) {\r
+               $sql = array();\r
+               \r
+               // drop any existing indexes\r
+               if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {\r
+                       foreach( $legacy_indexes as $index => $index_details ) {\r
+                               $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );\r
+                       }\r
+               }\r
+               \r
+               // remove fields to be dropped from table object\r
+               foreach( $this->drop_field as $field ) {\r
+                       unset( $this->fields[$field] );\r
+               }\r
+               \r
+               // if table exists\r
+               if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {\r
+                       // drop table\r
+                       if( $this->drop_table ) {\r
+                               $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+                               \r
+                               return $sql;\r
+                       }\r
+                       \r
+                       // drop any existing fields not in schema\r
+                       foreach( $legacy_fields as $field_id => $field ) {\r
+                               if( !isset( $this->fields[$field_id] ) ) {\r
+                                       $sql[] = $xmls->dict->DropColumnSQL( $this->name, '`'.$field->name.'`' );\r
+                               }\r
+                       }\r
+               // if table doesn't exist\r
+               } else {\r
+                       if( $this->drop_table ) {\r
+                               return $sql;\r
+                       }\r
+                       \r
+                       $legacy_fields = array();\r
+               }\r
+               \r
+               // Loop through the field specifier array, building the associative array for the field options\r
+               $fldarray = array();\r
+               \r
+               foreach( $this->fields as $field_id => $finfo ) {\r
+                       // Set an empty size if it isn't supplied\r
+                       if( !isset( $finfo['SIZE'] ) ) {\r
+                               $finfo['SIZE'] = '';\r
+                       }\r
+                       \r
+                       // Initialize the field array with the type and size\r
+                       $fldarray[$field_id] = array(\r
+                               'NAME' => $finfo['NAME'],\r
+                               'TYPE' => $finfo['TYPE'],\r
+                               'SIZE' => $finfo['SIZE']\r
+                       );\r
+                       \r
+                       // Loop through the options array and add the field options. \r
+                       if( isset( $finfo['OPTS'] ) ) {\r
+                               foreach( $finfo['OPTS'] as $opt ) {\r
+                                       // Option has an argument.\r
+                                       if( is_array( $opt ) ) {\r
+                                               $key = key( $opt );\r
+                                               $value = $opt[key( $opt )];\r
+                                               @$fldarray[$field_id][$key] .= $value;\r
+                                       // Option doesn't have arguments\r
+                                       } else {\r
+                                               $fldarray[$field_id][$opt] = $opt;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               if( empty( $legacy_fields ) ) {\r
+                       // Create the new table\r
+                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+                       logMsg( end( $sql ), 'Generated CreateTableSQL' );\r
+               } else {\r
+                       // Upgrade an existing table\r
+                       logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );\r
+                       switch( $xmls->upgrade ) {\r
+                               // Use ChangeTableSQL\r
+                               case 'ALTER':\r
+                                       logMsg( 'Generated ChangeTableSQL (ALTERing table)' );\r
+                                       $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );\r
+                                       break;\r
+                               case 'REPLACE':\r
+                                       logMsg( 'Doing upgrade REPLACE (testing)' );\r
+                                       $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+                                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+                                       break;\r
+                               // ignore table\r
+                               default:\r
+                                       return array();\r
+                       }\r
+               }\r
+               \r
+               foreach( $this->indexes as $index ) {\r
+                       $sql[] = $index->create( $xmls );\r
+               }\r
+               \r
+               if( isset( $this->data ) ) {\r
+                       $sql[] = $this->data->create( $xmls );\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+       \r
+       /**\r
+       * Marks a field or table for destruction\r
+       */\r
+       function drop() {\r
+               if( isset( $this->current_field ) ) {\r
+                       // Drop the current field\r
+                       logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );\r
+                       // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );\r
+                       $this->drop_field[$this->current_field] = $this->current_field;\r
+               } else {\r
+                       // Drop the current table\r
+                       logMsg( "Dropping table '{$this->name}'" );\r
+                       // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );\r
+                       $this->drop_table = TRUE;\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+* Creates an index object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database index. As charactaristics\r
+* of the index are loaded from the external source, methods and properties\r
+* of this class are used to build up the index description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbIndex extends dbObject {\r
+       \r
+       /**\r
+       * @var string   Index name\r
+       */\r
+       var $name;\r
+       \r
+       /**\r
+       * @var array    Index options: Index-level options\r
+       */\r
+       var $opts = array();\r
+       \r
+       /**\r
+       * @var array    Indexed fields: Table columns included in this index\r
+       */\r
+       var $columns = array();\r
+       \r
+       /**\r
+       * @var boolean Mark index for destruction\r
+       * @access private\r
+       */\r
+       var $drop = FALSE;\r
+       \r
+       /**\r
+       * Initializes the new dbIndex object.\r
+       *\r
+       * @param object $parent Parent object\r
+       * @param array $attributes Attributes\r
+       *\r
+       * @internal\r
+       */\r
+       function dbIndex( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+               \r
+               $this->name = $this->prefix ($attributes['NAME']);\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * Processes XML opening tags. \r
+       * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'DROP':\r
+                               $this->drop();\r
+                               break;\r
+                       case 'CLUSTERED':\r
+                       case 'BITMAP':\r
+                       case 'UNIQUE':\r
+                       case 'FULLTEXT':\r
+                       case 'HASH':\r
+                               // Add index Option\r
+                               $this->addIndexOpt( $this->currentElement );\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * Processes XML cdata.\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Index field name\r
+                       case 'COL':\r
+                               $this->addField( $cdata );\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'INDEX':\r
+                               xml_set_object( $parser, $this->parent );\r
+                               break;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds a field to the index\r
+       *\r
+       * @param string $name Field name\r
+       * @return string Field list\r
+       */\r
+       function addField( $name ) {\r
+               $this->columns[$this->FieldID( $name )] = $name;\r
+               \r
+               // Return the field list\r
+               return $this->columns;\r
+       }\r
+       \r
+       /**\r
+       * Adds options to the index\r
+       *\r
+       * @param string $opt Comma-separated list of index options.\r
+       * @return string Option list\r
+       */\r
+       function addIndexOpt( $opt ) {\r
+               $this->opts[] = $opt;\r
+               \r
+               // Return the options list\r
+               return $this->opts;\r
+       }\r
+       \r
+       /**\r
+       * Generates the SQL that will create the index in the database\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Array containing index creation SQL\r
+       */\r
+       function create( &$xmls ) {\r
+               if( $this->drop ) {\r
+                       return NULL;\r
+               }\r
+               \r
+               // eliminate any columns that aren't in the table\r
+               foreach( $this->columns as $id => $col ) {\r
+                       if( !isset( $this->parent->fields[$id] ) ) {\r
+                               unset( $this->columns[$id] );\r
+                       }\r
+               }\r
+               \r
+               return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );\r
+       }\r
+       \r
+       /**\r
+       * Marks an index for destruction\r
+       */\r
+       function drop() {\r
+               $this->drop = TRUE;\r
+       }\r
+}\r
+\r
+/**\r
+* Creates a data object in ADOdb's datadict format\r
+*\r
+* This class stores information about table data.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbData extends dbObject {\r
+       \r
+       var $data = array();\r
+       \r
+       var $row;\r
+       \r
+       /**\r
+       * Initializes the new dbIndex object.\r
+       *\r
+       * @param object $parent Parent object\r
+       * @param array $attributes Attributes\r
+       *\r
+       * @internal\r
+       */\r
+       function dbData( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * Processes XML opening tags. \r
+       * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'ROW':\r
+                               $this->row = count( $this->data );\r
+                               $this->data[$this->row] = array();\r
+                               break;\r
+                       case 'F':\r
+                               $this->addField($attributes);\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * Processes XML cdata.\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Index field name\r
+                       case 'F':\r
+                               $this->addData( $cdata );\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'DATA':\r
+                               xml_set_object( $parser, $this->parent );\r
+                               break;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds a field to the index\r
+       *\r
+       * @param string $name Field name\r
+       * @return string Field list\r
+       */\r
+       function addField( $attributes ) {\r
+               if( isset( $attributes['NAME'] ) ) {\r
+                       $name = $attributes['NAME'];\r
+               } else {\r
+                       $name = count($this->data[$this->row]);\r
+               }\r
+               \r
+               // Set the field index so we know where we are\r
+               $this->current_field = $this->FieldID( $name );\r
+       }\r
+       \r
+       /**\r
+       * Adds options to the index\r
+       *\r
+       * @param string $opt Comma-separated list of index options.\r
+       * @return string Option list\r
+       */\r
+       function addData( $cdata ) {\r
+               if( !isset( $this->data[$this->row] ) ) {\r
+                       $this->data[$this->row] = array();\r
+               }\r
+               \r
+               if( !isset( $this->data[$this->row][$this->current_field] ) ) {\r
+                       $this->data[$this->row][$this->current_field] = '';\r
+               }\r
+               \r
+               $this->data[$this->row][$this->current_field] .= $cdata;\r
+       }\r
+       \r
+       /**\r
+       * Generates the SQL that will create the index in the database\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Array containing index creation SQL\r
+       */\r
+       function create( &$xmls ) {\r
+               $table = $xmls->dict->TableName($this->parent->name);\r
+               $table_field_count = count($this->parent->fields);\r
+               $sql = array();\r
+               \r
+               // eliminate any columns that aren't in the table\r
+               foreach( $this->data as $row ) {\r
+                       $table_fields = $this->parent->fields;\r
+                       $fields = array();\r
+                       \r
+                       foreach( $row as $field_id => $field_data ) {\r
+                               if( !array_key_exists( $field_id, $table_fields ) ) {\r
+                                       if( is_numeric( $field_id ) ) {\r
+                                               $field_id = reset( array_keys( $table_fields ) );\r
+                                       } else {\r
+                                               continue;\r
+                                       }\r
+                               }\r
+                               \r
+                               $name = $table_fields[$field_id]['NAME'];\r
+                               \r
+                               switch( $table_fields[$field_id]['TYPE'] ) {\r
+                                       case 'C':\r
+                                       case 'C2':\r
+                                       case 'X':\r
+                                       case 'X2':\r
+                                               $fields[$name] = $xmls->db->qstr( $field_data );\r
+                                               break;\r
+                                       case 'I':\r
+                                       case 'I1':\r
+                                       case 'I2':\r
+                                       case 'I4':\r
+                                       case 'I8':\r
+                                               $fields[$name] = intval($field_data);\r
+                                               break;\r
+                                       default:\r
+                                               $fields[$name] = $field_data;\r
+                               }\r
+                               \r
+                               unset($table_fields[$field_id]);\r
+                       }\r
+                       \r
+                       // check that at least 1 column is specified\r
+                       if( empty( $fields ) ) {\r
+                               continue;\r
+                       }\r
+                       \r
+                       // check that no required columns are missing\r
+                       if( count( $fields ) < $table_field_count ) {\r
+                               foreach( $table_fields as $field ) {\r
+                                       if (isset( $field['OPTS'] ))\r
+                                               if( ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {\r
+                                                       continue(2);\r
+                                               }\r
+                               }\r
+                       }\r
+                       \r
+                       $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+}\r
+\r
+/**\r
+* Creates the SQL to execute a list of provided SQL queries\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbQuerySet extends dbObject {\r
+       \r
+       /**\r
+       * @var array    List of SQL queries\r
+       */\r
+       var $queries = array();\r
+       \r
+       /**\r
+       * @var string   String used to build of a query line by line\r
+       */\r
+       var $query;\r
+       \r
+       /**\r
+       * @var string   Query prefix key\r
+       */\r
+       var $prefixKey = '';\r
+       \r
+       /**\r
+       * @var boolean  Auto prefix enable (TRUE)\r
+       */\r
+       var $prefixMethod = 'AUTO';\r
+       \r
+       /**\r
+       * Initializes the query set.\r
+       *\r
+       * @param object $parent Parent object\r
+       * @param array $attributes Attributes\r
+       */\r
+       function dbQuerySet( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+                       \r
+               // Overrides the manual prefix key\r
+               if( isset( $attributes['KEY'] ) ) {\r
+                       $this->prefixKey = $attributes['KEY'];\r
+               }\r
+               \r
+               $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';\r
+               \r
+               // Enables or disables automatic prefix prepending\r
+               switch( $prefixMethod ) {\r
+                       case 'AUTO':\r
+                               $this->prefixMethod = 'AUTO';\r
+                               break;\r
+                       case 'MANUAL':\r
+                               $this->prefixMethod = 'MANUAL';\r
+                               break;\r
+                       case 'NONE':\r
+                               $this->prefixMethod = 'NONE';\r
+                               break;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements. Elements currently \r
+       * processed are: QUERY. \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'QUERY':\r
+                               // Create a new query in a SQL queryset.\r
+                               // Ignore this query set if a platform is specified and it's different than the \r
+                               // current connection platform.\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       $this->newQuery();\r
+                               } else {\r
+                                       $this->discardQuery();\r
+                               }\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Line of queryset SQL data\r
+                       case 'QUERY':\r
+                               $this->buildQuery( $cdata );\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'QUERY':\r
+                               // Add the finished query to the open query set.\r
+                               $this->addQuery();\r
+                               break;\r
+                       case 'SQL':\r
+                               $this->parent->addSQL( $this->create( $this->parent ) );\r
+                               xml_set_object( $parser, $this->parent );\r
+                               $this->destroy();\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Re-initializes the query.\r
+       *\r
+       * @return boolean TRUE\r
+       */\r
+       function newQuery() {\r
+               $this->query = '';\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       /**\r
+       * Discards the existing query.\r
+       *\r
+       * @return boolean TRUE\r
+       */\r
+       function discardQuery() {\r
+               unset( $this->query );\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       /** \r
+       * Appends a line to a query that is being built line by line\r
+       *\r
+       * @param string $data Line of SQL data or NULL to initialize a new query\r
+       * @return string SQL query string.\r
+       */\r
+       function buildQuery( $sql = NULL ) {\r
+               if( !isset( $this->query ) OR empty( $sql ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $this->query .= $sql;\r
+               \r
+               return $this->query;\r
+       }\r
+       \r
+       /**\r
+       * Adds a completed query to the query list\r
+       *\r
+       * @return string        SQL of added query\r
+       */\r
+       function addQuery() {\r
+               if( !isset( $this->query ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $this->queries[] = $return = trim($this->query);\r
+               \r
+               unset( $this->query );\r
+               \r
+               return $return;\r
+       }\r
+       \r
+       /**\r
+       * Creates and returns the current query set\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Query set\r
+       */\r
+       function create( &$xmls ) {\r
+               foreach( $this->queries as $id => $query ) {\r
+                       switch( $this->prefixMethod ) {\r
+                               case 'AUTO':\r
+                                       // Enable auto prefix replacement\r
+                                       \r
+                                       // Process object prefix.\r
+                                       // Evaluate SQL statements to prepend prefix to objects\r
+                                       $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+                                       $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+                                       $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+                                       \r
+                                       // SELECT statements aren't working yet\r
+                                       #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );\r
+                                       \r
+                               case 'MANUAL':\r
+                                       // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.\r
+                                       // If prefixKey is not set, we use the default constant XMLS_PREFIX\r
+                                       if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {\r
+                                               // Enable prefix override\r
+                                               $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );\r
+                                       } else {\r
+                                               // Use default replacement\r
+                                               $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );\r
+                                       }\r
+                       }\r
+                       \r
+                       $this->queries[$id] = trim( $query );\r
+               }\r
+               \r
+               // Return the query set array\r
+               return $this->queries;\r
+       }\r
+       \r
+       /**\r
+       * Rebuilds the query with the prefix attached to any objects\r
+       *\r
+       * @param string $regex Regex used to add prefix\r
+       * @param string $query SQL query string\r
+       * @param string $prefix Prefix to be appended to tables, indices, etc.\r
+       * @return string Prefixed SQL query string.\r
+       */\r
+       function prefixQuery( $regex, $query, $prefix = NULL ) {\r
+               if( !isset( $prefix ) ) {\r
+                       return $query;\r
+               }\r
+               \r
+               if( preg_match( $regex, $query, $match ) ) {\r
+                       $preamble = $match[1];\r
+                       $postamble = $match[5];\r
+                       $objectList = explode( ',', $match[3] );\r
+                       // $prefix = $prefix . '_';\r
+                       \r
+                       $prefixedList = '';\r
+                       \r
+                       foreach( $objectList as $object ) {\r
+                               if( $prefixedList !== '' ) {\r
+                                       $prefixedList .= ', ';\r
+                               }\r
+                               \r
+                               $prefixedList .= $prefix . trim( $object );\r
+                       }\r
+                       \r
+                       $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;\r
+               }\r
+               \r
+               return $query;\r
+       }\r
+}\r
+\r
+/**\r
+* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements\r
+* \r
+* This class is used to load and parse the XML file, to create an array of SQL statements\r
+* that can be used to build a database, and to build the database using the SQL array.\r
+*\r
+* @tutorial getting_started.pkg\r
+*\r
+* @author Richard Tango-Lowy & Dan Cech\r
+* @version $Revision$\r
+*\r
+* @package axmls\r
+*/\r
+class adoSchema {\r
+       \r
+       /**\r
+       * @var array    Array containing SQL queries to generate all objects\r
+       * @access private\r
+       */\r
+       var $sqlArray;\r
+       \r
+       /**\r
+       * @var object   ADOdb connection object\r
+       * @access private\r
+       */\r
+       var $db;\r
+       \r
+       /**\r
+       * @var object   ADOdb Data Dictionary\r
+       * @access private\r
+       */\r
+       var $dict;\r
+       \r
+       /**\r
+       * @var string Current XML element\r
+       * @access private\r
+       */\r
+       var $currentElement = '';\r
+       \r
+       /**\r
+       * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database\r
+       * @access private\r
+       */\r
+       var $upgrade = '';\r
+       \r
+       /**\r
+       * @var string Optional object prefix\r
+       * @access private\r
+       */\r
+       var $objectPrefix = '';\r
+       \r
+       /**\r
+       * @var long     Original Magic Quotes Runtime value\r
+       * @access private\r
+       */\r
+       var $mgq;\r
+       \r
+       /**\r
+       * @var long     System debug\r
+       * @access private\r
+       */\r
+       var $debug;\r
+       \r
+       /**\r
+       * @var string Regular expression to find schema version\r
+       * @access private\r
+       */\r
+       var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';\r
+       \r
+       /**\r
+       * @var string Current schema version\r
+       * @access private\r
+       */\r
+       var $schemaVersion;\r
+       \r
+       /**\r
+       * @var int      Success of last Schema execution\r
+       */\r
+       var $success;\r
+       \r
+       /**\r
+       * @var bool     Execute SQL inline as it is generated\r
+       */\r
+       var $executeInline;\r
+       \r
+       /**\r
+       * @var bool     Continue SQL execution if errors occur\r
+       */\r
+       var $continueOnError;\r
+       \r
+       /**\r
+       * Creates an adoSchema object\r
+       *\r
+       * Creating an adoSchema object is the first step in processing an XML schema.\r
+       * The only parameter is an ADOdb database connection object, which must already\r
+       * have been created.\r
+       *\r
+       * @param object $db ADOdb database connection object.\r
+       */\r
+       function adoSchema( &$db ) {\r
+               // Initialize the environment\r
+               $this->mgq = get_magic_quotes_runtime();\r
+               set_magic_quotes_runtime(0);\r
+               \r
+               $this->db = $db;\r
+               $this->debug = $this->db->debug;\r
+               $this->dict = NewDataDictionary( $this->db );\r
+               $this->sqlArray = array();\r
+               $this->schemaVersion = XMLS_SCHEMA_VERSION;\r
+               $this->executeInline( XMLS_EXECUTE_INLINE );\r
+               $this->continueOnError( XMLS_CONTINUE_ON_ERROR );\r
+               $this->setUpgradeMethod();\r
+       }\r
+       \r
+       /**\r
+       * Sets the method to be used for upgrading an existing database\r
+       *\r
+       * Use this method to specify how existing database objects should be upgraded.\r
+       * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to\r
+       * alter each database object directly, REPLACE attempts to rebuild each object\r
+       * from scratch, BEST attempts to determine the best upgrade method for each\r
+       * object, and NONE disables upgrading.\r
+       *\r
+       * This method is not yet used by AXMLS, but exists for backward compatibility.\r
+       * The ALTER method is automatically assumed when the adoSchema object is\r
+       * instantiated; other upgrade methods are not currently supported.\r
+       *\r
+       * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)\r
+       * @returns string Upgrade method used\r
+       */\r
+       function SetUpgradeMethod( $method = '' ) {\r
+               if( !is_string( $method ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $method = strtoupper( $method );\r
+               \r
+               // Handle the upgrade methods\r
+               switch( $method ) {\r
+                       case 'ALTER':\r
+                               $this->upgrade = $method;\r
+                               break;\r
+                       case 'REPLACE':\r
+                               $this->upgrade = $method;\r
+                               break;\r
+                       case 'BEST':\r
+                               $this->upgrade = 'ALTER';\r
+                               break;\r
+                       case 'NONE':\r
+                               $this->upgrade = 'NONE';\r
+                               break;\r
+                       default:\r
+                               // Use default if no legitimate method is passed.\r
+                               $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;\r
+               }\r
+               \r
+               return $this->upgrade;\r
+       }\r
+       \r
+       /**\r
+       * Enables/disables inline SQL execution.\r
+       *\r
+       * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),\r
+       * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode\r
+       * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()\r
+       * to apply the schema to the database.\r
+       *\r
+       * @param bool $mode execute\r
+       * @return bool current execution mode\r
+       *\r
+       * @see ParseSchema(), ExecuteSchema()\r
+       */\r
+       function ExecuteInline( $mode = NULL ) {\r
+               if( is_bool( $mode ) ) {\r
+                       $this->executeInline = $mode;\r
+               }\r
+               \r
+               return $this->executeInline;\r
+       }\r
+       \r
+       /**\r
+       * Enables/disables SQL continue on error.\r
+       *\r
+       * Call this method to enable or disable continuation of SQL execution if an error occurs.\r
+       * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.\r
+       * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing\r
+       * of the schema will continue.\r
+       *\r
+       * @param bool $mode execute\r
+       * @return bool current continueOnError mode\r
+       *\r
+       * @see addSQL(), ExecuteSchema()\r
+       */\r
+       function ContinueOnError( $mode = NULL ) {\r
+               if( is_bool( $mode ) ) {\r
+                       $this->continueOnError = $mode;\r
+               }\r
+               \r
+               return $this->continueOnError;\r
+       }\r
+       \r
+       /**\r
+       * Loads an XML schema from a file and converts it to SQL.\r
+       *\r
+       * Call this method to load the specified schema (see the DTD for the proper format) from\r
+       * the filesystem and generate the SQL necessary to create the database described. \r
+       * @see ParseSchemaString()\r
+       *\r
+       * @param string $file Name of XML schema file.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute\r
+       */\r
+       function ParseSchema( $filename, $returnSchema = FALSE ) {\r
+               return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+       }\r
+       \r
+       /**\r
+       * Loads an XML schema from a file and converts it to SQL.\r
+       *\r
+       * Call this method to load the specified schema from a file (see the DTD for the proper format) \r
+       * and generate the SQL necessary to create the database described by the schema.\r
+       *\r
+       * @param string $file Name of XML schema file.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute.\r
+       *\r
+       * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()\r
+       * @see ParseSchema(), ParseSchemaString()\r
+       */\r
+       function ParseSchemaFile( $filename, $returnSchema = FALSE ) {\r
+               // Open the file\r
+               if( !($fp = fopen( $filename, 'r' )) ) {\r
+                       // die( 'Unable to open file' );\r
+                       return FALSE;\r
+               }\r
+               \r
+               // do version detection here\r
+               if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if ( $returnSchema )\r
+               {\r
+                       $xmlstring = '';\r
+                       while( $data = fread( $fp, 100000 ) ) {\r
+                               $xmlstring .= $data;\r
+                       }\r
+                       return $xmlstring;\r
+               }\r
+               \r
+               $this->success = 2;\r
+               \r
+               $xmlParser = $this->create_parser();\r
+               \r
+               // Process the file\r
+               while( $data = fread( $fp, 4096 ) ) {\r
+                       if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {\r
+                               die( sprintf(\r
+                                       "XML error: %s at line %d",\r
+                                       xml_error_string( xml_get_error_code( $xmlParser) ),\r
+                                       xml_get_current_line_number( $xmlParser)\r
+                               ) );\r
+                       }\r
+               }\r
+               \r
+               xml_parser_free( $xmlParser );\r
+               \r
+               return $this->sqlArray;\r
+       }\r
+       \r
+       /**\r
+       * Converts an XML schema string to SQL.\r
+       *\r
+       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+       * and generate the SQL necessary to create the database described by the schema. \r
+       * @see ParseSchema()\r
+       *\r
+       * @param string $xmlstring XML schema string.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute.\r
+       */\r
+       function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {\r
+               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               // do version detection here\r
+               if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if ( $returnSchema )\r
+               {\r
+                       return $xmlstring;\r
+               }\r
+               \r
+               $this->success = 2;\r
+               \r
+               $xmlParser = $this->create_parser();\r
+               \r
+               if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {\r
+                       die( sprintf(\r
+                               "XML error: %s at line %d",\r
+                               xml_error_string( xml_get_error_code( $xmlParser) ),\r
+                               xml_get_current_line_number( $xmlParser)\r
+                       ) );\r
+               }\r
+               \r
+               xml_parser_free( $xmlParser );\r
+               \r
+               return $this->sqlArray;\r
+       }\r
+       \r
+       /**\r
+       * Loads an XML schema from a file and converts it to uninstallation SQL.\r
+       *\r
+       * Call this method to load the specified schema (see the DTD for the proper format) from\r
+       * the filesystem and generate the SQL necessary to remove the database described.\r
+       * @see RemoveSchemaString()\r
+       *\r
+       * @param string $file Name of XML schema file.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute\r
+       */\r
+       function RemoveSchema( $filename, $returnSchema = FALSE ) {\r
+               return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+       }\r
+       \r
+       /**\r
+       * Converts an XML schema string to uninstallation SQL.\r
+       *\r
+       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+       * and generate the SQL necessary to uninstall the database described by the schema. \r
+       * @see RemoveSchema()\r
+       *\r
+       * @param string $schema XML schema string.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute.\r
+       */\r
+       function RemoveSchemaString( $schema, $returnSchema = FALSE ) {\r
+               \r
+               // grab current version\r
+               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );\r
+       }\r
+       \r
+       /**\r
+       * Applies the current XML schema to the database (post execution).\r
+       *\r
+       * Call this method to apply the current schema (generally created by calling \r
+       * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes, \r
+       * and executing other SQL specified in the schema) after parsing.\r
+       * @see ParseSchema(), ParseSchemaString(), ExecuteInline()\r
+       *\r
+       * @param array $sqlArray Array of SQL statements that will be applied rather than\r
+       *               the current schema.\r
+       * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.\r
+       * @returns integer 0 if failure, 1 if errors, 2 if successful.\r
+       */\r
+       function ExecuteSchema( $sqlArray = NULL, $continueOnErr =  NULL ) {\r
+               if( !is_bool( $continueOnErr ) ) {\r
+                       $continueOnErr = $this->ContinueOnError();\r
+               }\r
+               \r
+               if( !isset( $sqlArray ) ) {\r
+                       $sqlArray = $this->sqlArray;\r
+               }\r
+               \r
+               if( !is_array( $sqlArray ) ) {\r
+                       $this->success = 0;\r
+               } else {\r
+                       $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );\r
+               }\r
+               \r
+               return $this->success;\r
+       }\r
+       \r
+       /**\r
+       * Returns the current SQL array. \r
+       *\r
+       * Call this method to fetch the array of SQL queries resulting from \r
+       * ParseSchema() or ParseSchemaString(). \r
+       *\r
+       * @param string $format Format: HTML, TEXT, or NONE (PHP array)\r
+       * @return array Array of SQL statements or FALSE if an error occurs\r
+       */\r
+       function PrintSQL( $format = 'NONE' ) {\r
+               $sqlArray = null;\r
+               return $this->getSQL( $format, $sqlArray );\r
+       }\r
+       \r
+       /**\r
+       * Saves the current SQL array to the local filesystem as a list of SQL queries.\r
+       *\r
+       * Call this method to save the array of SQL queries (generally resulting from a\r
+       * parsed XML schema) to the filesystem.\r
+       *\r
+       * @param string $filename Path and name where the file should be saved.\r
+       * @return boolean TRUE if save is successful, else FALSE. \r
+       */\r
+       function SaveSQL( $filename = './schema.sql' ) {\r
+               \r
+               if( !isset( $sqlArray ) ) {\r
+                       $sqlArray = $this->sqlArray;\r
+               }\r
+               if( !isset( $sqlArray ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $fp = fopen( $filename, "w" );\r
+               \r
+               foreach( $sqlArray as $key => $query ) {\r
+                       fwrite( $fp, $query . ";\n" );\r
+               }\r
+               fclose( $fp );\r
+       }\r
+       \r
+       /**\r
+       * Create an xml parser\r
+       *\r
+       * @return object PHP XML parser object\r
+       *\r
+       * @access private\r
+       */\r
+       function create_parser() {\r
+               // Create the parser\r
+               $xmlParser = xml_parser_create();\r
+               xml_set_object( $xmlParser, $this );\r
+               \r
+               // Initialize the XML callback functions\r
+               xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );\r
+               xml_set_character_data_handler( $xmlParser, '_tag_cdata' );\r
+               \r
+               return $xmlParser;\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'TABLE':\r
+                               $this->obj = new dbTable( $this, $attributes );\r
+                               xml_set_object( $parser, $this->obj );\r
+                               break;\r
+                       case 'SQL':\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       $this->obj = new dbQuerySet( $this, $attributes );\r
+                                       xml_set_object( $parser, $this->obj );\r
+                               }\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+               \r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       * @internal\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               \r
+       }\r
+       \r
+       /**\r
+       * Converts an XML schema string to the specified DTD version.\r
+       *\r
+       * Call this method to convert a string containing an XML schema to a different AXMLS\r
+       * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+       * parameter is specified, the schema will be converted to the current DTD version. \r
+       * If the newFile parameter is provided, the converted schema will be written to the specified\r
+       * file.\r
+       * @see ConvertSchemaFile()\r
+       *\r
+       * @param string $schema String containing XML schema that will be converted.\r
+       * @param string $newVersion DTD version to convert to.\r
+       * @param string $newFile File name of (converted) output file.\r
+       * @return string Converted XML schema or FALSE if an error occurs.\r
+       */\r
+       function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {\r
+               \r
+               // grab current version\r
+               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( !isset ($newVersion) ) {\r
+                       $newVersion = $this->schemaVersion;\r
+               }\r
+               \r
+               if( $version == $newVersion ) {\r
+                       $result = $schema;\r
+               } else {\r
+                       $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);\r
+               }\r
+               \r
+               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+                       fwrite( $fp, $result );\r
+                       fclose( $fp );\r
+               }\r
+               \r
+               return $result;\r
+       }\r
+       \r
+       // compat for pre-4.3 - jlim\r
+       function _file_get_contents($path)\r
+       {\r
+               if (function_exists('file_get_contents')) return file_get_contents($path);\r
+               return join('',file($path));\r
+       }\r
+       \r
+       /**\r
+       * Converts an XML schema file to the specified DTD version.\r
+       *\r
+       * Call this method to convert the specified XML schema file to a different AXMLS\r
+       * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+       * parameter is specified, the schema will be converted to the current DTD version. \r
+       * If the newFile parameter is provided, the converted schema will be written to the specified\r
+       * file.\r
+       * @see ConvertSchemaString()\r
+       *\r
+       * @param string $filename Name of XML schema file that will be converted.\r
+       * @param string $newVersion DTD version to convert to.\r
+       * @param string $newFile File name of (converted) output file.\r
+       * @return string Converted XML schema or FALSE if an error occurs.\r
+       */\r
+       function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {\r
+               \r
+               // grab current version\r
+               if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( !isset ($newVersion) ) {\r
+                       $newVersion = $this->schemaVersion;\r
+               }\r
+               \r
+               if( $version == $newVersion ) {\r
+                       $result = _file_get_contents( $filename );\r
+                       \r
+                       // remove unicode BOM if present\r
+                       if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {\r
+                               $result = substr( $result, 3 );\r
+                       }\r
+               } else {\r
+                       $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );\r
+               }\r
+               \r
+               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+                       fwrite( $fp, $result );\r
+                       fclose( $fp );\r
+               }\r
+               \r
+               return $result;\r
+       }\r
+       \r
+       function TransformSchema( $schema, $xsl, $schematype='string' )\r
+       {\r
+               // Fail if XSLT extension is not available\r
+               if( ! function_exists( 'xslt_create' ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';\r
+               \r
+               // look for xsl\r
+               if( !is_readable( $xsl_file ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               switch( $schematype )\r
+               {\r
+                       case 'file':\r
+                               if( !is_readable( $schema ) ) {\r
+                                       return FALSE;\r
+                               }\r
+                               \r
+                               $schema = _file_get_contents( $schema );\r
+                               break;\r
+                       case 'string':\r
+                       default:\r
+                               if( !is_string( $schema ) ) {\r
+                                       return FALSE;\r
+                               }\r
+               }\r
+               \r
+               $arguments = array (\r
+                       '/_xml' => $schema,\r
+                       '/_xsl' => _file_get_contents( $xsl_file )\r
+               );\r
+               \r
+               // create an XSLT processor\r
+               $xh = xslt_create ();\r
+               \r
+               // set error handler\r
+               xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));\r
+               \r
+               // process the schema\r
+               $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); \r
+               \r
+               xslt_free ($xh);\r
+               \r
+               return $result;\r
+       }\r
+       \r
+       /**\r
+       * Processes XSLT transformation errors\r
+       *\r
+       * @param object $parser XML parser object\r
+       * @param integer $errno Error number\r
+       * @param integer $level Error level\r
+       * @param array $fields Error information fields\r
+       *\r
+       * @access private\r
+       */\r
+       function xslt_error_handler( $parser, $errno, $level, $fields ) {\r
+               if( is_array( $fields ) ) {\r
+                       $msg = array(\r
+                               'Message Type' => ucfirst( $fields['msgtype'] ),\r
+                               'Message Code' => $fields['code'],\r
+                               'Message' => $fields['msg'],\r
+                               'Error Number' => $errno,\r
+                               'Level' => $level\r
+                       );\r
+                       \r
+                       switch( $fields['URI'] ) {\r
+                               case 'arg:/_xml':\r
+                                       $msg['Input'] = 'XML';\r
+                                       break;\r
+                               case 'arg:/_xsl':\r
+                                       $msg['Input'] = 'XSL';\r
+                                       break;\r
+                               default:\r
+                                       $msg['Input'] = $fields['URI'];\r
+                       }\r
+                       \r
+                       $msg['Line'] = $fields['line'];\r
+               } else {\r
+                       $msg = array(\r
+                               'Message Type' => 'Error',\r
+                               'Error Number' => $errno,\r
+                               'Level' => $level,\r
+                               'Fields' => var_export( $fields, TRUE )\r
+                       );\r
+               }\r
+               \r
+               $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"\r
+                                          . '<table>' . "\n";\r
+               \r
+               foreach( $msg as $label => $details ) {\r
+                       $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";\r
+               }\r
+               \r
+               $error_details .= '</table>';\r
+               \r
+               trigger_error( $error_details, E_USER_ERROR );\r
+       }\r
+       \r
+       /**\r
+       * Returns the AXMLS Schema Version of the requested XML schema file.\r
+       *\r
+       * Call this method to obtain the AXMLS DTD version of the requested XML schema file.\r
+       * @see SchemaStringVersion()\r
+       *\r
+       * @param string $filename AXMLS schema file\r
+       * @return string Schema version number or FALSE on error\r
+       */\r
+       function SchemaFileVersion( $filename ) {\r
+               // Open the file\r
+               if( !($fp = fopen( $filename, 'r' )) ) {\r
+                       // die( 'Unable to open file' );\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Process the file\r
+               while( $data = fread( $fp, 4096 ) ) {\r
+                       if( preg_match( $this->versionRegex, $data, $matches ) ) {\r
+                               return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+                       }\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+       * Returns the AXMLS Schema Version of the provided XML schema string.\r
+       *\r
+       * Call this method to obtain the AXMLS DTD version of the provided XML schema string.\r
+       * @see SchemaFileVersion()\r
+       *\r
+       * @param string $xmlstring XML schema string\r
+       * @return string Schema version number or FALSE on error\r
+       */\r
+       function SchemaStringVersion( $xmlstring ) {\r
+               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {\r
+                       return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+       * Extracts an XML schema from an existing database.\r
+       *\r
+       * Call this method to create an XML schema string from an existing database.\r
+       * If the data parameter is set to TRUE, AXMLS will include the data from the database\r
+       * in the schema. \r
+       *\r
+       * @param boolean $data Include data in schema dump\r
+       * @return string Generated XML schema\r
+       */\r
+       function ExtractSchema( $data = FALSE ) {\r
+               $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );\r
+               \r
+               $schema = '<?xml version="1.0"?>' . "\n"\r
+                               . '<schema version="' . $this->schemaVersion . '">' . "\n";\r
+               \r
+               if( is_array( $tables = $this->db->MetaTables( 'TABLES' ) ) ) {\r
+                       foreach( $tables as $table ) {\r
+                               $schema .= '    <table name="' . $table . '">' . "\n";\r
+                               \r
+                               // grab details from database\r
+                               $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' );\r
+                               $fields = $this->db->MetaColumns( $table );\r
+                               $indexes = $this->db->MetaIndexes( $table );\r
+                               \r
+                               if( is_array( $fields ) ) {\r
+                                       foreach( $fields as $details ) {\r
+                                               $extra = '';\r
+                                               $content = array();\r
+                                               \r
+                                               if( $details->max_length > 0 ) {\r
+                                                       $extra .= ' size="' . $details->max_length . '"';\r
+                                               }\r
+                                               \r
+                                               if( $details->primary_key ) {\r
+                                                       $content[] = '<KEY/>';\r
+                                               } elseif( $details->not_null ) {\r
+                                                       $content[] = '<NOTNULL/>';\r
+                                               }\r
+                                               \r
+                                               if( $details->has_default ) {\r
+                                                       $content[] = '<DEFAULT value="' . $details->default_value . '"/>';\r
+                                               }\r
+                                               \r
+                                               if( $details->auto_increment ) {\r
+                                                       $content[] = '<AUTOINCREMENT/>';\r
+                                               }\r
+                                               \r
+                                               // this stops the creation of 'R' columns,\r
+                                               // AUTOINCREMENT is used to create auto columns\r
+                                               $details->primary_key = 0;\r
+                                               $type = $rs->MetaType( $details );\r
+                                               \r
+                                               $schema .= '            <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>';\r
+                                               \r
+                                               if( !empty( $content ) ) {\r
+                                                       $schema .= "\n                  " . implode( "\n                        ", $content ) . "\n             ";\r
+                                               }\r
+                                               \r
+                                               $schema .= '</field>' . "\n";\r
+                                       }\r
+                               }\r
+                               \r
+                               if( is_array( $indexes ) ) {\r
+                                       foreach( $indexes as $index => $details ) {\r
+                                               $schema .= '            <index name="' . $index . '">' . "\n";\r
+                                               \r
+                                               if( $details['unique'] ) {\r
+                                                       $schema .= '                    <UNIQUE/>' . "\n";\r
+                                               }\r
+                                               \r
+                                               foreach( $details['columns'] as $column ) {\r
+                                                       $schema .= '                    <col>' . $column . '</col>' . "\n";\r
+                                               }\r
+                                               \r
+                                               $schema .= '            </index>' . "\n";\r
+                                       }\r
+                               }\r
+                               \r
+                               if( $data ) {\r
+                                       $rs = $this->db->Execute( 'SELECT * FROM ' . $table );\r
+                                       \r
+                                       if( is_object( $rs ) ) {\r
+                                               $schema .= '            <data>' . "\n";\r
+                                               \r
+                                               while( $row = $rs->FetchRow() ) {\r
+                                                       foreach( $row as $key => $val ) {\r
+                                                               $row[$key] = htmlentities($val);\r
+                                                       }\r
+                                                       \r
+                                                       $schema .= '                    <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";\r
+                                               }\r
+                                               \r
+                                               $schema .= '            </data>' . "\n";\r
+                                       }\r
+                               }\r
+                               \r
+                               $schema .= '    </table>' . "\n";\r
+                       }\r
+               }\r
+               \r
+               $this->db->SetFetchMode( $old_mode );\r
+               \r
+               $schema .= '</schema>';\r
+               return $schema;\r
+       }\r
+       \r
+       /**\r
+       * Sets a prefix for database objects\r
+       *\r
+       * Call this method to set a standard prefix that will be prepended to all database tables \r
+       * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.\r
+       *\r
+       * @param string $prefix Prefix that will be prepended.\r
+       * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.\r
+       * @return boolean TRUE if successful, else FALSE\r
+       */\r
+       function SetPrefix( $prefix = '', $underscore = TRUE ) {\r
+               switch( TRUE ) {\r
+                       // clear prefix\r
+                       case empty( $prefix ):\r
+                               logMsg( 'Cleared prefix' );\r
+                               $this->objectPrefix = '';\r
+                               return TRUE;\r
+                       // prefix too long\r
+                       case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:\r
+                       // prefix contains invalid characters\r
+                       case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):\r
+                               logMsg( 'Invalid prefix: ' . $prefix );\r
+                               return FALSE;\r
+               }\r
+               \r
+               if( $underscore AND substr( $prefix, -1 ) != '_' ) {\r
+                       $prefix .= '_';\r
+               }\r
+               \r
+               // prefix valid\r
+               logMsg( 'Set prefix: ' . $prefix );\r
+               $this->objectPrefix = $prefix;\r
+               return TRUE;\r
+       }\r
+       \r
+       /**\r
+       * Returns an object name with the current prefix prepended.\r
+       *\r
+       * @param string $name Name\r
+       * @return string        Prefixed name\r
+       *\r
+       * @access private\r
+       */\r
+       function prefix( $name = '' ) {\r
+               // if prefix is set\r
+               if( !empty( $this->objectPrefix ) ) {\r
+                       // Prepend the object prefix to the table name\r
+                       // prepend after quote if used\r
+                       return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );\r
+               }\r
+               \r
+               // No prefix set. Use name provided.\r
+               return $name;\r
+       }\r
+       \r
+       /**\r
+       * Checks if element references a specific platform\r
+       *\r
+       * @param string $platform Requested platform\r
+       * @returns boolean TRUE if platform check succeeds\r
+       *\r
+       * @access private\r
+       */\r
+       function supportedPlatform( $platform = NULL ) {\r
+               $regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';\r
+               \r
+               if( !isset( $platform ) OR preg_match( $regex, $platform ) ) {\r
+                       logMsg( "Platform $platform is supported" );\r
+                       return TRUE;\r
+               } else {\r
+                       logMsg( "Platform $platform is NOT supported" );\r
+                       return FALSE;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Clears the array of generated SQL.\r
+       *\r
+       * @access private\r
+       */\r
+       function clearSQL() {\r
+               $this->sqlArray = array();\r
+       }\r
+       \r
+       /**\r
+       * Adds SQL into the SQL array.\r
+       *\r
+       * @param mixed $sql SQL to Add\r
+       * @return boolean TRUE if successful, else FALSE.\r
+       *\r
+       * @access private\r
+       */      \r
+       function addSQL( $sql = NULL ) {\r
+               if( is_array( $sql ) ) {\r
+                       foreach( $sql as $line ) {\r
+                               $this->addSQL( $line );\r
+                       }\r
+                       \r
+                       return TRUE;\r
+               }\r
+               \r
+               if( is_string( $sql ) ) {\r
+                       $this->sqlArray[] = $sql;\r
+                       \r
+                       // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.\r
+                       if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {\r
+                               $saved = $this->db->debug;\r
+                               $this->db->debug = $this->debug;\r
+                               $ok = $this->db->Execute( $sql );\r
+                               $this->db->debug = $saved;\r
+                               \r
+                               if( !$ok ) {\r
+                                       if( $this->debug ) {\r
+                                               ADOConnection::outp( $this->db->ErrorMsg() );\r
+                                       }\r
+                                       \r
+                                       $this->success = 1;\r
+                               }\r
+                       }\r
+                       \r
+                       return TRUE;\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+       * Gets the SQL array in the specified format.\r
+       *\r
+       * @param string $format Format\r
+       * @return mixed SQL\r
+       *       \r
+       * @access private\r
+       */\r
+       function getSQL( $format = NULL, $sqlArray = NULL ) {\r
+               if( !is_array( $sqlArray ) ) {\r
+                       $sqlArray = $this->sqlArray;\r
+               }\r
+               \r
+               if( !is_array( $sqlArray ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               switch( strtolower( $format ) ) {\r
+                       case 'string':\r
+                       case 'text':\r
+                               return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';\r
+                       case'html':\r
+                               return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';\r
+               }\r
+               \r
+               return $this->sqlArray;\r
+       }\r
+       \r
+       /**\r
+       * Destroys an adoSchema object.\r
+       *\r
+       * Call this method to clean up after an adoSchema object that is no longer in use.\r
+       * @deprecated adoSchema now cleans up automatically.\r
+       */\r
+       function Destroy() {\r
+               set_magic_quotes_runtime( $this->mgq );\r
+               unset( $this );\r
+       }\r
+}\r
+\r
+/**\r
+* Message logging function\r
+*\r
+* @access private\r
+*/\r
+function logMsg( $msg, $title = NULL, $force = FALSE ) {\r
+       if( XMLS_DEBUG or $force ) {\r
+               echo '<pre>';\r
+               \r
+               if( isset( $title ) ) {\r
+                       echo '<h3>' . htmlentities( $title ) . '</h3>';\r
+               }\r
+               \r
+               if( is_object( $this ) ) {\r
+                       echo '[' . get_class( $this ) . '] ';\r
+               }\r
+               \r
+               print_r( $msg );\r
+               \r
+               echo '</pre>';\r
+       }\r
+}\r
 ?>
\ No newline at end of file
index cc98bec6bb2c6fd5ce8517fb383e8632fe4c53b0..8c6a538780e077e8a29969e270971ef8e2b2663b 100644 (file)
-<?php
-// Copyright (c) 2004-2005 ars Cognita Inc., 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. 
-*******************************************************************************/
-/**
- * xmlschema is a class that allows the user to quickly and easily
- * build a database on any ADOdb-supported platform using a simple
- * XML schema.
- *
- * Last Editor: $Author$
- * @author Richard Tango-Lowy & Dan Cech
- * @version $Revision$
- *
- * @package axmls
- * @tutorial getting_started.pkg
- */
-function _file_get_contents($file) 
-{
-       if (function_exists('file_get_contents')) return file_get_contents($file);
-       
-       $f = fopen($file,'r');
-       if (!$f) return '';
-       $t = '';
-       
-       while ($s = fread($f,100000)) $t .= $s;
-       fclose($f);
-       return $t;
-}
-
-
-/**
-* Debug on or off
-*/
-if( !defined( 'XMLS_DEBUG' ) ) {
-       define( 'XMLS_DEBUG', FALSE );
-}
-
-/**
-* Default prefix key
-*/
-if( !defined( 'XMLS_PREFIX' ) ) {
-       define( 'XMLS_PREFIX', '%%P' );
-}
-
-/**
-* Maximum length allowed for object prefix
-*/
-if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
-       define( 'XMLS_PREFIX_MAXLEN', 10 );
-}
-
-/**
-* Execute SQL inline as it is generated
-*/
-if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
-       define( 'XMLS_EXECUTE_INLINE', FALSE );
-}
-
-/**
-* Continue SQL Execution if an error occurs?
-*/
-if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
-       define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
-}
-
-/**
-* Current Schema Version
-*/
-if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
-       define( 'XMLS_SCHEMA_VERSION', '0.3' );
-}
-
-/**
-* Default Schema Version.  Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
-       define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
-}
-
-/**
-* How to handle data rows that already exist in a database during and upgrade.
-* Options are INSERT (attempts to insert duplicate rows), UPDATE (updates existing
-* rows) and IGNORE (ignores existing rows).
-*/
-if( !defined( 'XMLS_MODE_INSERT' ) ) {
-       define( 'XMLS_MODE_INSERT', 0 );
-}
-if( !defined( 'XMLS_MODE_UPDATE' ) ) {
-       define( 'XMLS_MODE_UPDATE', 1 );
-}
-if( !defined( 'XMLS_MODE_IGNORE' ) ) {
-       define( 'XMLS_MODE_IGNORE', 2 );
-}
-if( !defined( 'XMLS_EXISTING_DATA' ) ) {
-       define( 'XMLS_EXISTING_DATA', XMLS_MODE_INSERT );
-}
-
-/**
-* Default Schema Version.  Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
-       define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
-}
-
-/**
-* Include the main ADODB library
-*/
-if( !defined( '_ADODB_LAYER' ) ) {
-       require( 'adodb.inc.php' );
-       require( 'adodb-datadict.inc.php' );
-}
-
-/**
-* Abstract DB Object. This class provides basic methods for database objects, such
-* as tables and indexes.
-*
-* @package axmls
-* @access private
-*/
-class dbObject {
-       
-       /**
-       * var object Parent
-       */
-       var $parent;
-       
-       /**
-       * var string current element
-       */
-       var $currentElement;
-       
-       /**
-       * NOP
-       */
-       function dbObject( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               
-       }
-       
-       function create() {
-               return array();
-       }
-       
-       /**
-       * Destroys the object
-       */
-       function destroy() {
-               unset( $this );
-       }
-       
-       /**
-       * Checks whether the specified RDBMS is supported by the current
-       * database object or its ranking ancestor.
-       *
-       * @param string $platform RDBMS platform name (from ADODB platform list).
-       * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
-       */
-       function supportedPlatform( $platform = NULL ) {
-               return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
-       }
-       
-       /**
-       * Returns the prefix set by the ranking ancestor of the database object.
-       *
-       * @param string $name Prefix string.
-       * @return string Prefix.
-       */
-       function prefix( $name = '' ) {
-               return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
-       }
-       
-       /**
-       * Extracts a field ID from the specified field.
-       *
-       * @param string $field Field.
-       * @return string Field ID.
-       */
-       function FieldID( $field ) {
-               return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
-       }
-}
-
-/**
-* Creates a table object in ADOdb's datadict format
-*
-* This class stores information about a database table. As charactaristics
-* of the table are loaded from the external source, methods and properties
-* of this class are used to build up the table description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbTable extends dbObject {
-       
-       /**
-       * @var string Table name
-       */
-       var $name;
-       
-       /**
-       * @var array Field specifier: Meta-information about each field
-       */
-       var $fields = array();
-       
-       /**
-       * @var array List of table indexes.
-       */
-       var $indexes = array();
-       
-       /**
-       * @var array Table options: Table-level options
-       */
-       var $opts = array();
-       
-       /**
-       * @var string Field index: Keeps track of which field is currently being processed
-       */
-       var $current_field;
-       
-       /**
-       * @var boolean Mark table for destruction
-       * @access private
-       */
-       var $drop_table;
-       
-       /**
-       * @var boolean Mark field for destruction (not yet implemented)
-       * @access private
-       */
-       var $drop_field = array();
-       
-       /**
-       * @var array Platform-specific options
-       * @access private
-       */
-       var $currentPlatform = true;
-       
-       
-       /**
-       * Iniitializes a new table object.
-       *
-       * @param string $prefix DB Object prefix
-       * @param array $attributes Array of table attributes.
-       */
-       function dbTable( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-               $this->name = $this->prefix($attributes['NAME']);
-       }
-       
-       /**
-       * XML Callback to process start elements. Elements currently 
-       * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT. 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'INDEX':
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       xml_set_object( $parser, $this->addIndex( $attributes ) );
-                               }
-                               break;
-                       case 'DATA':
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       xml_set_object( $parser, $this->addData( $attributes ) );
-                               }
-                               break;
-                       case 'DROP':
-                               $this->drop();
-                               break;
-                       case 'FIELD':
-                               // Add a field
-                               $fieldName = $attributes['NAME'];
-                               $fieldType = $attributes['TYPE'];
-                               $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;
-                               $fieldOpts = !empty( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;
-                               
-                               $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
-                               break;
-                       case 'KEY':
-                       case 'NOTNULL':
-                       case 'AUTOINCREMENT':
-                       case 'DEFDATE':
-                       case 'DEFTIMESTAMP':
-                       case 'UNSIGNED':
-                               // Add a field option
-                               $this->addFieldOpt( $this->current_field, $this->currentElement );
-                               break;
-                       case 'DEFAULT':
-                               // Add a field option to the table object
-                               
-                               // Work around ADOdb datadict issue that misinterprets empty strings.
-                               if( $attributes['VALUE'] == '' ) {
-                                       $attributes['VALUE'] = " '' ";
-                               }
-                               
-                               $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );
-                               break;
-                       case 'OPT':
-                       case 'CONSTRAINT':
-                               // Accept platform-specific options
-                               $this->currentPlatform = ( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) );
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Table/field constraint
-                       case 'CONSTRAINT':
-                               if( isset( $this->current_field ) ) {
-                                       $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
-                               } else {
-                                       $this->addTableOpt( $cdata );
-                               }
-                               break;
-                       // Table/field option
-                       case 'OPT':
-                               if( isset( $this->current_field ) ) {
-                                       $this->addFieldOpt( $this->current_field, $cdata );
-                               } else {
-                               $this->addTableOpt( $cdata );
-                               }
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'TABLE':
-                               $this->parent->addSQL( $this->create( $this->parent ) );
-                               xml_set_object( $parser, $this->parent );
-                               $this->destroy();
-                               break;
-                       case 'FIELD':
-                               unset($this->current_field);
-                               break;
-                       case 'OPT':
-                       case 'CONSTRAINT':
-                               $this->currentPlatform = true;
-                               break;
-                       default:
-
-               }
-       }
-       
-       /**
-       * Adds an index to a table object
-       *
-       * @param array $attributes Index attributes
-       * @return object dbIndex object
-       */
-       function &addIndex( $attributes ) {
-               $name = strtoupper( $attributes['NAME'] );
-               $this->indexes[$name] =& new dbIndex( $this, $attributes );
-               return $this->indexes[$name];
-       }
-       
-       /**
-       * Adds data to a table object
-       *
-       * @param array $attributes Data attributes
-       * @return object dbData object
-       */
-       function &addData( $attributes ) {
-               if( !isset( $this->data ) ) {
-                       $this->data =& new dbData( $this, $attributes );
-               }
-               return $this->data;
-       }
-       
-       /**
-       * Adds a field to a table object
-       *
-       * $name is the name of the table to which the field should be added. 
-       * $type is an ADODB datadict field type. The following field types
-       * are supported as of ADODB 3.40:
-       *       - C:  varchar
-       *       - X:  CLOB (character large object) or largest varchar size
-       *          if CLOB is not supported
-       *       - C2: Multibyte varchar
-       *       - X2: Multibyte CLOB
-       *       - B:  BLOB (binary large object)
-       *       - D:  Date (some databases do not support this, and we return a datetime type)
-       *       - T:  Datetime or Timestamp
-       *       - L:  Integer field suitable for storing booleans (0 or 1)
-       *       - I:  Integer (mapped to I4)
-       *       - I1: 1-byte integer
-       *       - I2: 2-byte integer
-       *       - I4: 4-byte integer
-       *       - I8: 8-byte integer
-       *       - F:  Floating point number
-       *       - N:  Numeric or decimal number
-       *
-       * @param string $name Name of the table to which the field will be added.
-       * @param string $type   ADODB datadict field type.
-       * @param string $size   Field size
-       * @param array $opts    Field options array
-       * @return array Field specifier array
-       */
-       function addField( $name, $type, $size = NULL, $opts = NULL ) {
-               $field_id = $this->FieldID( $name );
-               
-               // Set the field index so we know where we are
-               $this->current_field = $field_id;
-               
-               // Set the field name (required)
-               $this->fields[$field_id]['NAME'] = $name;
-               
-               // Set the field type (required)
-               $this->fields[$field_id]['TYPE'] = $type;
-               
-               // Set the field size (optional)
-               if( isset( $size ) ) {
-                       $this->fields[$field_id]['SIZE'] = $size;
-               }
-               
-               // Set the field options
-               if( isset( $opts ) ) {
-                       $this->fields[$field_id]['OPTS'] = array($opts);
-               } else {
-                       $this->fields[$field_id]['OPTS'] = array();
-               }
-       }
-       
-       /**
-       * Adds a field option to the current field specifier
-       *
-       * This method adds a field option allowed by the ADOdb datadict 
-       * and appends it to the given field.
-       *
-       * @param string $field  Field name
-       * @param string $opt ADOdb field option
-       * @param mixed $value Field option value
-       * @return array Field specifier array
-       */
-       function addFieldOpt( $field, $opt, $value = NULL ) {
-               if( $this->currentPlatform ) {
-               if( !isset( $value ) ) {
-                       $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
-               // Add the option and value
-               } else {
-                       $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );
-               }
-       }
-       }
-       
-       /**
-       * Adds an option to the table
-       *
-       * This method takes a comma-separated list of table-level options
-       * and appends them to the table object.
-       *
-       * @param string $opt Table option
-       * @return array Options
-       */
-       function addTableOpt( $opt ) {
-               if( $this->currentPlatform ) {
-               $this->opts[] = $opt;
-               }
-               return $this->opts;
-       }
-       
-       /**
-       * Generates the SQL that will create the table in the database
-       *
-       * @param object $xmls adoSchema object
-       * @return array Array containing table creation SQL
-       */
-       function create( &$xmls ) {
-               $sql = array();
-               
-               // drop any existing indexes
-               if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
-                       foreach( $legacy_indexes as $index => $index_details ) {
-                               $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
-                       }
-               }
-               
-               // remove fields to be dropped from table object
-               foreach( $this->drop_field as $field ) {
-                       unset( $this->fields[$field] );
-               }
-               
-               // if table exists
-               if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
-                       // drop table
-                       if( $this->drop_table ) {
-                               $sql[] = $xmls->dict->DropTableSQL( $this->name );
-                               
-                               return $sql;
-                       }
-                       
-                       // drop any existing fields not in schema
-                       foreach( $legacy_fields as $field_id => $field ) {
-                               if( !isset( $this->fields[$field_id] ) ) {
-                                       $sql[] = $xmls->dict->DropColumnSQL( $this->name, $field->name );
-                               }
-                       }
-               // if table doesn't exist
-               } else {
-                       if( $this->drop_table ) {
-                               return $sql;
-                       }
-                       
-                       $legacy_fields = array();
-               }
-               
-               // Loop through the field specifier array, building the associative array for the field options
-               $fldarray = array();
-               
-               foreach( $this->fields as $field_id => $finfo ) {
-                       // Set an empty size if it isn't supplied
-                       if( !isset( $finfo['SIZE'] ) ) {
-                               $finfo['SIZE'] = '';
-                       }
-                       
-                       // Initialize the field array with the type and size
-                       $fldarray[$field_id] = array(
-                               'NAME' => $finfo['NAME'],
-                               'TYPE' => $finfo['TYPE'],
-                               'SIZE' => $finfo['SIZE']
-                       );
-                       
-                       // Loop through the options array and add the field options. 
-                       if( isset( $finfo['OPTS'] ) ) {
-                               foreach( $finfo['OPTS'] as $opt ) {
-                                       // Option has an argument.
-                                       if( is_array( $opt ) ) {
-                                               $key = key( $opt );
-                                               $value = $opt[key( $opt )];
-                                               @$fldarray[$field_id][$key] .= $value;
-                                       // Option doesn't have arguments
-                                       } else {
-                                               $fldarray[$field_id][$opt] = $opt;
-                                       }
-                               }
-                       }
-               }
-               
-               if( empty( $legacy_fields ) ) {
-                       // Create the new table
-                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
-                       logMsg( end( $sql ), 'Generated CreateTableSQL' );
-               } else {
-                       // Upgrade an existing table
-                       logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
-                       switch( $xmls->upgrade ) {
-                               // Use ChangeTableSQL
-                               case 'ALTER':
-                                       logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
-                                       $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
-                                       break;
-                               case 'REPLACE':
-                                       logMsg( 'Doing upgrade REPLACE (testing)' );
-                                       $sql[] = $xmls->dict->DropTableSQL( $this->name );
-                                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
-                                       break;
-                               // ignore table
-                               default:
-                                       return array();
-                       }
-               }
-               
-               foreach( $this->indexes as $index ) {
-                       $sql[] = $index->create( $xmls );
-               }
-               
-               if( isset( $this->data ) ) {
-                       $sql[] = $this->data->create( $xmls );
-               }
-               
-               return $sql;
-       }
-       
-       /**
-       * Marks a field or table for destruction
-       */
-       function drop() {
-               if( isset( $this->current_field ) ) {
-                       // Drop the current field
-                       logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );
-                       // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );
-                       $this->drop_field[$this->current_field] = $this->current_field;
-               } else {
-                       // Drop the current table
-                       logMsg( "Dropping table '{$this->name}'" );
-                       // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );
-                       $this->drop_table = TRUE;
-               }
-       }
-}
-
-/**
-* Creates an index object in ADOdb's datadict format
-*
-* This class stores information about a database index. As charactaristics
-* of the index are loaded from the external source, methods and properties
-* of this class are used to build up the index description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbIndex extends dbObject {
-       
-       /**
-       * @var string   Index name
-       */
-       var $name;
-       
-       /**
-       * @var array    Index options: Index-level options
-       */
-       var $opts = array();
-       
-       /**
-       * @var array    Indexed fields: Table columns included in this index
-       */
-       var $columns = array();
-       
-       /**
-       * @var boolean Mark index for destruction
-       * @access private
-       */
-       var $drop = FALSE;
-       
-       /**
-       * Initializes the new dbIndex object.
-       *
-       * @param object $parent Parent object
-       * @param array $attributes Attributes
-       *
-       * @internal
-       */
-       function dbIndex( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-               
-               $this->name = $this->prefix ($attributes['NAME']);
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * Processes XML opening tags. 
-       * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'DROP':
-                               $this->drop();
-                               break;
-                       case 'CLUSTERED':
-                       case 'BITMAP':
-                       case 'UNIQUE':
-                       case 'FULLTEXT':
-                       case 'HASH':
-                               // Add index Option
-                               $this->addIndexOpt( $this->currentElement );
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * Processes XML cdata.
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Index field name
-                       case 'COL':
-                               $this->addField( $cdata );
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'INDEX':
-                               xml_set_object( $parser, $this->parent );
-                               break;
-               }
-       }
-       
-       /**
-       * Adds a field to the index
-       *
-       * @param string $name Field name
-       * @return string Field list
-       */
-       function addField( $name ) {
-               $this->columns[$this->FieldID( $name )] = $name;
-               
-               // Return the field list
-               return $this->columns;
-       }
-       
-       /**
-       * Adds options to the index
-       *
-       * @param string $opt Comma-separated list of index options.
-       * @return string Option list
-       */
-       function addIndexOpt( $opt ) {
-               $this->opts[] = $opt;
-               
-               // Return the options list
-               return $this->opts;
-       }
-       
-       /**
-       * Generates the SQL that will create the index in the database
-       *
-       * @param object $xmls adoSchema object
-       * @return array Array containing index creation SQL
-       */
-       function create( &$xmls ) {
-               if( $this->drop ) {
-                       return NULL;
-               }
-               
-               // eliminate any columns that aren't in the table
-               foreach( $this->columns as $id => $col ) {
-                       if( !isset( $this->parent->fields[$id] ) ) {
-                               unset( $this->columns[$id] );
-                       }
-               }
-               
-               return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
-       }
-       
-       /**
-       * Marks an index for destruction
-       */
-       function drop() {
-               $this->drop = TRUE;
-       }
-}
-
-/**
-* Creates a data object in ADOdb's datadict format
-*
-* This class stores information about table data, and is called
-* when we need to load field data into a table.
-*
-* @package axmls
-* @access private
-*/
-class dbData extends dbObject {
-       
-       var $data = array();
-       
-       var $row;
-       
-       /**
-       * Initializes the new dbData object.
-       *
-       * @param object $parent Parent object
-       * @param array $attributes Attributes
-       *
-       * @internal
-       */
-       function dbData( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * Processes XML opening tags. 
-       * Elements currently processed are: ROW and F (field). 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'ROW':
-                               $this->row = count( $this->data );
-                               $this->data[$this->row] = array();
-                               break;
-                       case 'F':
-                               $this->addField($attributes);
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * Processes XML cdata.
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Index field name
-                       case 'F':
-                               $this->addData( $cdata );
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'DATA':
-                               xml_set_object( $parser, $this->parent );
-                               break;
-               }
-       }
-       
-       /**
-       * Adds a field to the insert
-       *
-       * @param string $name Field name
-       * @return string Field list
-       */
-       function addField( $attributes ) {
-               // check we're in a valid row
-               if( !isset( $this->row ) || !isset( $this->data[$this->row] ) ) {
-                       return;
-               }
-               
-               // Set the field index so we know where we are
-               if( isset( $attributes['NAME'] ) ) {
-                       $this->current_field = $this->FieldID( $attributes['NAME'] );
-               } else {
-                       $this->current_field = count( $this->data[$this->row] );
-               }
-               
-               // initialise data
-               if( !isset( $this->data[$this->row][$this->current_field] ) ) {
-                       $this->data[$this->row][$this->current_field] = '';
-               }
-       }
-       
-       /**
-       * Adds options to the index
-       *
-       * @param string $opt Comma-separated list of index options.
-       * @return string Option list
-       */
-       function addData( $cdata ) {
-               // check we're in a valid field
-               if ( isset( $this->data[$this->row][$this->current_field] ) ) {
-                       // add data to field
-                       $this->data[$this->row][$this->current_field] .= $cdata;
-               }
-       }
-       
-       /**
-       * Generates the SQL that will add/update the data in the database
-       *
-       * @param object $xmls adoSchema object
-       * @return array Array containing index creation SQL
-       */
-       function create( &$xmls ) {
-               $table = $xmls->dict->TableName($this->parent->name);
-               $table_field_count = count($this->parent->fields);
-               $tables = $xmls->db->MetaTables(); 
-               $sql = array();
-               
-               $ukeys = $xmls->db->MetaPrimaryKeys( $table );
-               if( !empty( $this->parent->indexes ) and !empty( $ukeys ) ) {
-                       foreach( $this->parent->indexes as $indexObj ) {
-                               if( !in_array( $indexObj->name, $ukeys ) ) $ukeys[] = $indexObj->name;
-                       }
-               }
-               
-               // eliminate any columns that aren't in the table
-               foreach( $this->data as $row ) {
-                       $table_fields = $this->parent->fields;
-                       $fields = array();
-                       $rawfields = array(); // Need to keep some of the unprocessed data on hand.
-                       
-                       foreach( $row as $field_id => $field_data ) {
-                               if( !array_key_exists( $field_id, $table_fields ) ) {
-                                       if( is_numeric( $field_id ) ) {
-                                               $field_id = reset( array_keys( $table_fields ) );
-                                       } else {
-                                               continue;
-                                       }
-                               }
-                               
-                               $name = $table_fields[$field_id]['NAME'];
-                               
-                               switch( $table_fields[$field_id]['TYPE'] ) {
-                                       case 'I':
-                                       case 'I1':
-                                       case 'I2':
-                                       case 'I4':
-                                       case 'I8':
-                                               $fields[$name] = intval($field_data);
-                                               break;
-                                       case 'C':
-                                       case 'C2':
-                                       case 'X':
-                                       case 'X2':
-                                       default:
-                                               $fields[$name] = $xmls->db->qstr( $field_data );
-                                               $rawfields[$name] = $field_data;
-                               }
-                               
-                               unset($table_fields[$field_id]);
-                               
-                       }
-                       
-                       // check that at least 1 column is specified
-                       if( empty( $fields ) ) {
-                               continue;
-                       }
-                       
-                       // check that no required columns are missing
-                       if( count( $fields ) < $table_field_count ) {
-                               foreach( $table_fields as $field ) {
-                                       if( isset( $field['OPTS'] ) and ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {
-                                                       continue(2);
-                                               }
-                               }
-                       }
-                       
-                       // The rest of this method deals with updating existing data records.
-                       
-                       if( !in_array( $table, $tables ) or ( $mode = $xmls->existingData() ) == XMLS_MODE_INSERT ) {
-                               // Table doesn't yet exist, so it's safe to insert.
-                               logMsg( "$table doesn't exist, inserting or mode is INSERT" );
-                       $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
-                               continue;
-               }
-               
-                       // Prepare to test for potential violations. Get primary keys and unique indexes
-                       $mfields = array_merge( $fields, $rawfields );
-                       $keyFields = array_intersect( $ukeys, array_keys( $mfields ) );
-                       
-                       if( empty( $ukeys ) or count( $keyFields ) == 0 ) {
-                               // No unique keys in schema, so safe to insert
-                               logMsg( "Either schema or data has no unique keys, so safe to insert" );
-                               $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
-                               continue;
-                       }
-                       
-                       // Select record containing matching unique keys.
-                       $where = '';
-                       foreach( $ukeys as $key ) {
-                               if( isset( $mfields[$key] ) and $mfields[$key] ) {
-                                       if( $where ) $where .= ' AND ';
-                                       $where .= $key . ' = ' . $xmls->db->qstr( $mfields[$key] );
-                               }
-                       }
-                       $records = $xmls->db->Execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where );
-                       switch( $records->RecordCount() ) {
-                               case 0:
-                                       // No matching record, so safe to insert.
-                                       logMsg( "No matching records. Inserting new row with unique data" );
-                                       $sql[] = $xmls->db->GetInsertSQL( $records, $mfields );
-                                       break;
-                               case 1:
-                                       // Exactly one matching record, so we can update if the mode permits.
-                                       logMsg( "One matching record..." );
-                                       if( $mode == XMLS_MODE_UPDATE ) {
-                                               logMsg( "...Updating existing row from unique data" );
-                                               $sql[] = $xmls->db->GetUpdateSQL( $records, $mfields );
-                                       }
-                                       break;
-                               default:
-                                       // More than one matching record; the result is ambiguous, so we must ignore the row.
-                                       logMsg( "More than one matching record. Ignoring row." );
-                       }
-               }
-               return $sql;
-       }
-}
-
-/**
-* Creates the SQL to execute a list of provided SQL queries
-*
-* @package axmls
-* @access private
-*/
-class dbQuerySet extends dbObject {
-       
-       /**
-       * @var array    List of SQL queries
-       */
-       var $queries = array();
-       
-       /**
-       * @var string   String used to build of a query line by line
-       */
-       var $query;
-       
-       /**
-       * @var string   Query prefix key
-       */
-       var $prefixKey = '';
-       
-       /**
-       * @var boolean  Auto prefix enable (TRUE)
-       */
-       var $prefixMethod = 'AUTO';
-       
-       /**
-       * Initializes the query set.
-       *
-       * @param object $parent Parent object
-       * @param array $attributes Attributes
-       */
-       function dbQuerySet( &$parent, $attributes = NULL ) {
-               $this->parent =& $parent;
-                       
-               // Overrides the manual prefix key
-               if( isset( $attributes['KEY'] ) ) {
-                       $this->prefixKey = $attributes['KEY'];
-               }
-               
-               $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';
-               
-               // Enables or disables automatic prefix prepending
-               switch( $prefixMethod ) {
-                       case 'AUTO':
-                               $this->prefixMethod = 'AUTO';
-                               break;
-                       case 'MANUAL':
-                               $this->prefixMethod = 'MANUAL';
-                               break;
-                       case 'NONE':
-                               $this->prefixMethod = 'NONE';
-                               break;
-               }
-       }
-       
-       /**
-       * XML Callback to process start elements. Elements currently 
-       * processed are: QUERY. 
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               $this->currentElement = strtoupper( $tag );
-               
-               switch( $this->currentElement ) {
-                       case 'QUERY':
-                               // Create a new query in a SQL queryset.
-                               // Ignore this query set if a platform is specified and it's different than the 
-                               // current connection platform.
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       $this->newQuery();
-                               } else {
-                                       $this->discardQuery();
-                               }
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-               switch( $this->currentElement ) {
-                       // Line of queryset SQL data
-                       case 'QUERY':
-                               $this->buildQuery( $cdata );
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       */
-       function _tag_close( &$parser, $tag ) {
-               $this->currentElement = '';
-               
-               switch( strtoupper( $tag ) ) {
-                       case 'QUERY':
-                               // Add the finished query to the open query set.
-                               $this->addQuery();
-                               break;
-                       case 'SQL':
-                               $this->parent->addSQL( $this->create( $this->parent ) );
-                               xml_set_object( $parser, $this->parent );
-                               $this->destroy();
-                               break;
-                       default:
-                               
-               }
-       }
-       
-       /**
-       * Re-initializes the query.
-       *
-       * @return boolean TRUE
-       */
-       function newQuery() {
-               $this->query = '';
-               
-               return TRUE;
-       }
-       
-       /**
-       * Discards the existing query.
-       *
-       * @return boolean TRUE
-       */
-       function discardQuery() {
-               unset( $this->query );
-               
-               return TRUE;
-       }
-       
-       /** 
-       * Appends a line to a query that is being built line by line
-       *
-       * @param string $data Line of SQL data or NULL to initialize a new query
-       * @return string SQL query string.
-       */
-       function buildQuery( $sql = NULL ) {
-               if( !isset( $this->query ) OR empty( $sql ) ) {
-                       return FALSE;
-               }
-               
-               $this->query .= $sql;
-               
-               return $this->query;
-       }
-       
-       /**
-       * Adds a completed query to the query list
-       *
-       * @return string        SQL of added query
-       */
-       function addQuery() {
-               if( !isset( $this->query ) ) {
-                       return FALSE;
-               }
-               
-               $this->queries[] = $return = trim($this->query);
-               
-               unset( $this->query );
-               
-               return $return;
-       }
-       
-       /**
-       * Creates and returns the current query set
-       *
-       * @param object $xmls adoSchema object
-       * @return array Query set
-       */
-       function create( &$xmls ) {
-               foreach( $this->queries as $id => $query ) {
-                       switch( $this->prefixMethod ) {
-                               case 'AUTO':
-                                       // Enable auto prefix replacement
-                                       
-                                       // Process object prefix.
-                                       // Evaluate SQL statements to prepend prefix to objects
-                                       $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-                                       $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-                                       $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-                                       
-                                       // SELECT statements aren't working yet
-                                       #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
-                                       
-                               case 'MANUAL':
-                                       // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
-                                       // If prefixKey is not set, we use the default constant XMLS_PREFIX
-                                       if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
-                                               // Enable prefix override
-                                               $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
-                                       } else {
-                                               // Use default replacement
-                                               $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
-                                       }
-                       }
-                       
-                       $this->queries[$id] = trim( $query );
-               }
-               
-               // Return the query set array
-               return $this->queries;
-       }
-       
-       /**
-       * Rebuilds the query with the prefix attached to any objects
-       *
-       * @param string $regex Regex used to add prefix
-       * @param string $query SQL query string
-       * @param string $prefix Prefix to be appended to tables, indices, etc.
-       * @return string Prefixed SQL query string.
-       */
-       function prefixQuery( $regex, $query, $prefix = NULL ) {
-               if( !isset( $prefix ) ) {
-                       return $query;
-               }
-               
-               if( preg_match( $regex, $query, $match ) ) {
-                       $preamble = $match[1];
-                       $postamble = $match[5];
-                       $objectList = explode( ',', $match[3] );
-                       // $prefix = $prefix . '_';
-                       
-                       $prefixedList = '';
-                       
-                       foreach( $objectList as $object ) {
-                               if( $prefixedList !== '' ) {
-                                       $prefixedList .= ', ';
-                               }
-                               
-                               $prefixedList .= $prefix . trim( $object );
-                       }
-                       
-                       $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
-               }
-               
-               return $query;
-       }
-}
-
-/**
-* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
-* 
-* This class is used to load and parse the XML file, to create an array of SQL statements
-* that can be used to build a database, and to build the database using the SQL array.
-*
-* @tutorial getting_started.pkg
-*
-* @author Richard Tango-Lowy & Dan Cech
-* @version $Revision$
-*
-* @package axmls
-*/
-class adoSchema {
-       
-       /**
-       * @var array    Array containing SQL queries to generate all objects
-       * @access private
-       */
-       var $sqlArray;
-       
-       /**
-       * @var object   ADOdb connection object
-       * @access private
-       */
-       var $db;
-       
-       /**
-       * @var object   ADOdb Data Dictionary
-       * @access private
-       */
-       var $dict;
-       
-       /**
-       * @var string Current XML element
-       * @access private
-       */
-       var $currentElement = '';
-       
-       /**
-       * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
-       * @access private
-       */
-       var $upgrade = '';
-       
-       /**
-       * @var string Optional object prefix
-       * @access private
-       */
-       var $objectPrefix = '';
-       
-       /**
-       * @var long     Original Magic Quotes Runtime value
-       * @access private
-       */
-       var $mgq;
-       
-       /**
-       * @var long     System debug
-       * @access private
-       */
-       var $debug;
-       
-       /**
-       * @var string Regular expression to find schema version
-       * @access private
-       */
-       var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
-       
-       /**
-       * @var string Current schema version
-       * @access private
-       */
-       var $schemaVersion;
-       
-       /**
-       * @var int      Success of last Schema execution
-       */
-       var $success;
-       
-       /**
-       * @var bool     Execute SQL inline as it is generated
-       */
-       var $executeInline;
-       
-       /**
-       * @var bool     Continue SQL execution if errors occur
-       */
-       var $continueOnError;
-       
-       /**
-       * @var int      How to handle existing data rows (insert, update, or ignore)
-       */
-       var $existingData;
-       
-       /**
-       * Creates an adoSchema object
-       *
-       * Creating an adoSchema object is the first step in processing an XML schema.
-       * The only parameter is an ADOdb database connection object, which must already
-       * have been created.
-       *
-       * @param object $db ADOdb database connection object.
-       */
-       function adoSchema( &$db ) {
-               // Initialize the environment
-               $this->mgq = get_magic_quotes_runtime();
-               set_magic_quotes_runtime(0);
-               
-               $this->db =& $db;
-               $this->debug = $this->db->debug;
-               $this->dict = NewDataDictionary( $this->db );
-               $this->sqlArray = array();
-               $this->schemaVersion = XMLS_SCHEMA_VERSION;
-               $this->executeInline( XMLS_EXECUTE_INLINE );
-               $this->continueOnError( XMLS_CONTINUE_ON_ERROR );
-               $this->existingData( XMLS_EXISTING_DATA );
-               $this->setUpgradeMethod();
-       }
-       
-       /**
-       * Sets the method to be used for upgrading an existing database
-       *
-       * Use this method to specify how existing database objects should be upgraded.
-       * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
-       * alter each database object directly, REPLACE attempts to rebuild each object
-       * from scratch, BEST attempts to determine the best upgrade method for each
-       * object, and NONE disables upgrading.
-       *
-       * This method is not yet used by AXMLS, but exists for backward compatibility.
-       * The ALTER method is automatically assumed when the adoSchema object is
-       * instantiated; other upgrade methods are not currently supported.
-       *
-       * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
-       * @returns string Upgrade method used
-       */
-       function SetUpgradeMethod( $method = '' ) {
-               if( !is_string( $method ) ) {
-                       return FALSE;
-               }
-               
-               $method = strtoupper( $method );
-               
-               // Handle the upgrade methods
-               switch( $method ) {
-                       case 'ALTER':
-                               $this->upgrade = $method;
-                               break;
-                       case 'REPLACE':
-                               $this->upgrade = $method;
-                               break;
-                       case 'BEST':
-                               $this->upgrade = 'ALTER';
-                               break;
-                       case 'NONE':
-                               $this->upgrade = 'NONE';
-                               break;
-                       default:
-                               // Use default if no legitimate method is passed.
-                               $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
-               }
-               
-               return $this->upgrade;
-       }
-       
-       /**
-       * Specifies how to handle existing data row when there is a unique key conflict.
-       *
-       * The existingData setting specifies how the parser should handle existing rows
-       * when a unique key violation occurs during the insert. This can happen when inserting
-       * data into an existing table with one or more primary keys or unique indexes.
-       * The existingData method takes one of three options: XMLS_MODE_INSERT attempts
-       * to always insert the data as a new row. In the event of a unique key violation,
-       * the database will generate an error.  XMLS_MODE_UPDATE attempts to update the 
-       * any existing rows with the new data based upon primary or unique key fields in
-       * the schema. If the data row in the schema specifies no unique fields, the row
-       * data will be inserted as a new row. XMLS_MODE_IGNORE specifies that any data rows
-       * that would result in a unique key violation be ignored; no inserts or updates will
-       * take place. For backward compatibility, the default setting is XMLS_MODE_INSERT,
-       * but XMLS_MODE_UPDATE will generally be the most appropriate setting.
-       *
-       * @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE
-       * @return int current mode
-       */
-       function ExistingData( $mode = NULL ) {
-               if( is_int( $mode ) ) {
-                       switch( $mode ) {
-                               case XMLS_MODE_UPDATE:
-                                       $mode = XMLS_MODE_UPDATE;
-                                       break;
-                               case XMLS_MODE_IGNORE:
-                                       $mode = XMLS_MODE_IGNORE;
-                                       break;
-                               case XMLS_MODE_INSERT:
-                                       $mode = XMLS_MODE_INSERT;
-                                       break;
-                               default:
-                                       $mode = XMLS_EXISITNG_DATA;
-                                       break;
-                       }
-                       $this->existingData = $mode;
-               }
-               
-               return $this->existingData;
-       }
-       
-       /**
-       * Enables/disables inline SQL execution.
-       *
-       * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
-       * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
-       * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
-       * to apply the schema to the database.
-       *
-       * @param bool $mode execute
-       * @return bool current execution mode
-       *
-       * @see ParseSchema(), ExecuteSchema()
-       */
-       function ExecuteInline( $mode = NULL ) {
-               if( is_bool( $mode ) ) {
-                       $this->executeInline = $mode;
-               }
-               
-               return $this->executeInline;
-       }
-       
-       /**
-       * Enables/disables SQL continue on error.
-       *
-       * Call this method to enable or disable continuation of SQL execution if an error occurs.
-       * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
-       * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
-       * of the schema will continue.
-       *
-       * @param bool $mode execute
-       * @return bool current continueOnError mode
-       *
-       * @see addSQL(), ExecuteSchema()
-       */
-       function ContinueOnError( $mode = NULL ) {
-               if( is_bool( $mode ) ) {
-                       $this->continueOnError = $mode;
-               }
-               
-               return $this->continueOnError;
-       }
-       
-       /**
-       * Loads an XML schema from a file and converts it to SQL.
-       *
-       * Call this method to load the specified schema (see the DTD for the proper format) from
-       * the filesystem and generate the SQL necessary to create the database
-       * described. This method automatically converts the schema to the latest
-       * axmls schema version.
-       * @see ParseSchemaString()
-       *
-       * @param string $file Name of XML schema file.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute
-       */
-       function ParseSchema( $filename, $returnSchema = FALSE ) {
-               return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
-       }
-       
-       /**
-       * Loads an XML schema from a file and converts it to SQL.
-       *
-       * Call this method to load the specified schema directly from a file (see
-       * the DTD for the proper format) and generate the SQL necessary to create
-       * the database described by the schema. Use this method when you are dealing
-       * with large schema files. Otherwise, ParseSchema() is faster.
-       * This method does not automatically convert the schema to the latest axmls
-       * schema version. You must convert the schema manually using either the
-       * ConvertSchemaFile() or ConvertSchemaString() method.
-       * @see ParseSchema()
-       * @see ConvertSchemaFile()
-       * @see ConvertSchemaString()
-       *
-       * @param string $file Name of XML schema file.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute.
-       *
-       * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
-       * @see ParseSchema(), ParseSchemaString()
-       */
-       function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
-               // Open the file
-               if( !($fp = fopen( $filename, 'r' )) ) {
-                       logMsg( 'Unable to open file' );
-                       return FALSE;
-               }
-               
-               // do version detection here
-               if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
-                       logMsg( 'Invalid Schema Version' );
-                       return FALSE;
-               }
-               
-               if( $returnSchema ) {
-                       $xmlstring = '';
-                       while( $data = fread( $fp, 4096 ) ) {
-                               $xmlstring .= $data . "\n";
-                       }
-                       return $xmlstring;
-               }
-               
-               $this->success = 2;
-               
-               $xmlParser = $this->create_parser();
-               
-               // Process the file
-               while( $data = fread( $fp, 4096 ) ) {
-                       if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
-                               die( sprintf(
-                                       "XML error: %s at line %d",
-                                       xml_error_string( xml_get_error_code( $xmlParser) ),
-                                       xml_get_current_line_number( $xmlParser)
-                               ) );
-                       }
-               }
-               
-               xml_parser_free( $xmlParser );
-               
-               return $this->sqlArray;
-       }
-       
-       /**
-       * Converts an XML schema string to SQL.
-       *
-       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
-       * and generate the SQL necessary to create the database described by the schema. 
-       * @see ParseSchema()
-       *
-       * @param string $xmlstring XML schema string.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute.
-       */
-       function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
-               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
-                       logMsg( 'Empty or Invalid Schema' );
-                       return FALSE;
-               }
-               
-               // do version detection here
-               if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
-                       logMsg( 'Invalid Schema Version' );
-                       return FALSE;
-               }
-               
-               if( $returnSchema ) {
-                       return $xmlstring;
-               }
-               
-               $this->success = 2;
-               
-               $xmlParser = $this->create_parser();
-               
-               if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
-                       die( sprintf(
-                               "XML error: %s at line %d",
-                               xml_error_string( xml_get_error_code( $xmlParser) ),
-                               xml_get_current_line_number( $xmlParser)
-                       ) );
-               }
-               
-               xml_parser_free( $xmlParser );
-               
-               return $this->sqlArray;
-       }
-       
-       /**
-       * Loads an XML schema from a file and converts it to uninstallation SQL.
-       *
-       * Call this method to load the specified schema (see the DTD for the proper format) from
-       * the filesystem and generate the SQL necessary to remove the database described.
-       * @see RemoveSchemaString()
-       *
-       * @param string $file Name of XML schema file.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute
-       */
-       function RemoveSchema( $filename, $returnSchema = FALSE ) {
-               return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
-       }
-       
-       /**
-       * Converts an XML schema string to uninstallation SQL.
-       *
-       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
-       * and generate the SQL necessary to uninstall the database described by the schema. 
-       * @see RemoveSchema()
-       *
-       * @param string $schema XML schema string.
-       * @param bool $returnSchema Return schema rather than parsing.
-       * @return array Array of SQL queries, ready to execute.
-       */
-       function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
-               
-               // grab current version
-               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
-                       return FALSE;
-               }
-               
-               return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
-       }
-       
-       /**
-       * Applies the current XML schema to the database (post execution).
-       *
-       * Call this method to apply the current schema (generally created by calling 
-       * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes, 
-       * and executing other SQL specified in the schema) after parsing.
-       * @see ParseSchema(), ParseSchemaString(), ExecuteInline()
-       *
-       * @param array $sqlArray Array of SQL statements that will be applied rather than
-       *               the current schema.
-       * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
-       * @returns integer 0 if failure, 1 if errors, 2 if successful.
-       */
-       function ExecuteSchema( $sqlArray = NULL, $continueOnErr =  NULL ) {
-               if( !is_bool( $continueOnErr ) ) {
-                       $continueOnErr = $this->ContinueOnError();
-               }
-               
-               if( !isset( $sqlArray ) ) {
-                       $sqlArray = $this->sqlArray;
-               }
-               
-               if( !is_array( $sqlArray ) ) {
-                       $this->success = 0;
-               } else {
-                       $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
-               }
-               
-               return $this->success;
-       }
-       
-       /**
-       * Returns the current SQL array. 
-       *
-       * Call this method to fetch the array of SQL queries resulting from 
-       * ParseSchema() or ParseSchemaString(). 
-       *
-       * @param string $format Format: HTML, TEXT, or NONE (PHP array)
-       * @return array Array of SQL statements or FALSE if an error occurs
-       */
-       function PrintSQL( $format = 'NONE' ) {
-               $sqlArray = null;
-               return $this->getSQL( $format, $sqlArray );
-       }
-       
-       /**
-       * Saves the current SQL array to the local filesystem as a list of SQL queries.
-       *
-       * Call this method to save the array of SQL queries (generally resulting from a
-       * parsed XML schema) to the filesystem.
-       *
-       * @param string $filename Path and name where the file should be saved.
-       * @return boolean TRUE if save is successful, else FALSE. 
-       */
-       function SaveSQL( $filename = './schema.sql' ) {
-               
-               if( !isset( $sqlArray ) ) {
-                       $sqlArray = $this->sqlArray;
-               }
-               if( !isset( $sqlArray ) ) {
-                       return FALSE;
-               }
-               
-               $fp = fopen( $filename, "w" );
-               
-               foreach( $sqlArray as $key => $query ) {
-                       fwrite( $fp, $query . ";\n" );
-               }
-               fclose( $fp );
-       }
-       
-       /**
-       * Create an xml parser
-       *
-       * @return object PHP XML parser object
-       *
-       * @access private
-       */
-       function &create_parser() {
-               // Create the parser
-               $xmlParser = xml_parser_create();
-               xml_set_object( $xmlParser, $this );
-               
-               // Initialize the XML callback functions
-               xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
-               xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
-               
-               return $xmlParser;
-       }
-       
-       /**
-       * XML Callback to process start elements
-       *
-       * @access private
-       */
-       function _tag_open( &$parser, $tag, $attributes ) {
-               switch( strtoupper( $tag ) ) {
-                       case 'TABLE':
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                               $this->obj = new dbTable( $this, $attributes );
-                               xml_set_object( $parser, $this->obj );
-                               }
-                               break;
-                       case 'SQL':
-                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
-                                       $this->obj = new dbQuerySet( $this, $attributes );
-                                       xml_set_object( $parser, $this->obj );
-                               }
-                               break;
-                       default:
-                               // print_r( array( $tag, $attributes ) );
-               }
-               
-       }
-       
-       /**
-       * XML Callback to process CDATA elements
-       *
-       * @access private
-       */
-       function _tag_cdata( &$parser, $cdata ) {
-       }
-       
-       /**
-       * XML Callback to process end elements
-       *
-       * @access private
-       * @internal
-       */
-       function _tag_close( &$parser, $tag ) {
-               
-       }
-       
-       /**
-       * Converts an XML schema string to the specified DTD version.
-       *
-       * Call this method to convert a string containing an XML schema to a different AXMLS
-       * DTD version. For instance, to convert a schema created for an pre-1.0 version for 
-       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version 
-       * parameter is specified, the schema will be converted to the current DTD version. 
-       * If the newFile parameter is provided, the converted schema will be written to the specified
-       * file.
-       * @see ConvertSchemaFile()
-       *
-       * @param string $schema String containing XML schema that will be converted.
-       * @param string $newVersion DTD version to convert to.
-       * @param string $newFile File name of (converted) output file.
-       * @return string Converted XML schema or FALSE if an error occurs.
-       */
-       function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
-               
-               // grab current version
-               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
-                       return FALSE;
-               }
-               
-               if( !isset ($newVersion) ) {
-                       $newVersion = $this->schemaVersion;
-               }
-               
-               if( $version == $newVersion ) {
-                       $result = $schema;
-               } else {
-                       $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
-               }
-               
-               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
-                       fwrite( $fp, $result );
-                       fclose( $fp );
-               }
-               
-               return $result;
-       }
-
-       /*
-       // compat for pre-4.3 - jlim
-       function _file_get_contents($path)
-       {
-               if (function_exists('file_get_contents')) return file_get_contents($path);
-               return join('',file($path));
-       }*/
-       
-       /**
-       * Converts an XML schema file to the specified DTD version.
-       *
-       * Call this method to convert the specified XML schema file to a different AXMLS
-       * DTD version. For instance, to convert a schema created for an pre-1.0 version for 
-       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version 
-       * parameter is specified, the schema will be converted to the current DTD version. 
-       * If the newFile parameter is provided, the converted schema will be written to the specified
-       * file.
-       * @see ConvertSchemaString()
-       *
-       * @param string $filename Name of XML schema file that will be converted.
-       * @param string $newVersion DTD version to convert to.
-       * @param string $newFile File name of (converted) output file.
-       * @return string Converted XML schema or FALSE if an error occurs.
-       */
-       function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
-               
-               // grab current version
-               if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
-                       return FALSE;
-               }
-               
-               if( !isset ($newVersion) ) {
-                       $newVersion = $this->schemaVersion;
-               }
-               
-               if( $version == $newVersion ) {
-                       $result = _file_get_contents( $filename );
-                       
-                       // remove unicode BOM if present
-                       if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
-                               $result = substr( $result, 3 );
-                       }
-               } else {
-                       $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
-               }
-               
-               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
-                       fwrite( $fp, $result );
-                       fclose( $fp );
-               }
-               
-               return $result;
-       }
-       
-       function TransformSchema( $schema, $xsl, $schematype='string' )
-       {
-               // Fail if XSLT extension is not available
-               if( ! function_exists( 'xslt_create' ) ) {
-                       return FALSE;
-               }
-               
-               $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
-               
-               // look for xsl
-               if( !is_readable( $xsl_file ) ) {
-                       return FALSE;
-               }
-               
-               switch( $schematype )
-               {
-                       case 'file':
-                               if( !is_readable( $schema ) ) {
-                                       return FALSE;
-                               }
-                               
-                               $schema = _file_get_contents( $schema );
-                               break;
-                       case 'string':
-                       default:
-                               if( !is_string( $schema ) ) {
-                                       return FALSE;
-                               }
-               }
-               
-               $arguments = array (
-                       '/_xml' => $schema,
-                       '/_xsl' => _file_get_contents( $xsl_file )
-               );
-               
-               // create an XSLT processor
-               $xh = xslt_create ();
-               
-               // set error handler
-               xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
-               
-               // process the schema
-               $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); 
-               
-               xslt_free ($xh);
-               
-               return $result;
-       }
-       
-       /**
-       * Processes XSLT transformation errors
-       *
-       * @param object $parser XML parser object
-       * @param integer $errno Error number
-       * @param integer $level Error level
-       * @param array $fields Error information fields
-       *
-       * @access private
-       */
-       function xslt_error_handler( $parser, $errno, $level, $fields ) {
-               if( is_array( $fields ) ) {
-                       $msg = array(
-                               'Message Type' => ucfirst( $fields['msgtype'] ),
-                               'Message Code' => $fields['code'],
-                               'Message' => $fields['msg'],
-                               'Error Number' => $errno,
-                               'Level' => $level
-                       );
-                       
-                       switch( $fields['URI'] ) {
-                               case 'arg:/_xml':
-                                       $msg['Input'] = 'XML';
-                                       break;
-                               case 'arg:/_xsl':
-                                       $msg['Input'] = 'XSL';
-                                       break;
-                               default:
-                                       $msg['Input'] = $fields['URI'];
-                       }
-                       
-                       $msg['Line'] = $fields['line'];
-               } else {
-                       $msg = array(
-                               'Message Type' => 'Error',
-                               'Error Number' => $errno,
-                               'Level' => $level,
-                               'Fields' => var_export( $fields, TRUE )
-                       );
-               }
-               
-               $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
-                                          . '<table>' . "\n";
-               
-               foreach( $msg as $label => $details ) {
-                       $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
-               }
-               
-               $error_details .= '</table>';
-               
-               trigger_error( $error_details, E_USER_ERROR );
-       }
-       
-       /**
-       * Returns the AXMLS Schema Version of the requested XML schema file.
-       *
-       * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
-       * @see SchemaStringVersion()
-       *
-       * @param string $filename AXMLS schema file
-       * @return string Schema version number or FALSE on error
-       */
-       function SchemaFileVersion( $filename ) {
-               // Open the file
-               if( !($fp = fopen( $filename, 'r' )) ) {
-                       // die( 'Unable to open file' );
-                       return FALSE;
-               }
-               
-               // Process the file
-               while( $data = fread( $fp, 4096 ) ) {
-                       if( preg_match( $this->versionRegex, $data, $matches ) ) {
-                               return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
-                       }
-               }
-               
-               return FALSE;
-       }
-       
-       /**
-       * Returns the AXMLS Schema Version of the provided XML schema string.
-       *
-       * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
-       * @see SchemaFileVersion()
-       *
-       * @param string $xmlstring XML schema string
-       * @return string Schema version number or FALSE on error
-       */
-       function SchemaStringVersion( $xmlstring ) {
-               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
-                       return FALSE;
-               }
-               
-               if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
-                       return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
-               }
-               
-               return FALSE;
-       }
-       
-       /**
-       * Extracts an XML schema from an existing database.
-       *
-       * Call this method to create an XML schema string from an existing database.
-       * If the data parameter is set to TRUE, AXMLS will include the data from the database
-       * in the schema. 
-       *
-       * @param boolean $data Include data in schema dump
-       * @indent string indentation to use
-       * @prefix string extract only tables with given prefix
-       * @stripprefix strip prefix string when storing in XML schema
-       * @return string Generated XML schema
-       */
-       function ExtractSchema( $data = FALSE, $indent = '  ', $prefix = '' , $stripprefix=false) {
-               $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
-               
-               $schema = '<?xml version="1.0"?>' . "\n"
-                               . '<schema version="' . $this->schemaVersion . '">' . "\n";
-               
-               if( is_array( $tables = $this->db->MetaTables( 'TABLES' , ($prefix) ? $prefix.'%' : '') ) ) {
-                       foreach( $tables as $table ) {
-                               if ($stripprefix) $table = str_replace(str_replace('\\_', '_', $pfx ), '', $table);
-                               $schema .= $indent . '<table name="' . htmlentities( $table ) . '">' . "\n";
-                               
-                               // grab details from database
-                               $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE -1' );
-                               $fields = $this->db->MetaColumns( $table );
-                               $indexes = $this->db->MetaIndexes( $table );
-                               
-                               if( is_array( $fields ) ) {
-                                       foreach( $fields as $details ) {
-                                               $extra = '';
-                                               $content = array();
-                                               
-                                               if( isset($details->max_length) && $details->max_length > 0 ) {
-                                                       $extra .= ' size="' . $details->max_length . '"';
-                                               }
-                                               
-                                               if( isset($details->primary_key) && $details->primary_key ) {
-                                                       $content[] = '<KEY/>';
-                                               } elseif( isset($details->not_null) && $details->not_null ) {
-                                                       $content[] = '<NOTNULL/>';
-                                               }
-                                               
-                                               if( isset($details->has_default) && $details->has_default ) {
-                                                       $content[] = '<DEFAULT value="' . htmlentities( $details->default_value ) . '"/>';
-                                               }
-                                               
-                                               if( isset($details->auto_increment) && $details->auto_increment ) {
-                                                       $content[] = '<AUTOINCREMENT/>';
-                                               }
-                                               
-                                               if( isset($details->unsigned) && $details->unsigned ) {
-                                                       $content[] = '<UNSIGNED/>';
-                                               }
-                                               
-                                               // this stops the creation of 'R' columns,
-                                               // AUTOINCREMENT is used to create auto columns
-                                               $details->primary_key = 0;
-                                               $type = $rs->MetaType( $details );
-                                               
-                                               $schema .= str_repeat( $indent, 2 ) . '<field name="' . htmlentities( $details->name ) . '" type="' . $type . '"' . $extra;
-                                               
-                                               if( !empty( $content ) ) {
-                                                       $schema .= ">\n" . str_repeat( $indent, 3 )
-                                                                        . implode( "\n" . str_repeat( $indent, 3 ), $content ) . "\n"
-                                                                        . str_repeat( $indent, 2 ) . '</field>' . "\n";
-                                               } else {
-                                                       $schema .= "/>\n";
-                                               }
-                                       }
-                               }
-                               
-                               if( is_array( $indexes ) ) {
-                                       foreach( $indexes as $index => $details ) {
-                                               $schema .= str_repeat( $indent, 2 ) . '<index name="' . $index . '">' . "\n";
-                                               
-                                               if( $details['unique'] ) {
-                                                       $schema .= str_repeat( $indent, 3 ) . '<UNIQUE/>' . "\n";
-                                               }
-                                               
-                                               foreach( $details['columns'] as $column ) {
-                                                       $schema .= str_repeat( $indent, 3 ) . '<col>' . htmlentities( $column ) . '</col>' . "\n";
-                                               }
-                                               
-                                               $schema .= str_repeat( $indent, 2 ) . '</index>' . "\n";
-                                       }
-                               }
-                               
-                               if( $data ) {
-                                       $rs = $this->db->Execute( 'SELECT * FROM ' . $table );
-                                       
-                                       if( is_object( $rs ) && !$rs->EOF ) {
-                                               $schema .= str_repeat( $indent, 2 ) . "<data>\n";
-                                               
-                                               while( $row = $rs->FetchRow() ) {
-                                                       foreach( $row as $key => $val ) {
-                                                               if ( $val != htmlentities( $val ) ) {
-                                                                       $row[$key] = '<![CDATA[' . $val . ']]>';
-                                                               }
-                                                       }
-                                                       
-                                                       $schema .= str_repeat( $indent, 3 ) . '<row><f>' . implode( '</f><f>', $row ) . "</f></row>\n";
-                                               }
-                                               
-                                               $schema .= str_repeat( $indent, 2 ) . "</data>\n";
-                                       }
-                               }
-                               
-                               $schema .= $indent . "</table>\n";
-                       }
-               }
-               
-               $this->db->SetFetchMode( $old_mode );
-               
-               $schema .= '</schema>';
-               return $schema;
-       }
-       
-       /**
-       * Sets a prefix for database objects
-       *
-       * Call this method to set a standard prefix that will be prepended to all database tables 
-       * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
-       *
-       * @param string $prefix Prefix that will be prepended.
-       * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
-       * @return boolean TRUE if successful, else FALSE
-       */
-       function SetPrefix( $prefix = '', $underscore = TRUE ) {
-               switch( TRUE ) {
-                       // clear prefix
-                       case empty( $prefix ):
-                               logMsg( 'Cleared prefix' );
-                               $this->objectPrefix = '';
-                               return TRUE;
-                       // prefix too long
-                       case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
-                       // prefix contains invalid characters
-                       case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
-                               logMsg( 'Invalid prefix: ' . $prefix );
-                               return FALSE;
-               }
-               
-               if( $underscore AND substr( $prefix, -1 ) != '_' ) {
-                       $prefix .= '_';
-               }
-               
-               // prefix valid
-               logMsg( 'Set prefix: ' . $prefix );
-               $this->objectPrefix = $prefix;
-               return TRUE;
-       }
-       
-       /**
-       * Returns an object name with the current prefix prepended.
-       *
-       * @param string $name Name
-       * @return string        Prefixed name
-       *
-       * @access private
-       */
-       function prefix( $name = '' ) {
-               // if prefix is set
-               if( !empty( $this->objectPrefix ) ) {
-                       // Prepend the object prefix to the table name
-                       // prepend after quote if used
-                       return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
-               }
-               
-               // No prefix set. Use name provided.
-               return $name;
-       }
-       
-       /**
-       * Checks if element references a specific platform
-       *
-       * @param string $platform Requested platform
-       * @returns boolean TRUE if platform check succeeds
-       *
-       * @access private
-       */
-       function supportedPlatform( $platform = NULL ) {
-               if( !empty( $platform ) ) {
-                       $regex = '/(^|\|)' . $this->db->databaseType . '(\||$)/i';
-               
-                       if( preg_match( '/^- /', $platform ) ) {
-                               if (preg_match ( $regex, substr( $platform, 2 ) ) ) {
-                                       logMsg( 'Platform ' . $platform . ' is NOT supported' );
-                                       return FALSE;
-                               }
-               } else {
-                               if( !preg_match ( $regex, $platform ) ) {
-                                       logMsg( 'Platform ' . $platform . ' is NOT supported' );
-                       return FALSE;
-               }
-       }
-               }
-               
-               logMsg( 'Platform ' . $platform . ' is supported' );
-               return TRUE;
-       }
-       
-       /**
-       * Clears the array of generated SQL.
-       *
-       * @access private
-       */
-       function clearSQL() {
-               $this->sqlArray = array();
-       }
-       
-       /**
-       * Adds SQL into the SQL array.
-       *
-       * @param mixed $sql SQL to Add
-       * @return boolean TRUE if successful, else FALSE.
-       *
-       * @access private
-       */      
-       function addSQL( $sql = NULL ) {
-               if( is_array( $sql ) ) {
-                       foreach( $sql as $line ) {
-                               $this->addSQL( $line );
-                       }
-                       
-                       return TRUE;
-               }
-               
-               if( is_string( $sql ) ) {
-                       $this->sqlArray[] = $sql;
-                       
-                       // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
-                       if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
-                               $saved = $this->db->debug;
-                               $this->db->debug = $this->debug;
-                               $ok = $this->db->Execute( $sql );
-                               $this->db->debug = $saved;
-                               
-                               if( !$ok ) {
-                                       if( $this->debug ) {
-                                               ADOConnection::outp( $this->db->ErrorMsg() );
-                                       }
-                                       
-                                       $this->success = 1;
-                               }
-                       }
-                       
-                       return TRUE;
-               }
-               
-               return FALSE;
-       }
-       
-       /**
-       * Gets the SQL array in the specified format.
-       *
-       * @param string $format Format
-       * @return mixed SQL
-       *       
-       * @access private
-       */
-       function getSQL( $format = NULL, $sqlArray = NULL ) {
-               if( !is_array( $sqlArray ) ) {
-                       $sqlArray = $this->sqlArray;
-               }
-               
-               if( !is_array( $sqlArray ) ) {
-                       return FALSE;
-               }
-               
-               switch( strtolower( $format ) ) {
-                       case 'string':
-                       case 'text':
-                               return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
-                       case'html':
-                               return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
-               }
-               
-               return $this->sqlArray;
-       }
-       
-       /**
-       * Destroys an adoSchema object.
-       *
-       * Call this method to clean up after an adoSchema object that is no longer in use.
-       * @deprecated adoSchema now cleans up automatically.
-       */
-       function Destroy() {
-               set_magic_quotes_runtime( $this->mgq );
-               unset( $this );
-       }
-}
-
-/**
-* Message logging function
-*
-* @access private
-*/
-function logMsg( $msg, $title = NULL, $force = FALSE ) {
-       if( XMLS_DEBUG or $force ) {
-               echo '<pre>';
-               
-               if( isset( $title ) ) {
-                       echo '<h3>' . htmlentities( $title ) . '</h3>';
-               }
-               
-               if( @is_object( $this ) ) {
-                       echo '[' . get_class( $this ) . '] ';
-               }
-               
-               print_r( $msg );
-               
-               echo '</pre>';
-       }
-}
+<?php\r
+// Copyright (c) 2004-2005 ars Cognita Inc., all rights reserved\r
+/* ******************************************************************************\r
+    Released under both BSD license and Lesser GPL library license. \r
+       Whenever there is any discrepancy between the two licenses, \r
+       the BSD license will take precedence. \r
+*******************************************************************************/\r
+/**\r
+ * xmlschema is a class that allows the user to quickly and easily\r
+ * build a database on any ADOdb-supported platform using a simple\r
+ * XML schema.\r
+ *\r
+ * Last Editor: $Author$\r
+ * @author Richard Tango-Lowy & Dan Cech\r
+ * @version $Revision$\r
+ *\r
+ * @package axmls\r
+ * @tutorial getting_started.pkg\r
+ */\r
\r
+function _file_get_contents($file) \r
+{\r
+       if (function_exists('file_get_contents')) return file_get_contents($file);\r
+       \r
+       $f = fopen($file,'r');\r
+       if (!$f) return '';\r
+       $t = '';\r
+       \r
+       while ($s = fread($f,100000)) $t .= $s;\r
+       fclose($f);\r
+       return $t;\r
+}\r
+\r
+\r
+/**\r
+* Debug on or off\r
+*/\r
+if( !defined( 'XMLS_DEBUG' ) ) {\r
+       define( 'XMLS_DEBUG', FALSE );\r
+}\r
+\r
+/**\r
+* Default prefix key\r
+*/\r
+if( !defined( 'XMLS_PREFIX' ) ) {\r
+       define( 'XMLS_PREFIX', '%%P' );\r
+}\r
+\r
+/**\r
+* Maximum length allowed for object prefix\r
+*/\r
+if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {\r
+       define( 'XMLS_PREFIX_MAXLEN', 10 );\r
+}\r
+\r
+/**\r
+* Execute SQL inline as it is generated\r
+*/\r
+if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {\r
+       define( 'XMLS_EXECUTE_INLINE', FALSE );\r
+}\r
+\r
+/**\r
+* Continue SQL Execution if an error occurs?\r
+*/\r
+if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {\r
+       define( 'XMLS_CONTINUE_ON_ERROR', FALSE );\r
+}\r
+\r
+/**\r
+* Current Schema Version\r
+*/\r
+if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {\r
+       define( 'XMLS_SCHEMA_VERSION', '0.3' );\r
+}\r
+\r
+/**\r
+* Default Schema Version.  Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {\r
+       define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );\r
+}\r
+\r
+/**\r
+* How to handle data rows that already exist in a database during and upgrade.\r
+* Options are INSERT (attempts to insert duplicate rows), UPDATE (updates existing\r
+* rows) and IGNORE (ignores existing rows).\r
+*/\r
+if( !defined( 'XMLS_MODE_INSERT' ) ) {\r
+       define( 'XMLS_MODE_INSERT', 0 );\r
+}\r
+if( !defined( 'XMLS_MODE_UPDATE' ) ) {\r
+       define( 'XMLS_MODE_UPDATE', 1 );\r
+}\r
+if( !defined( 'XMLS_MODE_IGNORE' ) ) {\r
+       define( 'XMLS_MODE_IGNORE', 2 );\r
+}\r
+if( !defined( 'XMLS_EXISTING_DATA' ) ) {\r
+       define( 'XMLS_EXISTING_DATA', XMLS_MODE_INSERT );\r
+}\r
+\r
+/**\r
+* Default Schema Version.  Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {\r
+       define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );\r
+}\r
+\r
+/**\r
+* Include the main ADODB library\r
+*/\r
+if( !defined( '_ADODB_LAYER' ) ) {\r
+       require( 'adodb.inc.php' );\r
+       require( 'adodb-datadict.inc.php' );\r
+}\r
+\r
+/**\r
+* Abstract DB Object. This class provides basic methods for database objects, such\r
+* as tables and indexes.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbObject {\r
+       \r
+       /**\r
+       * var object Parent\r
+       */\r
+       var $parent;\r
+       \r
+       /**\r
+       * var string current element\r
+       */\r
+       var $currentElement;\r
+       \r
+       /**\r
+       * NOP\r
+       */\r
+       function dbObject( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               \r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               \r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               \r
+       }\r
+       \r
+       function create() {\r
+               return array();\r
+       }\r
+       \r
+       /**\r
+       * Destroys the object\r
+       */\r
+       function destroy() {\r
+               unset( $this );\r
+       }\r
+       \r
+       /**\r
+       * Checks whether the specified RDBMS is supported by the current\r
+       * database object or its ranking ancestor.\r
+       *\r
+       * @param string $platform RDBMS platform name (from ADODB platform list).\r
+       * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.\r
+       */\r
+       function supportedPlatform( $platform = NULL ) {\r
+               return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;\r
+       }\r
+       \r
+       /**\r
+       * Returns the prefix set by the ranking ancestor of the database object.\r
+       *\r
+       * @param string $name Prefix string.\r
+       * @return string Prefix.\r
+       */\r
+       function prefix( $name = '' ) {\r
+               return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;\r
+       }\r
+       \r
+       /**\r
+       * Extracts a field ID from the specified field.\r
+       *\r
+       * @param string $field Field.\r
+       * @return string Field ID.\r
+       */\r
+       function FieldID( $field ) {\r
+               return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );\r
+       }\r
+}\r
+\r
+/**\r
+* Creates a table object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database table. As charactaristics\r
+* of the table are loaded from the external source, methods and properties\r
+* of this class are used to build up the table description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbTable extends dbObject {\r
+       \r
+       /**\r
+       * @var string Table name\r
+       */\r
+       var $name;\r
+       \r
+       /**\r
+       * @var array Field specifier: Meta-information about each field\r
+       */\r
+       var $fields = array();\r
+       \r
+       /**\r
+       * @var array List of table indexes.\r
+       */\r
+       var $indexes = array();\r
+       \r
+       /**\r
+       * @var array Table options: Table-level options\r
+       */\r
+       var $opts = array();\r
+       \r
+       /**\r
+       * @var string Field index: Keeps track of which field is currently being processed\r
+       */\r
+       var $current_field;\r
+       \r
+       /**\r
+       * @var boolean Mark table for destruction\r
+       * @access private\r
+       */\r
+       var $drop_table;\r
+       \r
+       /**\r
+       * @var boolean Mark field for destruction (not yet implemented)\r
+       * @access private\r
+       */\r
+       var $drop_field = array();\r
+       \r
+       /**\r
+       * @var array Platform-specific options\r
+       * @access private\r
+       */\r
+       var $currentPlatform = true;\r
+       \r
+       \r
+       /**\r
+       * Iniitializes a new table object.\r
+       *\r
+       * @param string $prefix DB Object prefix\r
+       * @param array $attributes Array of table attributes.\r
+       */\r
+       function dbTable( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+               $this->name = $this->prefix($attributes['NAME']);\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements. Elements currently \r
+       * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT. \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'INDEX':\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       xml_set_object( $parser, $this->addIndex( $attributes ) );\r
+                               }\r
+                               break;\r
+                       case 'DATA':\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       xml_set_object( $parser, $this->addData( $attributes ) );\r
+                               }\r
+                               break;\r
+                       case 'DROP':\r
+                               $this->drop();\r
+                               break;\r
+                       case 'FIELD':\r
+                               // Add a field\r
+                               $fieldName = $attributes['NAME'];\r
+                               $fieldType = $attributes['TYPE'];\r
+                               $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;\r
+                               $fieldOpts = !empty( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;\r
+                               \r
+                               $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );\r
+                               break;\r
+                       case 'KEY':\r
+                       case 'NOTNULL':\r
+                       case 'AUTOINCREMENT':\r
+                       case 'DEFDATE':\r
+                       case 'DEFTIMESTAMP':\r
+                       case 'UNSIGNED':\r
+                               // Add a field option\r
+                               $this->addFieldOpt( $this->current_field, $this->currentElement );\r
+                               break;\r
+                       case 'DEFAULT':\r
+                               // Add a field option to the table object\r
+                               \r
+                               // Work around ADOdb datadict issue that misinterprets empty strings.\r
+                               if( $attributes['VALUE'] == '' ) {\r
+                                       $attributes['VALUE'] = " '' ";\r
+                               }\r
+                               \r
+                               $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );\r
+                               break;\r
+                       case 'OPT':\r
+                       case 'CONSTRAINT':\r
+                               // Accept platform-specific options\r
+                               $this->currentPlatform = ( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) );\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Table/field constraint\r
+                       case 'CONSTRAINT':\r
+                               if( isset( $this->current_field ) ) {\r
+                                       $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );\r
+                               } else {\r
+                                       $this->addTableOpt( $cdata );\r
+                               }\r
+                               break;\r
+                       // Table/field option\r
+                       case 'OPT':\r
+                               if( isset( $this->current_field ) ) {\r
+                                       $this->addFieldOpt( $this->current_field, $cdata );\r
+                               } else {\r
+                               $this->addTableOpt( $cdata );\r
+                               }\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'TABLE':\r
+                               $this->parent->addSQL( $this->create( $this->parent ) );\r
+                               xml_set_object( $parser, $this->parent );\r
+                               $this->destroy();\r
+                               break;\r
+                       case 'FIELD':\r
+                               unset($this->current_field);\r
+                               break;\r
+                       case 'OPT':\r
+                       case 'CONSTRAINT':\r
+                               $this->currentPlatform = true;\r
+                               break;\r
+                       default:\r
+\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds an index to a table object\r
+       *\r
+       * @param array $attributes Index attributes\r
+       * @return object dbIndex object\r
+       */\r
+       function addIndex( $attributes ) {\r
+               $name = strtoupper( $attributes['NAME'] );\r
+               $this->indexes[$name] = new dbIndex( $this, $attributes );\r
+               return $this->indexes[$name];\r
+       }\r
+       \r
+       /**\r
+       * Adds data to a table object\r
+       *\r
+       * @param array $attributes Data attributes\r
+       * @return object dbData object\r
+       */\r
+       function addData( $attributes ) {\r
+               if( !isset( $this->data ) ) {\r
+                       $this->data = new dbData( $this, $attributes );\r
+               }\r
+               return $this->data;\r
+       }\r
+       \r
+       /**\r
+       * Adds a field to a table object\r
+       *\r
+       * $name is the name of the table to which the field should be added. \r
+       * $type is an ADODB datadict field type. The following field types\r
+       * are supported as of ADODB 3.40:\r
+       *       - C:  varchar\r
+       *       - X:  CLOB (character large object) or largest varchar size\r
+       *          if CLOB is not supported\r
+       *       - C2: Multibyte varchar\r
+       *       - X2: Multibyte CLOB\r
+       *       - B:  BLOB (binary large object)\r
+       *       - D:  Date (some databases do not support this, and we return a datetime type)\r
+       *       - T:  Datetime or Timestamp\r
+       *       - L:  Integer field suitable for storing booleans (0 or 1)\r
+       *       - I:  Integer (mapped to I4)\r
+       *       - I1: 1-byte integer\r
+       *       - I2: 2-byte integer\r
+       *       - I4: 4-byte integer\r
+       *       - I8: 8-byte integer\r
+       *       - F:  Floating point number\r
+       *       - N:  Numeric or decimal number\r
+       *\r
+       * @param string $name Name of the table to which the field will be added.\r
+       * @param string $type   ADODB datadict field type.\r
+       * @param string $size   Field size\r
+       * @param array $opts    Field options array\r
+       * @return array Field specifier array\r
+       */\r
+       function addField( $name, $type, $size = NULL, $opts = NULL ) {\r
+               $field_id = $this->FieldID( $name );\r
+               \r
+               // Set the field index so we know where we are\r
+               $this->current_field = $field_id;\r
+               \r
+               // Set the field name (required)\r
+               $this->fields[$field_id]['NAME'] = $name;\r
+               \r
+               // Set the field type (required)\r
+               $this->fields[$field_id]['TYPE'] = $type;\r
+               \r
+               // Set the field size (optional)\r
+               if( isset( $size ) ) {\r
+                       $this->fields[$field_id]['SIZE'] = $size;\r
+               }\r
+               \r
+               // Set the field options\r
+               if( isset( $opts ) ) {\r
+                       $this->fields[$field_id]['OPTS'] = array($opts);\r
+               } else {\r
+                       $this->fields[$field_id]['OPTS'] = array();\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds a field option to the current field specifier\r
+       *\r
+       * This method adds a field option allowed by the ADOdb datadict \r
+       * and appends it to the given field.\r
+       *\r
+       * @param string $field  Field name\r
+       * @param string $opt ADOdb field option\r
+       * @param mixed $value Field option value\r
+       * @return array Field specifier array\r
+       */\r
+       function addFieldOpt( $field, $opt, $value = NULL ) {\r
+               if( $this->currentPlatform ) {\r
+               if( !isset( $value ) ) {\r
+                       $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;\r
+               // Add the option and value\r
+               } else {\r
+                       $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );\r
+               }\r
+       }\r
+       }\r
+       \r
+       /**\r
+       * Adds an option to the table\r
+       *\r
+       * This method takes a comma-separated list of table-level options\r
+       * and appends them to the table object.\r
+       *\r
+       * @param string $opt Table option\r
+       * @return array Options\r
+       */\r
+       function addTableOpt( $opt ) {\r
+               if( $this->currentPlatform ) {\r
+               $this->opts[] = $opt;\r
+               }\r
+               return $this->opts;\r
+       }\r
+       \r
+       /**\r
+       * Generates the SQL that will create the table in the database\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Array containing table creation SQL\r
+       */\r
+       function create( &$xmls ) {\r
+               $sql = array();\r
+               \r
+               // drop any existing indexes\r
+               if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {\r
+                       foreach( $legacy_indexes as $index => $index_details ) {\r
+                               $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );\r
+                       }\r
+               }\r
+               \r
+               // remove fields to be dropped from table object\r
+               foreach( $this->drop_field as $field ) {\r
+                       unset( $this->fields[$field] );\r
+               }\r
+               \r
+               // if table exists\r
+               if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {\r
+                       // drop table\r
+                       if( $this->drop_table ) {\r
+                               $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+                               \r
+                               return $sql;\r
+                       }\r
+                       \r
+                       // drop any existing fields not in schema\r
+                       foreach( $legacy_fields as $field_id => $field ) {\r
+                               if( !isset( $this->fields[$field_id] ) ) {\r
+                                       $sql[] = $xmls->dict->DropColumnSQL( $this->name, $field->name );\r
+                               }\r
+                       }\r
+               // if table doesn't exist\r
+               } else {\r
+                       if( $this->drop_table ) {\r
+                               return $sql;\r
+                       }\r
+                       \r
+                       $legacy_fields = array();\r
+               }\r
+               \r
+               // Loop through the field specifier array, building the associative array for the field options\r
+               $fldarray = array();\r
+               \r
+               foreach( $this->fields as $field_id => $finfo ) {\r
+                       // Set an empty size if it isn't supplied\r
+                       if( !isset( $finfo['SIZE'] ) ) {\r
+                               $finfo['SIZE'] = '';\r
+                       }\r
+                       \r
+                       // Initialize the field array with the type and size\r
+                       $fldarray[$field_id] = array(\r
+                               'NAME' => $finfo['NAME'],\r
+                               'TYPE' => $finfo['TYPE'],\r
+                               'SIZE' => $finfo['SIZE']\r
+                       );\r
+                       \r
+                       // Loop through the options array and add the field options. \r
+                       if( isset( $finfo['OPTS'] ) ) {\r
+                               foreach( $finfo['OPTS'] as $opt ) {\r
+                                       // Option has an argument.\r
+                                       if( is_array( $opt ) ) {\r
+                                               $key = key( $opt );\r
+                                               $value = $opt[key( $opt )];\r
+                                               @$fldarray[$field_id][$key] .= $value;\r
+                                       // Option doesn't have arguments\r
+                                       } else {\r
+                                               $fldarray[$field_id][$opt] = $opt;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               if( empty( $legacy_fields ) ) {\r
+                       // Create the new table\r
+                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+                       logMsg( end( $sql ), 'Generated CreateTableSQL' );\r
+               } else {\r
+                       // Upgrade an existing table\r
+                       logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );\r
+                       switch( $xmls->upgrade ) {\r
+                               // Use ChangeTableSQL\r
+                               case 'ALTER':\r
+                                       logMsg( 'Generated ChangeTableSQL (ALTERing table)' );\r
+                                       $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );\r
+                                       break;\r
+                               case 'REPLACE':\r
+                                       logMsg( 'Doing upgrade REPLACE (testing)' );\r
+                                       $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+                                       $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+                                       break;\r
+                               // ignore table\r
+                               default:\r
+                                       return array();\r
+                       }\r
+               }\r
+               \r
+               foreach( $this->indexes as $index ) {\r
+                       $sql[] = $index->create( $xmls );\r
+               }\r
+               \r
+               if( isset( $this->data ) ) {\r
+                       $sql[] = $this->data->create( $xmls );\r
+               }\r
+               \r
+               return $sql;\r
+       }\r
+       \r
+       /**\r
+       * Marks a field or table for destruction\r
+       */\r
+       function drop() {\r
+               if( isset( $this->current_field ) ) {\r
+                       // Drop the current field\r
+                       logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );\r
+                       // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );\r
+                       $this->drop_field[$this->current_field] = $this->current_field;\r
+               } else {\r
+                       // Drop the current table\r
+                       logMsg( "Dropping table '{$this->name}'" );\r
+                       // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );\r
+                       $this->drop_table = TRUE;\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+* Creates an index object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database index. As charactaristics\r
+* of the index are loaded from the external source, methods and properties\r
+* of this class are used to build up the index description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbIndex extends dbObject {\r
+       \r
+       /**\r
+       * @var string   Index name\r
+       */\r
+       var $name;\r
+       \r
+       /**\r
+       * @var array    Index options: Index-level options\r
+       */\r
+       var $opts = array();\r
+       \r
+       /**\r
+       * @var array    Indexed fields: Table columns included in this index\r
+       */\r
+       var $columns = array();\r
+       \r
+       /**\r
+       * @var boolean Mark index for destruction\r
+       * @access private\r
+       */\r
+       var $drop = FALSE;\r
+       \r
+       /**\r
+       * Initializes the new dbIndex object.\r
+       *\r
+       * @param object $parent Parent object\r
+       * @param array $attributes Attributes\r
+       *\r
+       * @internal\r
+       */\r
+       function dbIndex( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+               \r
+               $this->name = $this->prefix ($attributes['NAME']);\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * Processes XML opening tags. \r
+       * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'DROP':\r
+                               $this->drop();\r
+                               break;\r
+                       case 'CLUSTERED':\r
+                       case 'BITMAP':\r
+                       case 'UNIQUE':\r
+                       case 'FULLTEXT':\r
+                       case 'HASH':\r
+                               // Add index Option\r
+                               $this->addIndexOpt( $this->currentElement );\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * Processes XML cdata.\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Index field name\r
+                       case 'COL':\r
+                               $this->addField( $cdata );\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'INDEX':\r
+                               xml_set_object( $parser, $this->parent );\r
+                               break;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds a field to the index\r
+       *\r
+       * @param string $name Field name\r
+       * @return string Field list\r
+       */\r
+       function addField( $name ) {\r
+               $this->columns[$this->FieldID( $name )] = $name;\r
+               \r
+               // Return the field list\r
+               return $this->columns;\r
+       }\r
+       \r
+       /**\r
+       * Adds options to the index\r
+       *\r
+       * @param string $opt Comma-separated list of index options.\r
+       * @return string Option list\r
+       */\r
+       function addIndexOpt( $opt ) {\r
+               $this->opts[] = $opt;\r
+               \r
+               // Return the options list\r
+               return $this->opts;\r
+       }\r
+       \r
+       /**\r
+       * Generates the SQL that will create the index in the database\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Array containing index creation SQL\r
+       */\r
+       function create( &$xmls ) {\r
+               if( $this->drop ) {\r
+                       return NULL;\r
+               }\r
+               \r
+               // eliminate any columns that aren't in the table\r
+               foreach( $this->columns as $id => $col ) {\r
+                       if( !isset( $this->parent->fields[$id] ) ) {\r
+                               unset( $this->columns[$id] );\r
+                       }\r
+               }\r
+               \r
+               return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );\r
+       }\r
+       \r
+       /**\r
+       * Marks an index for destruction\r
+       */\r
+       function drop() {\r
+               $this->drop = TRUE;\r
+       }\r
+}\r
+\r
+/**\r
+* Creates a data object in ADOdb's datadict format\r
+*\r
+* This class stores information about table data, and is called\r
+* when we need to load field data into a table.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbData extends dbObject {\r
+       \r
+       var $data = array();\r
+       \r
+       var $row;\r
+       \r
+       /**\r
+       * Initializes the new dbData object.\r
+       *\r
+       * @param object $parent Parent object\r
+       * @param array $attributes Attributes\r
+       *\r
+       * @internal\r
+       */\r
+       function dbData( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * Processes XML opening tags. \r
+       * Elements currently processed are: ROW and F (field). \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'ROW':\r
+                               $this->row = count( $this->data );\r
+                               $this->data[$this->row] = array();\r
+                               break;\r
+                       case 'F':\r
+                               $this->addField($attributes);\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * Processes XML cdata.\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Index field name\r
+                       case 'F':\r
+                               $this->addData( $cdata );\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'DATA':\r
+                               xml_set_object( $parser, $this->parent );\r
+                               break;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds a field to the insert\r
+       *\r
+       * @param string $name Field name\r
+       * @return string Field list\r
+       */\r
+       function addField( $attributes ) {\r
+               // check we're in a valid row\r
+               if( !isset( $this->row ) || !isset( $this->data[$this->row] ) ) {\r
+                       return;\r
+               }\r
+               \r
+               // Set the field index so we know where we are\r
+               if( isset( $attributes['NAME'] ) ) {\r
+                       $this->current_field = $this->FieldID( $attributes['NAME'] );\r
+               } else {\r
+                       $this->current_field = count( $this->data[$this->row] );\r
+               }\r
+               \r
+               // initialise data\r
+               if( !isset( $this->data[$this->row][$this->current_field] ) ) {\r
+                       $this->data[$this->row][$this->current_field] = '';\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Adds options to the index\r
+       *\r
+       * @param string $opt Comma-separated list of index options.\r
+       * @return string Option list\r
+       */\r
+       function addData( $cdata ) {\r
+               // check we're in a valid field\r
+               if ( isset( $this->data[$this->row][$this->current_field] ) ) {\r
+                       // add data to field\r
+                       $this->data[$this->row][$this->current_field] .= $cdata;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Generates the SQL that will add/update the data in the database\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Array containing index creation SQL\r
+       */\r
+       function create( &$xmls ) {\r
+               $table = $xmls->dict->TableName($this->parent->name);\r
+               $table_field_count = count($this->parent->fields);\r
+               $tables = $xmls->db->MetaTables(); \r
+               $sql = array();\r
+               \r
+               $ukeys = $xmls->db->MetaPrimaryKeys( $table );\r
+               if( !empty( $this->parent->indexes ) and !empty( $ukeys ) ) {\r
+                       foreach( $this->parent->indexes as $indexObj ) {\r
+                               if( !in_array( $indexObj->name, $ukeys ) ) $ukeys[] = $indexObj->name;\r
+                       }\r
+               }\r
+               \r
+               // eliminate any columns that aren't in the table\r
+               foreach( $this->data as $row ) {\r
+                       $table_fields = $this->parent->fields;\r
+                       $fields = array();\r
+                       $rawfields = array(); // Need to keep some of the unprocessed data on hand.\r
+                       \r
+                       foreach( $row as $field_id => $field_data ) {\r
+                               if( !array_key_exists( $field_id, $table_fields ) ) {\r
+                                       if( is_numeric( $field_id ) ) {\r
+                                               $field_id = reset( array_keys( $table_fields ) );\r
+                                       } else {\r
+                                               continue;\r
+                                       }\r
+                               }\r
+                               \r
+                               $name = $table_fields[$field_id]['NAME'];\r
+                               \r
+                               switch( $table_fields[$field_id]['TYPE'] ) {\r
+                                       case 'I':\r
+                                       case 'I1':\r
+                                       case 'I2':\r
+                                       case 'I4':\r
+                                       case 'I8':\r
+                                               $fields[$name] = intval($field_data);\r
+                                               break;\r
+                                       case 'C':\r
+                                       case 'C2':\r
+                                       case 'X':\r
+                                       case 'X2':\r
+                                       default:\r
+                                               $fields[$name] = $xmls->db->qstr( $field_data );\r
+                                               $rawfields[$name] = $field_data;\r
+                               }\r
+                               \r
+                               unset($table_fields[$field_id]);\r
+                               \r
+                       }\r
+                       \r
+                       // check that at least 1 column is specified\r
+                       if( empty( $fields ) ) {\r
+                               continue;\r
+                       }\r
+                       \r
+                       // check that no required columns are missing\r
+                       if( count( $fields ) < $table_field_count ) {\r
+                               foreach( $table_fields as $field ) {\r
+                                       if( isset( $field['OPTS'] ) and ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {\r
+                                                       continue(2);\r
+                                               }\r
+                               }\r
+                       }\r
+                       \r
+                       // The rest of this method deals with updating existing data records.\r
+                       \r
+                       if( !in_array( $table, $tables ) or ( $mode = $xmls->existingData() ) == XMLS_MODE_INSERT ) {\r
+                               // Table doesn't yet exist, so it's safe to insert.\r
+                               logMsg( "$table doesn't exist, inserting or mode is INSERT" );\r
+                       $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';\r
+                               continue;\r
+               }\r
+               \r
+                       // Prepare to test for potential violations. Get primary keys and unique indexes\r
+                       $mfields = array_merge( $fields, $rawfields );\r
+                       $keyFields = array_intersect( $ukeys, array_keys( $mfields ) );\r
+                       \r
+                       if( empty( $ukeys ) or count( $keyFields ) == 0 ) {\r
+                               // No unique keys in schema, so safe to insert\r
+                               logMsg( "Either schema or data has no unique keys, so safe to insert" );\r
+                               $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';\r
+                               continue;\r
+                       }\r
+                       \r
+                       // Select record containing matching unique keys.\r
+                       $where = '';\r
+                       foreach( $ukeys as $key ) {\r
+                               if( isset( $mfields[$key] ) and $mfields[$key] ) {\r
+                                       if( $where ) $where .= ' AND ';\r
+                                       $where .= $key . ' = ' . $xmls->db->qstr( $mfields[$key] );\r
+                               }\r
+                       }\r
+                       $records = $xmls->db->Execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where );\r
+                       switch( $records->RecordCount() ) {\r
+                               case 0:\r
+                                       // No matching record, so safe to insert.\r
+                                       logMsg( "No matching records. Inserting new row with unique data" );\r
+                                       $sql[] = $xmls->db->GetInsertSQL( $records, $mfields );\r
+                                       break;\r
+                               case 1:\r
+                                       // Exactly one matching record, so we can update if the mode permits.\r
+                                       logMsg( "One matching record..." );\r
+                                       if( $mode == XMLS_MODE_UPDATE ) {\r
+                                               logMsg( "...Updating existing row from unique data" );\r
+                                               $sql[] = $xmls->db->GetUpdateSQL( $records, $mfields );\r
+                                       }\r
+                                       break;\r
+                               default:\r
+                                       // More than one matching record; the result is ambiguous, so we must ignore the row.\r
+                                       logMsg( "More than one matching record. Ignoring row." );\r
+                       }\r
+               }\r
+               return $sql;\r
+       }\r
+}\r
+\r
+/**\r
+* Creates the SQL to execute a list of provided SQL queries\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbQuerySet extends dbObject {\r
+       \r
+       /**\r
+       * @var array    List of SQL queries\r
+       */\r
+       var $queries = array();\r
+       \r
+       /**\r
+       * @var string   String used to build of a query line by line\r
+       */\r
+       var $query;\r
+       \r
+       /**\r
+       * @var string   Query prefix key\r
+       */\r
+       var $prefixKey = '';\r
+       \r
+       /**\r
+       * @var boolean  Auto prefix enable (TRUE)\r
+       */\r
+       var $prefixMethod = 'AUTO';\r
+       \r
+       /**\r
+       * Initializes the query set.\r
+       *\r
+       * @param object $parent Parent object\r
+       * @param array $attributes Attributes\r
+       */\r
+       function dbQuerySet( &$parent, $attributes = NULL ) {\r
+               $this->parent = $parent;\r
+                       \r
+               // Overrides the manual prefix key\r
+               if( isset( $attributes['KEY'] ) ) {\r
+                       $this->prefixKey = $attributes['KEY'];\r
+               }\r
+               \r
+               $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';\r
+               \r
+               // Enables or disables automatic prefix prepending\r
+               switch( $prefixMethod ) {\r
+                       case 'AUTO':\r
+                               $this->prefixMethod = 'AUTO';\r
+                               break;\r
+                       case 'MANUAL':\r
+                               $this->prefixMethod = 'MANUAL';\r
+                               break;\r
+                       case 'NONE':\r
+                               $this->prefixMethod = 'NONE';\r
+                               break;\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements. Elements currently \r
+       * processed are: QUERY. \r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               $this->currentElement = strtoupper( $tag );\r
+               \r
+               switch( $this->currentElement ) {\r
+                       case 'QUERY':\r
+                               // Create a new query in a SQL queryset.\r
+                               // Ignore this query set if a platform is specified and it's different than the \r
+                               // current connection platform.\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       $this->newQuery();\r
+                               } else {\r
+                                       $this->discardQuery();\r
+                               }\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+               switch( $this->currentElement ) {\r
+                       // Line of queryset SQL data\r
+                       case 'QUERY':\r
+                               $this->buildQuery( $cdata );\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               $this->currentElement = '';\r
+               \r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'QUERY':\r
+                               // Add the finished query to the open query set.\r
+                               $this->addQuery();\r
+                               break;\r
+                       case 'SQL':\r
+                               $this->parent->addSQL( $this->create( $this->parent ) );\r
+                               xml_set_object( $parser, $this->parent );\r
+                               $this->destroy();\r
+                               break;\r
+                       default:\r
+                               \r
+               }\r
+       }\r
+       \r
+       /**\r
+       * Re-initializes the query.\r
+       *\r
+       * @return boolean TRUE\r
+       */\r
+       function newQuery() {\r
+               $this->query = '';\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       /**\r
+       * Discards the existing query.\r
+       *\r
+       * @return boolean TRUE\r
+       */\r
+       function discardQuery() {\r
+               unset( $this->query );\r
+               \r
+               return TRUE;\r
+       }\r
+       \r
+       /** \r
+       * Appends a line to a query that is being built line by line\r
+       *\r
+       * @param string $data Line of SQL data or NULL to initialize a new query\r
+       * @return string SQL query string.\r
+       */\r
+       function buildQuery( $sql = NULL ) {\r
+               if( !isset( $this->query ) OR empty( $sql ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $this->query .= $sql;\r
+               \r
+               return $this->query;\r
+       }\r
+       \r
+       /**\r
+       * Adds a completed query to the query list\r
+       *\r
+       * @return string        SQL of added query\r
+       */\r
+       function addQuery() {\r
+               if( !isset( $this->query ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $this->queries[] = $return = trim($this->query);\r
+               \r
+               unset( $this->query );\r
+               \r
+               return $return;\r
+       }\r
+       \r
+       /**\r
+       * Creates and returns the current query set\r
+       *\r
+       * @param object $xmls adoSchema object\r
+       * @return array Query set\r
+       */\r
+       function create( &$xmls ) {\r
+               foreach( $this->queries as $id => $query ) {\r
+                       switch( $this->prefixMethod ) {\r
+                               case 'AUTO':\r
+                                       // Enable auto prefix replacement\r
+                                       \r
+                                       // Process object prefix.\r
+                                       // Evaluate SQL statements to prepend prefix to objects\r
+                                       $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+                                       $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+                                       $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+                                       \r
+                                       // SELECT statements aren't working yet\r
+                                       #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );\r
+                                       \r
+                               case 'MANUAL':\r
+                                       // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.\r
+                                       // If prefixKey is not set, we use the default constant XMLS_PREFIX\r
+                                       if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {\r
+                                               // Enable prefix override\r
+                                               $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );\r
+                                       } else {\r
+                                               // Use default replacement\r
+                                               $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );\r
+                                       }\r
+                       }\r
+                       \r
+                       $this->queries[$id] = trim( $query );\r
+               }\r
+               \r
+               // Return the query set array\r
+               return $this->queries;\r
+       }\r
+       \r
+       /**\r
+       * Rebuilds the query with the prefix attached to any objects\r
+       *\r
+       * @param string $regex Regex used to add prefix\r
+       * @param string $query SQL query string\r
+       * @param string $prefix Prefix to be appended to tables, indices, etc.\r
+       * @return string Prefixed SQL query string.\r
+       */\r
+       function prefixQuery( $regex, $query, $prefix = NULL ) {\r
+               if( !isset( $prefix ) ) {\r
+                       return $query;\r
+               }\r
+               \r
+               if( preg_match( $regex, $query, $match ) ) {\r
+                       $preamble = $match[1];\r
+                       $postamble = $match[5];\r
+                       $objectList = explode( ',', $match[3] );\r
+                       // $prefix = $prefix . '_';\r
+                       \r
+                       $prefixedList = '';\r
+                       \r
+                       foreach( $objectList as $object ) {\r
+                               if( $prefixedList !== '' ) {\r
+                                       $prefixedList .= ', ';\r
+                               }\r
+                               \r
+                               $prefixedList .= $prefix . trim( $object );\r
+                       }\r
+                       \r
+                       $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;\r
+               }\r
+               \r
+               return $query;\r
+       }\r
+}\r
+\r
+/**\r
+* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements\r
+* \r
+* This class is used to load and parse the XML file, to create an array of SQL statements\r
+* that can be used to build a database, and to build the database using the SQL array.\r
+*\r
+* @tutorial getting_started.pkg\r
+*\r
+* @author Richard Tango-Lowy & Dan Cech\r
+* @version $Revision$\r
+*\r
+* @package axmls\r
+*/\r
+class adoSchema {\r
+       \r
+       /**\r
+       * @var array    Array containing SQL queries to generate all objects\r
+       * @access private\r
+       */\r
+       var $sqlArray;\r
+       \r
+       /**\r
+       * @var object   ADOdb connection object\r
+       * @access private\r
+       */\r
+       var $db;\r
+       \r
+       /**\r
+       * @var object   ADOdb Data Dictionary\r
+       * @access private\r
+       */\r
+       var $dict;\r
+       \r
+       /**\r
+       * @var string Current XML element\r
+       * @access private\r
+       */\r
+       var $currentElement = '';\r
+       \r
+       /**\r
+       * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database\r
+       * @access private\r
+       */\r
+       var $upgrade = '';\r
+       \r
+       /**\r
+       * @var string Optional object prefix\r
+       * @access private\r
+       */\r
+       var $objectPrefix = '';\r
+       \r
+       /**\r
+       * @var long     Original Magic Quotes Runtime value\r
+       * @access private\r
+       */\r
+       var $mgq;\r
+       \r
+       /**\r
+       * @var long     System debug\r
+       * @access private\r
+       */\r
+       var $debug;\r
+       \r
+       /**\r
+       * @var string Regular expression to find schema version\r
+       * @access private\r
+       */\r
+       var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';\r
+       \r
+       /**\r
+       * @var string Current schema version\r
+       * @access private\r
+       */\r
+       var $schemaVersion;\r
+       \r
+       /**\r
+       * @var int      Success of last Schema execution\r
+       */\r
+       var $success;\r
+       \r
+       /**\r
+       * @var bool     Execute SQL inline as it is generated\r
+       */\r
+       var $executeInline;\r
+       \r
+       /**\r
+       * @var bool     Continue SQL execution if errors occur\r
+       */\r
+       var $continueOnError;\r
+       \r
+       /**\r
+       * @var int      How to handle existing data rows (insert, update, or ignore)\r
+       */\r
+       var $existingData;\r
+       \r
+       /**\r
+       * Creates an adoSchema object\r
+       *\r
+       * Creating an adoSchema object is the first step in processing an XML schema.\r
+       * The only parameter is an ADOdb database connection object, which must already\r
+       * have been created.\r
+       *\r
+       * @param object $db ADOdb database connection object.\r
+       */\r
+       function adoSchema( &$db ) {\r
+               // Initialize the environment\r
+               $this->mgq = get_magic_quotes_runtime();\r
+               set_magic_quotes_runtime(0);\r
+               \r
+               $this->db = $db;\r
+               $this->debug = $this->db->debug;\r
+               $this->dict = NewDataDictionary( $this->db );\r
+               $this->sqlArray = array();\r
+               $this->schemaVersion = XMLS_SCHEMA_VERSION;\r
+               $this->executeInline( XMLS_EXECUTE_INLINE );\r
+               $this->continueOnError( XMLS_CONTINUE_ON_ERROR );\r
+               $this->existingData( XMLS_EXISTING_DATA );\r
+               $this->setUpgradeMethod();\r
+       }\r
+       \r
+       /**\r
+       * Sets the method to be used for upgrading an existing database\r
+       *\r
+       * Use this method to specify how existing database objects should be upgraded.\r
+       * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to\r
+       * alter each database object directly, REPLACE attempts to rebuild each object\r
+       * from scratch, BEST attempts to determine the best upgrade method for each\r
+       * object, and NONE disables upgrading.\r
+       *\r
+       * This method is not yet used by AXMLS, but exists for backward compatibility.\r
+       * The ALTER method is automatically assumed when the adoSchema object is\r
+       * instantiated; other upgrade methods are not currently supported.\r
+       *\r
+       * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)\r
+       * @returns string Upgrade method used\r
+       */\r
+       function SetUpgradeMethod( $method = '' ) {\r
+               if( !is_string( $method ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $method = strtoupper( $method );\r
+               \r
+               // Handle the upgrade methods\r
+               switch( $method ) {\r
+                       case 'ALTER':\r
+                               $this->upgrade = $method;\r
+                               break;\r
+                       case 'REPLACE':\r
+                               $this->upgrade = $method;\r
+                               break;\r
+                       case 'BEST':\r
+                               $this->upgrade = 'ALTER';\r
+                               break;\r
+                       case 'NONE':\r
+                               $this->upgrade = 'NONE';\r
+                               break;\r
+                       default:\r
+                               // Use default if no legitimate method is passed.\r
+                               $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;\r
+               }\r
+               \r
+               return $this->upgrade;\r
+       }\r
+       \r
+       /**\r
+       * Specifies how to handle existing data row when there is a unique key conflict.\r
+       *\r
+       * The existingData setting specifies how the parser should handle existing rows\r
+       * when a unique key violation occurs during the insert. This can happen when inserting\r
+       * data into an existing table with one or more primary keys or unique indexes.\r
+       * The existingData method takes one of three options: XMLS_MODE_INSERT attempts\r
+       * to always insert the data as a new row. In the event of a unique key violation,\r
+       * the database will generate an error.  XMLS_MODE_UPDATE attempts to update the \r
+       * any existing rows with the new data based upon primary or unique key fields in\r
+       * the schema. If the data row in the schema specifies no unique fields, the row\r
+       * data will be inserted as a new row. XMLS_MODE_IGNORE specifies that any data rows\r
+       * that would result in a unique key violation be ignored; no inserts or updates will\r
+       * take place. For backward compatibility, the default setting is XMLS_MODE_INSERT,\r
+       * but XMLS_MODE_UPDATE will generally be the most appropriate setting.\r
+       *\r
+       * @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE\r
+       * @return int current mode\r
+       */\r
+       function ExistingData( $mode = NULL ) {\r
+               if( is_int( $mode ) ) {\r
+                       switch( $mode ) {\r
+                               case XMLS_MODE_UPDATE:\r
+                                       $mode = XMLS_MODE_UPDATE;\r
+                                       break;\r
+                               case XMLS_MODE_IGNORE:\r
+                                       $mode = XMLS_MODE_IGNORE;\r
+                                       break;\r
+                               case XMLS_MODE_INSERT:\r
+                                       $mode = XMLS_MODE_INSERT;\r
+                                       break;\r
+                               default:\r
+                                       $mode = XMLS_EXISITNG_DATA;\r
+                                       break;\r
+                       }\r
+                       $this->existingData = $mode;\r
+               }\r
+               \r
+               return $this->existingData;\r
+       }\r
+       \r
+       /**\r
+       * Enables/disables inline SQL execution.\r
+       *\r
+       * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),\r
+       * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode\r
+       * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()\r
+       * to apply the schema to the database.\r
+       *\r
+       * @param bool $mode execute\r
+       * @return bool current execution mode\r
+       *\r
+       * @see ParseSchema(), ExecuteSchema()\r
+       */\r
+       function ExecuteInline( $mode = NULL ) {\r
+               if( is_bool( $mode ) ) {\r
+                       $this->executeInline = $mode;\r
+               }\r
+               \r
+               return $this->executeInline;\r
+       }\r
+       \r
+       /**\r
+       * Enables/disables SQL continue on error.\r
+       *\r
+       * Call this method to enable or disable continuation of SQL execution if an error occurs.\r
+       * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.\r
+       * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing\r
+       * of the schema will continue.\r
+       *\r
+       * @param bool $mode execute\r
+       * @return bool current continueOnError mode\r
+       *\r
+       * @see addSQL(), ExecuteSchema()\r
+       */\r
+       function ContinueOnError( $mode = NULL ) {\r
+               if( is_bool( $mode ) ) {\r
+                       $this->continueOnError = $mode;\r
+               }\r
+               \r
+               return $this->continueOnError;\r
+       }\r
+       \r
+       /**\r
+       * Loads an XML schema from a file and converts it to SQL.\r
+       *\r
+       * Call this method to load the specified schema (see the DTD for the proper format) from\r
+       * the filesystem and generate the SQL necessary to create the database\r
+       * described. This method automatically converts the schema to the latest\r
+       * axmls schema version.\r
+       * @see ParseSchemaString()\r
+       *\r
+       * @param string $file Name of XML schema file.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute\r
+       */\r
+       function ParseSchema( $filename, $returnSchema = FALSE ) {\r
+               return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+       }\r
+       \r
+       /**\r
+       * Loads an XML schema from a file and converts it to SQL.\r
+       *\r
+       * Call this method to load the specified schema directly from a file (see\r
+       * the DTD for the proper format) and generate the SQL necessary to create\r
+       * the database described by the schema. Use this method when you are dealing\r
+       * with large schema files. Otherwise, ParseSchema() is faster.\r
+       * This method does not automatically convert the schema to the latest axmls\r
+       * schema version. You must convert the schema manually using either the\r
+       * ConvertSchemaFile() or ConvertSchemaString() method.\r
+       * @see ParseSchema()\r
+       * @see ConvertSchemaFile()\r
+       * @see ConvertSchemaString()\r
+       *\r
+       * @param string $file Name of XML schema file.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute.\r
+       *\r
+       * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()\r
+       * @see ParseSchema(), ParseSchemaString()\r
+       */\r
+       function ParseSchemaFile( $filename, $returnSchema = FALSE ) {\r
+               // Open the file\r
+               if( !($fp = fopen( $filename, 'r' )) ) {\r
+                       logMsg( 'Unable to open file' );\r
+                       return FALSE;\r
+               }\r
+               \r
+               // do version detection here\r
+               if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {\r
+                       logMsg( 'Invalid Schema Version' );\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( $returnSchema ) {\r
+                       $xmlstring = '';\r
+                       while( $data = fread( $fp, 4096 ) ) {\r
+                               $xmlstring .= $data . "\n";\r
+                       }\r
+                       return $xmlstring;\r
+               }\r
+               \r
+               $this->success = 2;\r
+               \r
+               $xmlParser = $this->create_parser();\r
+               \r
+               // Process the file\r
+               while( $data = fread( $fp, 4096 ) ) {\r
+                       if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {\r
+                               die( sprintf(\r
+                                       "XML error: %s at line %d",\r
+                                       xml_error_string( xml_get_error_code( $xmlParser) ),\r
+                                       xml_get_current_line_number( $xmlParser)\r
+                               ) );\r
+                       }\r
+               }\r
+               \r
+               xml_parser_free( $xmlParser );\r
+               \r
+               return $this->sqlArray;\r
+       }\r
+       \r
+       /**\r
+       * Converts an XML schema string to SQL.\r
+       *\r
+       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+       * and generate the SQL necessary to create the database described by the schema. \r
+       * @see ParseSchema()\r
+       *\r
+       * @param string $xmlstring XML schema string.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute.\r
+       */\r
+       function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {\r
+               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+                       logMsg( 'Empty or Invalid Schema' );\r
+                       return FALSE;\r
+               }\r
+               \r
+               // do version detection here\r
+               if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {\r
+                       logMsg( 'Invalid Schema Version' );\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( $returnSchema ) {\r
+                       return $xmlstring;\r
+               }\r
+               \r
+               $this->success = 2;\r
+               \r
+               $xmlParser = $this->create_parser();\r
+               \r
+               if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {\r
+                       die( sprintf(\r
+                               "XML error: %s at line %d",\r
+                               xml_error_string( xml_get_error_code( $xmlParser) ),\r
+                               xml_get_current_line_number( $xmlParser)\r
+                       ) );\r
+               }\r
+               \r
+               xml_parser_free( $xmlParser );\r
+               \r
+               return $this->sqlArray;\r
+       }\r
+       \r
+       /**\r
+       * Loads an XML schema from a file and converts it to uninstallation SQL.\r
+       *\r
+       * Call this method to load the specified schema (see the DTD for the proper format) from\r
+       * the filesystem and generate the SQL necessary to remove the database described.\r
+       * @see RemoveSchemaString()\r
+       *\r
+       * @param string $file Name of XML schema file.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute\r
+       */\r
+       function RemoveSchema( $filename, $returnSchema = FALSE ) {\r
+               return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+       }\r
+       \r
+       /**\r
+       * Converts an XML schema string to uninstallation SQL.\r
+       *\r
+       * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+       * and generate the SQL necessary to uninstall the database described by the schema. \r
+       * @see RemoveSchema()\r
+       *\r
+       * @param string $schema XML schema string.\r
+       * @param bool $returnSchema Return schema rather than parsing.\r
+       * @return array Array of SQL queries, ready to execute.\r
+       */\r
+       function RemoveSchemaString( $schema, $returnSchema = FALSE ) {\r
+               \r
+               // grab current version\r
+               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );\r
+       }\r
+       \r
+       /**\r
+       * Applies the current XML schema to the database (post execution).\r
+       *\r
+       * Call this method to apply the current schema (generally created by calling \r
+       * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes, \r
+       * and executing other SQL specified in the schema) after parsing.\r
+       * @see ParseSchema(), ParseSchemaString(), ExecuteInline()\r
+       *\r
+       * @param array $sqlArray Array of SQL statements that will be applied rather than\r
+       *               the current schema.\r
+       * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.\r
+       * @returns integer 0 if failure, 1 if errors, 2 if successful.\r
+       */\r
+       function ExecuteSchema( $sqlArray = NULL, $continueOnErr =  NULL ) {\r
+               if( !is_bool( $continueOnErr ) ) {\r
+                       $continueOnErr = $this->ContinueOnError();\r
+               }\r
+               \r
+               if( !isset( $sqlArray ) ) {\r
+                       $sqlArray = $this->sqlArray;\r
+               }\r
+               \r
+               if( !is_array( $sqlArray ) ) {\r
+                       $this->success = 0;\r
+               } else {\r
+                       $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );\r
+               }\r
+               \r
+               return $this->success;\r
+       }\r
+       \r
+       /**\r
+       * Returns the current SQL array. \r
+       *\r
+       * Call this method to fetch the array of SQL queries resulting from \r
+       * ParseSchema() or ParseSchemaString(). \r
+       *\r
+       * @param string $format Format: HTML, TEXT, or NONE (PHP array)\r
+       * @return array Array of SQL statements or FALSE if an error occurs\r
+       */\r
+       function PrintSQL( $format = 'NONE' ) {\r
+               $sqlArray = null;\r
+               return $this->getSQL( $format, $sqlArray );\r
+       }\r
+       \r
+       /**\r
+       * Saves the current SQL array to the local filesystem as a list of SQL queries.\r
+       *\r
+       * Call this method to save the array of SQL queries (generally resulting from a\r
+       * parsed XML schema) to the filesystem.\r
+       *\r
+       * @param string $filename Path and name where the file should be saved.\r
+       * @return boolean TRUE if save is successful, else FALSE. \r
+       */\r
+       function SaveSQL( $filename = './schema.sql' ) {\r
+               \r
+               if( !isset( $sqlArray ) ) {\r
+                       $sqlArray = $this->sqlArray;\r
+               }\r
+               if( !isset( $sqlArray ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $fp = fopen( $filename, "w" );\r
+               \r
+               foreach( $sqlArray as $key => $query ) {\r
+                       fwrite( $fp, $query . ";\n" );\r
+               }\r
+               fclose( $fp );\r
+       }\r
+       \r
+       /**\r
+       * Create an xml parser\r
+       *\r
+       * @return object PHP XML parser object\r
+       *\r
+       * @access private\r
+       */\r
+       function create_parser() {\r
+               // Create the parser\r
+               $xmlParser = xml_parser_create();\r
+               xml_set_object( $xmlParser, $this );\r
+               \r
+               // Initialize the XML callback functions\r
+               xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );\r
+               xml_set_character_data_handler( $xmlParser, '_tag_cdata' );\r
+               \r
+               return $xmlParser;\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process start elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_open( &$parser, $tag, $attributes ) {\r
+               switch( strtoupper( $tag ) ) {\r
+                       case 'TABLE':\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                               $this->obj = new dbTable( $this, $attributes );\r
+                               xml_set_object( $parser, $this->obj );\r
+                               }\r
+                               break;\r
+                       case 'SQL':\r
+                               if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+                                       $this->obj = new dbQuerySet( $this, $attributes );\r
+                                       xml_set_object( $parser, $this->obj );\r
+                               }\r
+                               break;\r
+                       default:\r
+                               // print_r( array( $tag, $attributes ) );\r
+               }\r
+               \r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process CDATA elements\r
+       *\r
+       * @access private\r
+       */\r
+       function _tag_cdata( &$parser, $cdata ) {\r
+       }\r
+       \r
+       /**\r
+       * XML Callback to process end elements\r
+       *\r
+       * @access private\r
+       * @internal\r
+       */\r
+       function _tag_close( &$parser, $tag ) {\r
+               \r
+       }\r
+       \r
+       /**\r
+       * Converts an XML schema string to the specified DTD version.\r
+       *\r
+       * Call this method to convert a string containing an XML schema to a different AXMLS\r
+       * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+       * parameter is specified, the schema will be converted to the current DTD version. \r
+       * If the newFile parameter is provided, the converted schema will be written to the specified\r
+       * file.\r
+       * @see ConvertSchemaFile()\r
+       *\r
+       * @param string $schema String containing XML schema that will be converted.\r
+       * @param string $newVersion DTD version to convert to.\r
+       * @param string $newFile File name of (converted) output file.\r
+       * @return string Converted XML schema or FALSE if an error occurs.\r
+       */\r
+       function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {\r
+               \r
+               // grab current version\r
+               if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( !isset ($newVersion) ) {\r
+                       $newVersion = $this->schemaVersion;\r
+               }\r
+               \r
+               if( $version == $newVersion ) {\r
+                       $result = $schema;\r
+               } else {\r
+                       $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);\r
+               }\r
+               \r
+               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+                       fwrite( $fp, $result );\r
+                       fclose( $fp );\r
+               }\r
+               \r
+               return $result;\r
+       }\r
+\r
+       /*\r
+       // compat for pre-4.3 - jlim\r
+       function _file_get_contents($path)\r
+       {\r
+               if (function_exists('file_get_contents')) return file_get_contents($path);\r
+               return join('',file($path));\r
+       }*/\r
+       \r
+       /**\r
+       * Converts an XML schema file to the specified DTD version.\r
+       *\r
+       * Call this method to convert the specified XML schema file to a different AXMLS\r
+       * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+       * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+       * parameter is specified, the schema will be converted to the current DTD version. \r
+       * If the newFile parameter is provided, the converted schema will be written to the specified\r
+       * file.\r
+       * @see ConvertSchemaString()\r
+       *\r
+       * @param string $filename Name of XML schema file that will be converted.\r
+       * @param string $newVersion DTD version to convert to.\r
+       * @param string $newFile File name of (converted) output file.\r
+       * @return string Converted XML schema or FALSE if an error occurs.\r
+       */\r
+       function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {\r
+               \r
+               // grab current version\r
+               if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( !isset ($newVersion) ) {\r
+                       $newVersion = $this->schemaVersion;\r
+               }\r
+               \r
+               if( $version == $newVersion ) {\r
+                       $result = _file_get_contents( $filename );\r
+                       \r
+                       // remove unicode BOM if present\r
+                       if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {\r
+                               $result = substr( $result, 3 );\r
+                       }\r
+               } else {\r
+                       $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );\r
+               }\r
+               \r
+               if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+                       fwrite( $fp, $result );\r
+                       fclose( $fp );\r
+               }\r
+               \r
+               return $result;\r
+       }\r
+       \r
+       function TransformSchema( $schema, $xsl, $schematype='string' )\r
+       {\r
+               // Fail if XSLT extension is not available\r
+               if( ! function_exists( 'xslt_create' ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';\r
+               \r
+               // look for xsl\r
+               if( !is_readable( $xsl_file ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               switch( $schematype )\r
+               {\r
+                       case 'file':\r
+                               if( !is_readable( $schema ) ) {\r
+                                       return FALSE;\r
+                               }\r
+                               \r
+                               $schema = _file_get_contents( $schema );\r
+                               break;\r
+                       case 'string':\r
+                       default:\r
+                               if( !is_string( $schema ) ) {\r
+                                       return FALSE;\r
+                               }\r
+               }\r
+               \r
+               $arguments = array (\r
+                       '/_xml' => $schema,\r
+                       '/_xsl' => _file_get_contents( $xsl_file )\r
+               );\r
+               \r
+               // create an XSLT processor\r
+               $xh = xslt_create ();\r
+               \r
+               // set error handler\r
+               xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));\r
+               \r
+               // process the schema\r
+               $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); \r
+               \r
+               xslt_free ($xh);\r
+               \r
+               return $result;\r
+       }\r
+       \r
+       /**\r
+       * Processes XSLT transformation errors\r
+       *\r
+       * @param object $parser XML parser object\r
+       * @param integer $errno Error number\r
+       * @param integer $level Error level\r
+       * @param array $fields Error information fields\r
+       *\r
+       * @access private\r
+       */\r
+       function xslt_error_handler( $parser, $errno, $level, $fields ) {\r
+               if( is_array( $fields ) ) {\r
+                       $msg = array(\r
+                               'Message Type' => ucfirst( $fields['msgtype'] ),\r
+                               'Message Code' => $fields['code'],\r
+                               'Message' => $fields['msg'],\r
+                               'Error Number' => $errno,\r
+                               'Level' => $level\r
+                       );\r
+                       \r
+                       switch( $fields['URI'] ) {\r
+                               case 'arg:/_xml':\r
+                                       $msg['Input'] = 'XML';\r
+                                       break;\r
+                               case 'arg:/_xsl':\r
+                                       $msg['Input'] = 'XSL';\r
+                                       break;\r
+                               default:\r
+                                       $msg['Input'] = $fields['URI'];\r
+                       }\r
+                       \r
+                       $msg['Line'] = $fields['line'];\r
+               } else {\r
+                       $msg = array(\r
+                               'Message Type' => 'Error',\r
+                               'Error Number' => $errno,\r
+                               'Level' => $level,\r
+                               'Fields' => var_export( $fields, TRUE )\r
+                       );\r
+               }\r
+               \r
+               $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"\r
+                                          . '<table>' . "\n";\r
+               \r
+               foreach( $msg as $label => $details ) {\r
+                       $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";\r
+               }\r
+               \r
+               $error_details .= '</table>';\r
+               \r
+               trigger_error( $error_details, E_USER_ERROR );\r
+       }\r
+       \r
+       /**\r
+       * Returns the AXMLS Schema Version of the requested XML schema file.\r
+       *\r
+       * Call this method to obtain the AXMLS DTD version of the requested XML schema file.\r
+       * @see SchemaStringVersion()\r
+       *\r
+       * @param string $filename AXMLS schema file\r
+       * @return string Schema version number or FALSE on error\r
+       */\r
+       function SchemaFileVersion( $filename ) {\r
+               // Open the file\r
+               if( !($fp = fopen( $filename, 'r' )) ) {\r
+                       // die( 'Unable to open file' );\r
+                       return FALSE;\r
+               }\r
+               \r
+               // Process the file\r
+               while( $data = fread( $fp, 4096 ) ) {\r
+                       if( preg_match( $this->versionRegex, $data, $matches ) ) {\r
+                               return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+                       }\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+       * Returns the AXMLS Schema Version of the provided XML schema string.\r
+       *\r
+       * Call this method to obtain the AXMLS DTD version of the provided XML schema string.\r
+       * @see SchemaFileVersion()\r
+       *\r
+       * @param string $xmlstring XML schema string\r
+       * @return string Schema version number or FALSE on error\r
+       */\r
+       function SchemaStringVersion( $xmlstring ) {\r
+               if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {\r
+                       return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+       * Extracts an XML schema from an existing database.\r
+       *\r
+       * Call this method to create an XML schema string from an existing database.\r
+       * If the data parameter is set to TRUE, AXMLS will include the data from the database\r
+       * in the schema. \r
+       *\r
+       * @param boolean $data Include data in schema dump\r
+       * @indent string indentation to use\r
+       * @prefix string extract only tables with given prefix\r
+       * @stripprefix strip prefix string when storing in XML schema\r
+       * @return string Generated XML schema\r
+       */\r
+       function ExtractSchema( $data = FALSE, $indent = '  ', $prefix = '' , $stripprefix=false) {\r
+               $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );\r
+               \r
+               $schema = '<?xml version="1.0"?>' . "\n"\r
+                               . '<schema version="' . $this->schemaVersion . '">' . "\n";\r
+               \r
+               if( is_array( $tables = $this->db->MetaTables( 'TABLES' , ($prefix) ? $prefix.'%' : '') ) ) {\r
+                       foreach( $tables as $table ) {\r
+                               if ($stripprefix) $table = str_replace(str_replace('\\_', '_', $pfx ), '', $table);\r
+                               $schema .= $indent . '<table name="' . htmlentities( $table ) . '">' . "\n";\r
+                               \r
+                               // grab details from database\r
+                               $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE -1' );\r
+                               $fields = $this->db->MetaColumns( $table );\r
+                               $indexes = $this->db->MetaIndexes( $table );\r
+                               \r
+                               if( is_array( $fields ) ) {\r
+                                       foreach( $fields as $details ) {\r
+                                               $extra = '';\r
+                                               $content = array();\r
+                                               \r
+                                               if( isset($details->max_length) && $details->max_length > 0 ) {\r
+                                                       $extra .= ' size="' . $details->max_length . '"';\r
+                                               }\r
+                                               \r
+                                               if( isset($details->primary_key) && $details->primary_key ) {\r
+                                                       $content[] = '<KEY/>';\r
+                                               } elseif( isset($details->not_null) && $details->not_null ) {\r
+                                                       $content[] = '<NOTNULL/>';\r
+                                               }\r
+                                               \r
+                                               if( isset($details->has_default) && $details->has_default ) {\r
+                                                       $content[] = '<DEFAULT value="' . htmlentities( $details->default_value ) . '"/>';\r
+                                               }\r
+                                               \r
+                                               if( isset($details->auto_increment) && $details->auto_increment ) {\r
+                                                       $content[] = '<AUTOINCREMENT/>';\r
+                                               }\r
+                                               \r
+                                               if( isset($details->unsigned) && $details->unsigned ) {\r
+                                                       $content[] = '<UNSIGNED/>';\r
+                                               }\r
+                                               \r
+                                               // this stops the creation of 'R' columns,\r
+                                               // AUTOINCREMENT is used to create auto columns\r
+                                               $details->primary_key = 0;\r
+                                               $type = $rs->MetaType( $details );\r
+                                               \r
+                                               $schema .= str_repeat( $indent, 2 ) . '<field name="' . htmlentities( $details->name ) . '" type="' . $type . '"' . $extra;\r
+                                               \r
+                                               if( !empty( $content ) ) {\r
+                                                       $schema .= ">\n" . str_repeat( $indent, 3 )\r
+                                                                        . implode( "\n" . str_repeat( $indent, 3 ), $content ) . "\n"\r
+                                                                        . str_repeat( $indent, 2 ) . '</field>' . "\n";\r
+                                               } else {\r
+                                                       $schema .= "/>\n";\r
+                                               }\r
+                                       }\r
+                               }\r
+                               \r
+                               if( is_array( $indexes ) ) {\r
+                                       foreach( $indexes as $index => $details ) {\r
+                                               $schema .= str_repeat( $indent, 2 ) . '<index name="' . $index . '">' . "\n";\r
+                                               \r
+                                               if( $details['unique'] ) {\r
+                                                       $schema .= str_repeat( $indent, 3 ) . '<UNIQUE/>' . "\n";\r
+                                               }\r
+                                               \r
+                                               foreach( $details['columns'] as $column ) {\r
+                                                       $schema .= str_repeat( $indent, 3 ) . '<col>' . htmlentities( $column ) . '</col>' . "\n";\r
+                                               }\r
+                                               \r
+                                               $schema .= str_repeat( $indent, 2 ) . '</index>' . "\n";\r
+                                       }\r
+                               }\r
+                               \r
+                               if( $data ) {\r
+                                       $rs = $this->db->Execute( 'SELECT * FROM ' . $table );\r
+                                       \r
+                                       if( is_object( $rs ) && !$rs->EOF ) {\r
+                                               $schema .= str_repeat( $indent, 2 ) . "<data>\n";\r
+                                               \r
+                                               while( $row = $rs->FetchRow() ) {\r
+                                                       foreach( $row as $key => $val ) {\r
+                                                               if ( $val != htmlentities( $val ) ) {\r
+                                                                       $row[$key] = '<![CDATA[' . $val . ']]>';\r
+                                                               }\r
+                                                       }\r
+                                                       \r
+                                                       $schema .= str_repeat( $indent, 3 ) . '<row><f>' . implode( '</f><f>', $row ) . "</f></row>\n";\r
+                                               }\r
+                                               \r
+                                               $schema .= str_repeat( $indent, 2 ) . "</data>\n";\r
+                                       }\r
+                               }\r
+                               \r
+                               $schema .= $indent . "</table>\n";\r
+                       }\r
+               }\r
+               \r
+               $this->db->SetFetchMode( $old_mode );\r
+               \r
+               $schema .= '</schema>';\r
+               return $schema;\r
+       }\r
+       \r
+       /**\r
+       * Sets a prefix for database objects\r
+       *\r
+       * Call this method to set a standard prefix that will be prepended to all database tables \r
+       * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.\r
+       *\r
+       * @param string $prefix Prefix that will be prepended.\r
+       * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.\r
+       * @return boolean TRUE if successful, else FALSE\r
+       */\r
+       function SetPrefix( $prefix = '', $underscore = TRUE ) {\r
+               switch( TRUE ) {\r
+                       // clear prefix\r
+                       case empty( $prefix ):\r
+                               logMsg( 'Cleared prefix' );\r
+                               $this->objectPrefix = '';\r
+                               return TRUE;\r
+                       // prefix too long\r
+                       case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:\r
+                       // prefix contains invalid characters\r
+                       case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):\r
+                               logMsg( 'Invalid prefix: ' . $prefix );\r
+                               return FALSE;\r
+               }\r
+               \r
+               if( $underscore AND substr( $prefix, -1 ) != '_' ) {\r
+                       $prefix .= '_';\r
+               }\r
+               \r
+               // prefix valid\r
+               logMsg( 'Set prefix: ' . $prefix );\r
+               $this->objectPrefix = $prefix;\r
+               return TRUE;\r
+       }\r
+       \r
+       /**\r
+       * Returns an object name with the current prefix prepended.\r
+       *\r
+       * @param string $name Name\r
+       * @return string        Prefixed name\r
+       *\r
+       * @access private\r
+       */\r
+       function prefix( $name = '' ) {\r
+               // if prefix is set\r
+               if( !empty( $this->objectPrefix ) ) {\r
+                       // Prepend the object prefix to the table name\r
+                       // prepend after quote if used\r
+                       return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );\r
+               }\r
+               \r
+               // No prefix set. Use name provided.\r
+               return $name;\r
+       }\r
+       \r
+       /**\r
+       * Checks if element references a specific platform\r
+       *\r
+       * @param string $platform Requested platform\r
+       * @returns boolean TRUE if platform check succeeds\r
+       *\r
+       * @access private\r
+       */\r
+       function supportedPlatform( $platform = NULL ) {\r
+               if( !empty( $platform ) ) {\r
+                       $regex = '/(^|\|)' . $this->db->databaseType . '(\||$)/i';\r
+               \r
+                       if( preg_match( '/^- /', $platform ) ) {\r
+                               if (preg_match ( $regex, substr( $platform, 2 ) ) ) {\r
+                                       logMsg( 'Platform ' . $platform . ' is NOT supported' );\r
+                                       return FALSE;\r
+                               }\r
+               } else {\r
+                               if( !preg_match ( $regex, $platform ) ) {\r
+                                       logMsg( 'Platform ' . $platform . ' is NOT supported' );\r
+                       return FALSE;\r
+               }\r
+       }\r
+               }\r
+               \r
+               logMsg( 'Platform ' . $platform . ' is supported' );\r
+               return TRUE;\r
+       }\r
+       \r
+       /**\r
+       * Clears the array of generated SQL.\r
+       *\r
+       * @access private\r
+       */\r
+       function clearSQL() {\r
+               $this->sqlArray = array();\r
+       }\r
+       \r
+       /**\r
+       * Adds SQL into the SQL array.\r
+       *\r
+       * @param mixed $sql SQL to Add\r
+       * @return boolean TRUE if successful, else FALSE.\r
+       *\r
+       * @access private\r
+       */      \r
+       function addSQL( $sql = NULL ) {\r
+               if( is_array( $sql ) ) {\r
+                       foreach( $sql as $line ) {\r
+                               $this->addSQL( $line );\r
+                       }\r
+                       \r
+                       return TRUE;\r
+               }\r
+               \r
+               if( is_string( $sql ) ) {\r
+                       $this->sqlArray[] = $sql;\r
+                       \r
+                       // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.\r
+                       if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {\r
+                               $saved = $this->db->debug;\r
+                               $this->db->debug = $this->debug;\r
+                               $ok = $this->db->Execute( $sql );\r
+                               $this->db->debug = $saved;\r
+                               \r
+                               if( !$ok ) {\r
+                                       if( $this->debug ) {\r
+                                               ADOConnection::outp( $this->db->ErrorMsg() );\r
+                                       }\r
+                                       \r
+                                       $this->success = 1;\r
+                               }\r
+                       }\r
+                       \r
+                       return TRUE;\r
+               }\r
+               \r
+               return FALSE;\r
+       }\r
+       \r
+       /**\r
+       * Gets the SQL array in the specified format.\r
+       *\r
+       * @param string $format Format\r
+       * @return mixed SQL\r
+       *       \r
+       * @access private\r
+       */\r
+       function getSQL( $format = NULL, $sqlArray = NULL ) {\r
+               if( !is_array( $sqlArray ) ) {\r
+                       $sqlArray = $this->sqlArray;\r
+               }\r
+               \r
+               if( !is_array( $sqlArray ) ) {\r
+                       return FALSE;\r
+               }\r
+               \r
+               switch( strtolower( $format ) ) {\r
+                       case 'string':\r
+                       case 'text':\r
+                               return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';\r
+                       case'html':\r
+                               return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';\r
+               }\r
+               \r
+               return $this->sqlArray;\r
+       }\r
+       \r
+       /**\r
+       * Destroys an adoSchema object.\r
+       *\r
+       * Call this method to clean up after an adoSchema object that is no longer in use.\r
+       * @deprecated adoSchema now cleans up automatically.\r
+       */\r
+       function Destroy() {\r
+               set_magic_quotes_runtime( $this->mgq );\r
+               unset( $this );\r
+       }\r
+}\r
+\r
+/**\r
+* Message logging function\r
+*\r
+* @access private\r
+*/\r
+function logMsg( $msg, $title = NULL, $force = FALSE ) {\r
+       if( XMLS_DEBUG or $force ) {\r
+               echo '<pre>';\r
+               \r
+               if( isset( $title ) ) {\r
+                       echo '<h3>' . htmlentities( $title ) . '</h3>';\r
+               }\r
+               \r
+               if( @is_object( $this ) ) {\r
+                       echo '[' . get_class( $this ) . '] ';\r
+               }\r
+               \r
+               print_r( $msg );\r
+               \r
+               echo '</pre>';\r
+       }\r
+}\r
 ?>
\ No newline at end of file
index 092e46ee913d8c55ad4c1dc3f842668b92f46c23..42fc35a2e90c61e4bb33897a1932771d7fa47800 100644 (file)
@@ -1,8 +1,8 @@
-<?php
+<?php 
 /*
  * Set tabs to 4 for best viewing.
  * 
- * Latest version is available at http://adodb.sourceforge.net/
+ * Latest version is available at http://adodb.sourceforge.net
  * 
  * This is the main include file for ADOdb.
  * Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php
@@ -14,7 +14,7 @@
 /**
        \mainpage       
        
-        @version V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+        @version V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
 
        Released under both BSD license and Lesser GPL library license. You can choose which license
        you prefer.
                        define('ADODB_PHPVER',0x5200);
                } else if ($_adodb_ver >= 5.0) {
                        define('ADODB_PHPVER',0x5000);
-               } else if ($_adodb_ver > 4.299999) { # 4.3
-                       define('ADODB_PHPVER',0x4300);
-               } else if ($_adodb_ver > 4.199999) { # 4.2
-                       define('ADODB_PHPVER',0x4200);
-               } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
-                       define('ADODB_PHPVER',0x4050);
-               } else {
-                       define('ADODB_PHPVER',0x4000);
-               }
+               } else 
+                       die("PHP5 or later required. You are running ".PHP_VERSION);
        }
        
        //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
                /**
                 * ADODB version as a string.
                 */
-               $ADODB_vers = 'V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
+               $ADODB_vers = 'V5.04a 25 Mar 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
        
                /**
                 * Determines whether recordset->RecordCount() is used. 
                die('Virtual Class -- cannot instantiate');
        }
        
-       function Version()
+       static function Version()
        {
        global $ADODB_vers;
        
        * All error messages go through this bottleneck function.
        * You can define your own handler by defining the function name in ADODB_OUTP.
        */
-       function outp($msg,$newline=true)
+       static function outp($msg,$newline=true)
        {
        global $ADODB_FLUSH,$ADODB_OUTP;
        
        
        function Time()
        {
-               $rs =& $this->_Execute("select $this->sysTimeStamp");
+               $rs = $this->_Execute("select $this->sysTimeStamp");
                if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
                
                return false;
                return $ret;
        }
 
+       function outp_throw($msg,$src='WARN',$sql='')
+       {
+               if (defined('ADODB_ERROR_HANDLER') &&  ADODB_ERROR_HANDLER == 'adodb_throw') {
+                       adodb_throw($this->databaseType,$src,-9999,$msg,$sql,false,$this);
+                       return;
+               } 
+               ADOConnection::outp($msg);
+       }
+       
        // Format date column in sql string given an input format that understands Y M D
        function SQLDate($fmt, $col=false)
        {       
        {
                return $sql;
        }
-       
+
        /**
         * Some databases, eg. mssql require a different function for preparing
         * stored procedures. So we cannot use Prepare().
        {
                return $this->Prepare($sql,$param);
        }
-       
+
        /**
        * PEAR DB Compat
        */
        /**
        * PEAR DB Compat - do not use internally. 
        */
-       function &Query($sql, $inputarr=false)
+       function Query($sql, $inputarr=false)
        {
-               $rs = &$this->Execute($sql, $inputarr);
+               $rs = $this->Execute($sql, $inputarr);
                if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
                return $rs;
        }
        /**
        * PEAR DB Compat - do not use internally
        */
-       function &LimitQuery($sql, $offset, $count, $params=false)
+       function LimitQuery($sql, $offset, $count, $params=false)
        {
-               $rs = &$this->SelectLimit($sql, $count, $offset, $params); 
+               $rs = $this->SelectLimit($sql, $count, $offset, $params); 
                if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
                return $rs;
        }
         * @param [inputarr]    holds the input data to bind to. Null elements will be set to null.
         * @return              RecordSet or false
         */
-       function &Execute($sql,$inputarr=false) 
+       function Execute($sql,$inputarr=false) 
        {
                if ($this->fnExecute) {
                        $fn = $this->fnExecute;
-                       $ret =& $fn($this,$sql,$inputarr);
+                       $ret = $fn($this,$sql,$inputarr);
                        if (isset($ret)) return $ret;
                }
                if ($inputarr) {
                                        }
                                        if (isset($sqlarr[$i])) {
                                                $sql .= $sqlarr[$i];
-                                               if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql));
+                                               if ($i+1 != sizeof($sqlarr)) $this->outp_throw( "Input Array does not match ?: ".htmlspecialchars($sql),'Execute');
                                        } else if ($i != sizeof($sqlarr))       
-                                               ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql));
+                                               $this->outp_throw( "Input array does not match ?: ".htmlspecialchars($sql),'Execute');
                
-                                       $ret =& $this->_Execute($sql);
+                                       $ret = $this->_Execute($sql);
                                        if (!$ret) return $ret;
                                }       
                        } else {
                                                $stmt = $sql;
                                                
                                        foreach($inputarr as $arr) {
-                                               $ret =& $this->_Execute($stmt,$arr);
+                                               $ret = $this->_Execute($stmt,$arr);
                                                if (!$ret) return $ret;
                                        }
                                } else {
-                                       $ret =& $this->_Execute($sql,$inputarr);
+                                       $ret = $this->_Execute($sql,$inputarr);
                                }
                        }
                } else {
-                       $ret =& $this->_Execute($sql,false);
+                       $ret = $this->_Execute($sql,false);
                }
 
                return $ret;
        }
        
        
-       function &_Execute($sql,$inputarr=false)
+       function _Execute($sql,$inputarr=false)
        {
                if ($this->debug) {
                        global $ADODB_INCLUDED_LIB;
                // return real recordset from select statement
                $rsclass = $this->rsPrefix.$this->databaseType;
                $rs = new $rsclass($this->_queryID,$this->fetchMode);
-               $rs->connection = &$this; // Pablo suggestion
+               $rs->connection = $this; // Pablo suggestion
                $rs->Init();
                if (is_array($sql)) $rs->sql = $sql[0];
                else $rs->sql = $sql;
                global $ADODB_COUNTRECS;
                        if ($ADODB_COUNTRECS) {
                                if (!$rs->EOF) { 
-                                       $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql));
+                                       $rs = $this->_rs2rs($rs,-1,-1,!is_array($sql));
                                        $rs->_queryID = $this->_queryID;
                                } else
                                        $rs->_numOfRows = 0;
        {
        // owner not used in base class - see oci8
                $p = array();
-               $objs =& $this->MetaColumns($table);
+               $objs = $this->MetaColumns($table);
                if ($objs) {
                        foreach($objs as $v) {
                                if (!empty($v->primary_key))
        * @param [secs2cache]           is a private parameter only used by jlim
        * @return               the recordset ($rs->databaseType == 'array')
        */
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                if ($this->hasTop && $nrows > 0) {
                // suggested by Reinhard Balling. Access requires top after distinct 
                                                '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
 
                                                if ($secs2cache != 0) {
-                                                       $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr);
+                                                       $ret = $this->CacheExecute($secs2cache, $sql,$inputarr);
                                                } else {
-                                                       $ret =& $this->Execute($sql,$inputarr);
+                                                       $ret = $this->Execute($sql,$inputarr);
                                                }
                                                return $ret; // PHP5 fix
                                        } else if ($ismssql){
                $ADODB_COUNTRECS = false;
                        
                if ($offset>0){
-                       if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
-                       else $rs = &$this->Execute($sql,$inputarr);
+                       if ($secs2cache != 0) $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+                       else $rs = $this->Execute($sql,$inputarr);
                } else {
-                       if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
-                       else $rs = &$this->Execute($sql,$inputarr);
+                       if ($secs2cache != 0) $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+                       else $rs = $this->Execute($sql,$inputarr);
                }
                $ADODB_COUNTRECS = $savec;
                if ($rs && !$rs->EOF) {
-                       $rs =& $this->_rs2rs($rs,$nrows,$offset);
+                       $rs = $this->_rs2rs($rs,$nrows,$offset);
                }
                //print_r($rs);
                return $rs;
        *
        * @param rs                     the recordset to serialize
        */
-       function &SerializableRS(&$rs)
+       function SerializableRS(&$rs)
        {
-               $rs2 =& $this->_rs2rs($rs);
+               $rs2 = $this->_rs2rs($rs);
                $ignore = false;
-               $rs2->connection =& $ignore;
+               $rs2->connection = $ignore;
                
                return $rs2;
        }
                }
                $dbtype = $rs->databaseType;
                if (!$dbtype) {
-                       $rs = &$rs;  // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
+                       $rs = $rs;  // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
                        return $rs;
                }
                if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) {
                        $rs->MoveFirst();
-                       $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
+                       $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
                        return $rs;
                }
                $flds = array();
                        $flds[] = $rs->FetchField($i);
                }
 
-               $arr =& $rs->GetArrayLimit($nrows,$offset);
+               $arr = $rs->GetArrayLimit($nrows,$offset);
                //print_r($arr);
                if ($close) $rs->Close();
                
                $arrayClass = $this->arrayClass;
                
                $rs2 = new $arrayClass();
-               $rs2->connection = &$this;
+               $rs2->connection = $this;
                $rs2->sql = $rs->sql;
                $rs2->dataProvider = $this->dataProvider;
                $rs2->InitArrayFields($arr,$flds);
        /*
        * Return all rows. Compat with PEAR DB
        */
-       function &GetAll($sql, $inputarr=false)
+       function GetAll($sql, $inputarr=false)
        {
-               $arr =& $this->GetArray($sql,$inputarr);
+               $arr = $this->GetArray($sql,$inputarr);
                return $arr;
        }
        
-       function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false)
+       function GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false)
        {
-               $rs =& $this->Execute($sql, $inputarr);
+               $rs = $this->Execute($sql, $inputarr);
                if (!$rs) {
                        $false = false;
                        return $false;
                }
-               $arr =& $rs->GetAssoc($force_array,$first2cols);
+               $arr = $rs->GetAssoc($force_array,$first2cols);
                return $arr;
        }
        
-       function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false)
+       function CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false)
        {
                if (!is_numeric($secs2cache)) {
                        $first2cols = $force_array;
                        $force_array = $inputarr;
                }
-               $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr);
+               $rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
                if (!$rs) {
                        $false = false;
                        return $false;
                }
-               $arr =& $rs->GetAssoc($force_array,$first2cols);
+               $arr = $rs->GetAssoc($force_array,$first2cols);
                return $arr;
        }
        
                $ADODB_COUNTRECS = false;
                
                $ret = false;
-               $rs = &$this->Execute($sql,$inputarr);
+               $rs = $this->Execute($sql,$inputarr);
                if ($rs) {      
                        if ($rs->EOF) $ret = null;
                        else $ret = reset($rs->fields);
        function CacheGetOne($secs2cache,$sql=false,$inputarr=false)
        {
                $ret = false;
-               $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
-               if ($rs) {              
+               $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+               if ($rs) {
                        if ($rs->EOF) $ret = null;
                        else $ret = reset($rs->fields);
                        $rs->Close();
        function GetCol($sql, $inputarr = false, $trim = false)
        {
                
-               $rs = &$this->Execute($sql, $inputarr);
+               $rs = $this->Execute($sql, $inputarr);
                if ($rs) {
                        $rv = array();
                        if ($trim) {
        
        function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false)
        {
-               $rs = &$this->CacheExecute($secs, $sql, $inputarr);
+               $rs = $this->CacheExecute($secs, $sql, $inputarr);
                if ($rs) {
                        $rv = array();
                        if ($trim) {
                                }
                        }
                        $rs->Close();
-               } else          
-                       $rv = false;
-               
-               return $rv;
+               } else
+                       $rv = false;
+                       
+               return $rv;
        }
        
-       function &Transpose(&$rs,$addfieldnames=true)
+       function Transpose(&$rs,$addfieldnames=true)
        {
-               $rs2 =& $this->_rs2rs($rs);
+               $rs2 = $this->_rs2rs($rs);
                $false = false;
                if (!$rs2) return $false;
                
        * @param sql                    SQL statement
        * @param [inputarr]             input bind array
        */
-       function &GetArray($sql,$inputarr=false)
+       function GetArray($sql,$inputarr=false)
        {
        global $ADODB_COUNTRECS;
                
                $savec = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
-               $rs =& $this->Execute($sql,$inputarr);
+               $rs = $this->Execute($sql,$inputarr);
                $ADODB_COUNTRECS = $savec;
                if (!$rs) 
                        if (defined('ADODB_PEAR')) {
                                $false = false;
                                return $false;
                        }
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $rs->Close();
                return $arr;
        }
        
-       function &CacheGetAll($secs2cache,$sql=false,$inputarr=false)
+       function CacheGetAll($secs2cache,$sql=false,$inputarr=false)
        {
-               $arr =& $this->CacheGetArray($secs2cache,$sql,$inputarr);
+               $arr = $this->CacheGetArray($secs2cache,$sql,$inputarr);
                return $arr;
        }
        
-       function &CacheGetArray($secs2cache,$sql=false,$inputarr=false)
+       function CacheGetArray($secs2cache,$sql=false,$inputarr=false)
        {
        global $ADODB_COUNTRECS;
                
                $savec = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
-               $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
+               $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
                $ADODB_COUNTRECS = $savec;
                
                if (!$rs) 
                                $false = false;
                                return $false;
                        }
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $rs->Close();
                return $arr;
        }
        * @param sql                    SQL statement
        * @param [inputarr]             input bind array
        */
-       function &GetRow($sql,$inputarr=false)
+       function GetRow($sql,$inputarr=false)
        {
        global $ADODB_COUNTRECS;
                $crecs = $ADODB_COUNTRECS;
                $ADODB_COUNTRECS = false;
                
-               $rs =& $this->Execute($sql,$inputarr);
+               $rs = $this->Execute($sql,$inputarr);
                
                $ADODB_COUNTRECS = $crecs;
                if ($rs) {
                return $false;
        }
        
-       function &CacheGetRow($secs2cache,$sql=false,$inputarr=false)
+       function CacheGetRow($secs2cache,$sql=false,$inputarr=false)
        {
-               $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
+               $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
                if ($rs) {
-                       $arr = array();
                        if (!$rs->EOF) $arr = $rs->fields;
+                       else $arr = array();
+                       
                        $rs->Close();
                        return $arr;
                }
        * @param [inputarr]     array of bind variables
        * @return               the recordset ($rs->databaseType == 'array')
        */
-       function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
+       function CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
        {       
                if (!is_numeric($secs2cache)) {
                        if ($sql === false) $sql = -1;
                        if ($offset == -1) $offset = false;
                                                                          // sql,       nrows, offset,inputarr
-                       $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
+                       $rs = $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
                } else {
-                       if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()");
-                       $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+                       if ($sql === false) $this->outp_throw("Warning: \$sql missing from CacheSelectLimit()",'CacheSelectLimit');
+                       $rs = $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
                }
                return $rs;
        }
    *
    * Just specify the directory, and tell it if you want to delete the directory or just clear it out.
    * Note: $kill_top_level is used internally in the function to flush subdirectories.
+   *
    */
    function _dirFlush($dir, $kill_top_level = false) 
    {
       return true;
    }
    
-   
+    // this only deletes .cache files
        function xCacheFlush($sql=false,$inputarr=false)
        {
        global $ADODB_CACHE_DIR;
         * @param [inputarr]    holds the input data  to bind to
         * @return              RecordSet or false
         */
-       function &CacheExecute($secs2cache,$sql=false,$inputarr=false)
+       function CacheExecute($secs2cache,$sql=false,$inputarr=false)
        {
-
-                       
                if (!is_numeric($secs2cache)) {
                        $inputarr = $sql;
                        $sql = $secs2cache;
                
                if ($secs2cache > 0){
                        if ($this->memCache)
-                               $rs = &getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort);
+                               $rs = getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort);
                        else
-                               $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass);
+                               $rs = csv2rs($md5file,$err,$secs2cache,$this->arrayClass);
                        $this->numCacheHits += 1;
                } else {
                        $err='Timeout 1';
                        $rs = false;
                        $this->numCacheMisses += 1;
                }
+       
                if (!$rs) {
                // no cached rs found
                        if ($this->debug) {
                                if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)");
                        }
                        
-                       $rs = &$this->Execute($sqlparam,$inputarr);
+                       $rs = $this->Execute($sqlparam,$inputarr);
 
                        if ($rs && $this->memCache) {
-                               $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately
+                               $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately
                                if(!putmemCache($md5file, $rs, $this->memCacheHost, $this->memCachePort, $this->memCacheCompress, $this->debug)) {
                                        if ($fn = $this->raiseErrorFn)
                                                $fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this);
                                }
                        } else if ($rs) {
                                $eof = $rs->EOF;
-                               $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately
+                               $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately
                                $txt = _rs2serialize($rs,false,$sql); // serialize
-               
+       
                                $ok = adodb_write_file($md5file,$txt,$this->debug);
                                if (!$ok) {
                                        if ($ok === false) {
                                }
                                if ($rs->EOF && !$eof) {
                                        $rs->MoveFirst();
-                                       //$rs = &csv2rs($md5file,$err);         
-                                       $rs->connection = &$this; // Pablo suggestion
+                                       //$rs = csv2rs($md5file,$err);          
+                                       $rs->connection = $this; // Pablo suggestion
                                }  
                                
                        } else
                                $fn($this, $secs2cache, $sql, $inputarr);
                        }
                // ok, set cached object found
-                       $rs->connection = &$this; // Pablo suggestion
-                       if ($this->debug){ 
-                                       
+                       $rs->connection = $this; // Pablo suggestion
+                       if ($this->debug){                      
+                               if ($this->debug == 99) adodb_backtrace();
                                $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
                                $ttl = $rs->timeCreated + $secs2cache - time();
                                $s = is_array($sql) ? $sql[0] : $sql;
                
                $forceUpdate means that even if the data has not changed, perform update.
         */
-       function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 
+       function AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false) 
        {
                $false = false;
                $sql = 'SELECT * FROM '.$table;  
                if ($where!==FALSE) $sql .= ' WHERE '.$where;
                else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) {
-                       ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause');
+                       $this->outp_throw('AutoExecute: Illegal mode=UPDATE with empty WHERE clause','AutoExecute');
                        return $false;
                }
 
-               $rs =& $this->SelectLimit($sql,1);
+               $rs = $this->SelectLimit($sql,1);
                if (!$rs) return $false; // table does not exist
                $rs->tableName = $table;
                
                        $sql = $this->GetInsertSQL($rs, $fields_values, $magicq);
                        break;
                default:
-                       ADOConnection::outp("AutoExecute: Unknown mode=$mode");
+                       $this->outp_throw("AutoExecute: Unknown mode=$mode",'AutoExecute');
                        return $false;
                }
                $ret = false;
                if (empty($this->_metars)) {
                        $rsclass = $this->rsPrefix.$this->databaseType;
                        $this->_metars = new $rsclass(false,$this->fetchMode); 
-                       $this->_metars->connection =& $this;
+                       $this->_metars->connection = $this;
                }
                return $this->_metars->MetaType($t,$len,$fieldobj);
        }
                }
        }
 
-       function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false)
+       function GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false)
        {
        global $_ADODB_ACTIVE_DBS;
        
                        include(ADODB_DIR.'/adodb-active-record.inc.php');
                }       
                if (!class_exists($class)) {
-                       ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()");
+                       $this->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
                        return $false;
                }
                $arr = array();
                return $arr;
        }
        
-       function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false)
+       function GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false)
        {
-               $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
+               $arr = $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
                return $arr;
        }
        
@@ -2238,7 +2241,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  array of tables for current database.
         */ 
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
        global $ADODB_FETCH_MODE;
        
@@ -2258,7 +2261,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        $ADODB_FETCH_MODE = $save; 
                        
                        if ($rs === false) return $false;
-                       $arr =& $rs->GetArray();
+                       $arr = $rs->GetArray();
                        $arr2 = array();
                        
                        if ($hast = ($ttype && isset($arr[0][1]))) { 
@@ -2300,7 +2303,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  array of ADOFieldObjects for current table.
         */
-       function &MetaColumns($table,$normalize=true) 
+       function MetaColumns($table,$normalize=true) 
        {
        global $ADODB_FETCH_MODE;
                
@@ -2359,7 +2362,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                  )
                )               
       */
-     function &MetaIndexes($table, $primary = false, $owner = false)
+     function MetaIndexes($table, $primary = false, $owner = false)
      {
                        $false = false;
             return $false;
@@ -2371,9 +2374,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return  array of column names for current table.
         */ 
-       function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 
+       function MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) 
        {
-               $objarr =& $this->MetaColumns($table);
+               $objarr = $this->MetaColumns($table);
                if (!is_array($objarr)) {
                        $false = false;
                        return $false;
@@ -2475,7 +2478,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixDate($v)
+       static function UnixDate($v)
        {
                if (is_object($v)) {
                // odbtp support
@@ -2499,7 +2502,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixTimeStamp($v)
+       static function UnixTimeStamp($v)
        {
                if (is_object($v)) {
                // odbtp support
@@ -2645,12 +2648,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        * NOTE: phpLens uses a different algorithm and does not use PageExecute().
        *
        */
-       function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
+       function PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) 
        {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
-               if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
-               else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
+               if ($this->pageExecuteCountRows) $rs = _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
+               else $rs = _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
                return $rs;
        }
        
@@ -2667,7 +2670,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        * @param [inputarr]     array of bind variables
        * @return               the recordset ($rs->databaseType == 'array')
        */
-       function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 
+       function CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) 
        {
                /*switch($this->dataProvider) {
                case 'postgres':
@@ -2675,7 +2678,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        break;
                default: $secs2cache = 0; break;
                }*/
-               $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
+               $rs = $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
                return $rs;
        }
 
@@ -2697,10 +2700,54 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        // CLASS ADORecordSet_empty
        //==============================================================================================        
        
+       class ADODB_Iterator_empty implements Iterator {
+       
+           private $rs;
+       
+           function __construct($rs) 
+               {
+               $this->rs = $rs;
+           }
+           function rewind() 
+               {
+           }
+       
+               function valid() 
+               {
+               return !$this->rs->EOF;
+           }
+               
+           function key() 
+               {
+               return $false;
+           }
+               
+           function current() 
+               {
+               return $false;
+           }
+               
+           function next() 
+               {
+           }
+               
+               function __call($func, $params)
+               {
+                       return call_user_func_array(array($this->rs, $func), $params);
+               }
+               
+               function hasMore()
+               {
+                       return false;
+               }
+       
+       }
+
+       
        /**
        * Lightweight recordset when there are no records to be returned
        */
-       class ADORecordSet_empty
+       class ADORecordSet_empty implements IteratorAggregate
        {
                var $dataProvider = 'empty';
                var $databaseType = false;
@@ -2715,6 +2762,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                function FetchRow() {return false;}
                function FieldCount(){ return 0;}
                function Init() {}
+               function getIterator() {return new ADODB_Iterator_empty($this);}
        }
        
        //==============================================================================================        
@@ -2726,15 +2774,61 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        // CLASS ADORecordSet
        //==============================================================================================        
 
-       if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php');
-       else include_once(ADODB_DIR.'/adodb-iterator.inc.php');
+       class ADODB_Iterator implements Iterator {
+       
+           private $rs;
+       
+           function __construct($rs) 
+               {
+               $this->rs = $rs;
+           }
+           function rewind() 
+               {
+               $this->rs->MoveFirst();
+           }
+       
+               function valid() 
+               {
+               return !$this->rs->EOF;
+           }
+               
+           function key() 
+               {
+               return $this->rs->_currentRow;
+           }
+               
+           function current() 
+               {
+               return $this->rs->fields;
+           }
+               
+           function next() 
+               {
+               $this->rs->MoveNext();
+           }
+               
+               function __call($func, $params)
+               {
+                       return call_user_func_array(array($this->rs, $func), $params);
+               }
+       
+               
+               function hasMore()
+               {
+                       return !$this->rs->EOF;
+               }
+       
+       }
+
+
+
    /**
         * RecordSet class that represents the dataset returned by the database.
         * To keep memory overhead low, this class holds only the current row in memory.
         * No prefetching of data is done, so the RecordCount() can return -1 ( which
         * means recordcount not known).
         */
-       class ADORecordSet extends ADODB_BASE_RS {
+       class ADORecordSet implements IteratorAggregate {
        /*
         * public variables     
         */
@@ -2784,6 +2878,17 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                $this->_queryID = $queryID;
        }
        
+       function getIterator() 
+       {
+        return new ADODB_Iterator($this);
+    }
+       
+       /* this is experimental - i don't really know what to return... */
+       function __toString()
+       {
+               include_once(ADODB_DIR.'/toexport.inc.php');
+               return _adodb_export($this,',',',',false,true);
+       }
        
        
        function Init()
@@ -2870,7 +2975,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return an array indexed by the rows (0-based) from the recordset
         */
-       function &GetArray($nRows = -1) 
+       function GetArray($nRows = -1) 
        {
        global $ADODB_EXTENSION; if ($ADODB_EXTENSION) {
                $results = adodb_getall($this,$nRows);
@@ -2886,9 +2991,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $results;
        }
        
-       function &GetAll($nRows = -1)
+       function GetAll($nRows = -1)
        {
-               $arr =& $this->GetArray($nRows);
+               $arr = $this->GetArray($nRows);
                return $arr;
        }
        
@@ -2910,10 +3015,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return an array indexed by the rows (0-based) from the recordset
         */
-       function &GetArrayLimit($nrows,$offset=-1) 
+       function GetArrayLimit($nrows,$offset=-1) 
        {       
                if ($offset <= 0) {
-                       $arr =& $this->GetArray($nrows);
+                       $arr = $this->GetArray($nrows);
                        return $arr;
                } 
                
@@ -2937,9 +3042,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return an array indexed by the rows (0-based) from the recordset
         */
-       function &GetRows($nRows = -1) 
+       function GetRows($nRows = -1) 
        {
-               $arr =& $this->GetArray($nRows);
+               $arr = $this->GetArray($nRows);
                return $arr;
        }
        
@@ -2959,7 +3064,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         * @return an associative array indexed by the first column of the array, 
         *      or false if the  data has less than 2 cols.
         */
-       function &GetAssoc($force_array = false, $first2cols = false) 
+       function GetAssoc($force_array = false, $first2cols = false) 
        {
        global $ADODB_EXTENSION;
        
@@ -3050,7 +3155,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        }
                }
                
-               $ref =& $results; # workaround accelerator incompat with PHP 4.4 :(
+               $ref = $results; # workaround accelerator incompat with PHP 4.4 :(
                return $ref; 
        }
        
@@ -3096,7 +3201,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixDate($v)
+       static function UnixDate($v)
        {
                return ADOConnection::UnixDate($v);
        }
@@ -3107,7 +3212,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
         */
-       function UnixTimeStamp($v)
+       static function UnixTimeStamp($v)
        {
                return ADOConnection::UnixTimeStamp($v);
        }
@@ -3145,7 +3250,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * @return false or array containing the current record
        */
-       function &FetchRow()
+       function FetchRow()
        {
                if ($this->EOF) {
                        $false = false;
@@ -3309,7 +3414,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
    *
    * $upper  0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField
    */
-       function &GetRowAssoc($upper=1)
+       function GetRowAssoc($upper=1)
        {
                $record = array();
         //     if (!$this->fields) return $record;
@@ -3383,7 +3488,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                if ($lnumrows == -1 && $this->connection) {
                        IF ($table) {
                                if ($condition) $condition = " WHERE " . $condition; 
-                               $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
+                               $resultrows = $this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
                                if ($resultrows) $lnumrows = reset($resultrows->fields);
                        }
                }
@@ -3417,7 +3522,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return the ADOFieldObject for that column, or false.
         */
-       function &FetchField($fieldoffset = -1) 
+       function FetchField($fieldoffset = -1) 
        {
                // must be defined by child class
                
@@ -3429,7 +3534,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         * Get the ADOFieldObjects of all columns in an array.
         *
         */
-       function& FieldTypesArray()
+       function FieldTypesArray()
        {
                $arr = array();
                for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) 
@@ -3443,9 +3548,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * @return the object with the properties set to the fields of the current row
        */
-       function &FetchObj()
+       function FetchObj()
        {
-               $o =& $this->FetchObject(false);
+               $o = $this->FetchObject(false);
                return $o;
        }
        
@@ -3457,7 +3562,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * @return the object with the properties set to the fields of the current row
        */
-       function &FetchObject($isupper=true)
+       function FetchObject($isupper=true)
        {
                if (empty($this->_obj)) {
                        $this->_obj = new ADOFetchObj();
@@ -3490,9 +3595,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * Fixed bug reported by tim@orotech.net
        */
-       function &FetchNextObj()
+       function FetchNextObj()
        {
-               $o =& $this->FetchNextObject(false);
+               $o = $this->FetchNextObject(false);
                return $o;
        }
        
@@ -3508,7 +3613,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        *
        * Fixed bug reported by tim@orotech.net
        */
-       function &FetchNextObject($isupper=true)
+       function FetchNextObject($isupper=true)
        {
                $o = false;
                if ($this->_numOfRows != 0 && !$this->EOF) {
@@ -3779,7 +3884,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        //adodb_pr($newarr);
                        
                        $this->_skiprow1 = false;
-                       $this->_array =& $newarr;
+                       $this->_array = $newarr;
                        $this->_colnames = $hdr;
                        
                        adodb_probetypes($newarr,$this->_types);
@@ -3833,20 +3938,20 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                 */
                function InitArrayFields(&$array,&$fieldarr)
                {
-                       $this->_array =& $array;
+                       $this->_array = $array;
                        $this->_skiprow1= false;
                        if ($fieldarr) {
-                               $this->_fieldobjects =& $fieldarr;
+                               $this->_fieldobjects = $fieldarr;
                        } 
                        $this->Init();
                }
                
-               function &GetArray($nRows=-1)
+               function GetArray($nRows=-1)
                {
                        if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) {
                                return $this->_array;
                        } else {
-                               $arr =& ADORecordSet::GetArray($nRows);
+                               $arr = ADORecordSet::GetArray($nRows);
                                return $arr;
                        }
                }
@@ -3879,7 +3984,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        return $this->fields[$this->bind[strtoupper($colname)]];
                }
                
-               function &FetchField($fieldOffset = -1) 
+               function FetchField($fieldOffset = -1) 
                {
                        if (isset($this->_fieldobjects)) {
                                return $this->_fieldobjects[$fieldOffset];
@@ -3994,9 +4099,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        /**
         * synonym for ADONewConnection for people like me who cannot remember the correct name
         */
-       function &NewADOConnection($db='')
+       function NewADOConnection($db='')
        {
-               $tmp =& ADONewConnection($db);
+               $tmp = ADONewConnection($db);
                return $tmp;
        }
        
@@ -4008,38 +4113,38 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
         *
         * @return the freshly created instance of the Connection class.
         */
-       function &ADONewConnection($db='')
+       function ADONewConnection($db='')
        {
        GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB;
                
                if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
                $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
                $false = false;
-               if ($at = strpos($db,'://')) {
+               if (($at = strpos($db,'://')) !== FALSE) {
                        $origdsn = $db;
-                       if (PHP_VERSION < 5) $dsna = @parse_url($db);
-                       else {
-                               $fakedsn = 'fake'.substr($db,$at);
+                       $fakedsn = 'fake'.substr($origdsn,$at);
+                       if (($at2 = strpos($origdsn,'@/')) !== FALSE) {
+                               // special handling of oracle, which might not have host
+                               $fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn);
+                       }
                                $dsna = @parse_url($fakedsn);
-                               $dsna['scheme'] = substr($db,0,$at);
+                       if (!$dsna) {
+                               return $false;
+                       }
+                               $dsna['scheme'] = substr($origdsn,0,$at);
+                       if ($at2 !== FALSE) {
+                               $dsna['host'] = '';
+                       }
                        
-                               if (strncmp($db,'pdo',3) == 0) {
-                                       $sch = explode('_',$dsna['scheme']);
-                                       if (sizeof($sch)>1) {
-                                               $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
-                                               $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
-                                               $dsna['scheme'] = 'pdo';
-                                       }
+                       if (strncmp($origdsn,'pdo',3) == 0) {
+                               $sch = explode('_',$dsna['scheme']);
+                               if (sizeof($sch)>1) {
+                                       $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
+                                       $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
+                                       $dsna['scheme'] = 'pdo';
                                }
                        }
                        
-                       if (!$dsna) {
-                               // special handling of oracle, which might not have host
-                               $db = str_replace('@/','@adodb-fakehost/',$db);
-                               $dsna = parse_url($db);
-                               if (!$dsna) return $false;
-                               $dsna['host'] = '';
-                       }
                        $db = @$dsna['scheme'];
                        if (!$db) return $false;
                        $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
@@ -4175,7 +4280,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $drivername;
        }
        
-       function &NewPerfMonitor(&$conn)
+       function NewPerfMonitor(&$conn)
        {
                $false = false;
                $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true);
@@ -4189,7 +4294,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $perf;
        }
        
-       function &NewDataDictionary(&$conn,$drivername=false)
+       function NewDataDictionary(&$conn,$drivername=false)
        {
                $false = false;
                if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType);
@@ -4206,7 +4311,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                $class = "ADODB2_$drivername";
                $dict = new $class();
                $dict->dataProvider = $conn->dataProvider;
-               $dict->connection = &$conn;
+               $dict->connection = $conn;
                $dict->upperName = strtoupper($drivername);
                $dict->quote = $conn->nameQuote;
                if (!empty($conn->_connectionID))
index 3ec194e3bf4860b19942f47cf845eeee20e1f36d..468c070026ef08ab930d6c06c9d1ec579c62f15d 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 6e03b253fb087eddf527a366d7d9851e90e75128..116aa5a5159787f496a7a89bad28d2a0fb18c505 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -83,7 +83,7 @@ class ADODB2_db2 extends ADODB_DataDict {
                $validTypes = array("CHAR","VARC");
                $invalidTypes = array("BIGI","BLOB","CLOB","DATE", "DECI","DOUB", "INTE", "REAL","SMAL", "TIME");
                // check table exists
-               $cols = &$this->MetaColumns($tablename);
+               $cols = $this->MetaColumns($tablename);
                if ( empty($cols)) { 
                        return $this->CreateTableSQL($tablename, $flds, $tableoptions);
                }
index c49b62444f2dcaf0000e391389a168bbb4144fc8..5d14c72c40bec8cb6c6dbf769906572c4fecc570 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 45639036bd01b2bc5f72ab1a3ccb18c69b3ad2d1..f376d970ec3d136b51d92f099c99a04dbd9b74c0 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index ac171f509e2f7481509bbe21aef858c0fc1ce536..656d211dd7e75440b3d47373adb40f3028af2aa0 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 8dae2302bd6ae33e6f9fb8428c0e952a286fa56a..34fd943c3619a23d5bda3d28870a07e6182f24ed 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 12753566cca668e355430b5d2759942b3ae1bf02..d9e59a3f912562d09d36266a6c1a8ad82b3cd09f 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index ef4dc8586a6a63809b181cc510d5c7fef9d15649..27e0b09e12ffa72965d800ab2e8a2673094e47ce 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 9f38e1e03bf742f0b6ff01bee26e1826f7748959..4b7884706f2a2d0093dfb7b457201477d4fb8b7a 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 0cee94c09f5ae813bad7ebf48456ec7eba931f9e..af948e1778edcebdb60a9c08f2cd609e0b025659 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -150,7 +150,7 @@ class ADODB2_postgres extends ADODB_DataDict {
                }
                return $sql;
        }
-       
+
 
        function DropIndexSQL ($idxname, $tabname = NULL)
        {
@@ -168,7 +168,8 @@ class ADODB2_postgres extends ADODB_DataDict {
         * @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
         * @return array with SQL strings
         */
-       /*function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
+        /*
+       function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
        {
                if (!$tableflds) {
                        if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
index 2adbe0035fef0c37d8356b2463e7cc636c69a31a..d0acc34a37e4455d6fd2edbe6642cec99f6c9412 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
index e13abb6f7e12a03977b8c1e0c47204bae072e516..663a2f474353681a7c31af4cad0ac089161d4b29 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -49,7 +49,7 @@ class  ADODB_access extends ADODB_odbc {
                return " IIF(IsNull($field), $ifNull, $field) "; // if Access
        }
 /*
-       function &MetaTables()
+       function MetaTables()
        {
        global $ADODB_FETCH_MODE;
        
@@ -62,7 +62,7 @@ class  ADODB_access extends ADODB_odbc {
                
                $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
                
-               $arr = &$rs->GetArray();
+               $arr = $rs->GetArray();
                //print_pre($arr);
                $arr2 = array();
                for ($i=0; $i < sizeof($arr); $i++) {
index 25c03e8024e8096b9e7d73a3a67c3945e57f75fa..d300e9225782bfc5b840e92814330b9178b8ed2c 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -147,7 +147,7 @@ class ADODB_ado extends ADOConnection {
 
 */
        
-       function &MetaTables()
+       function MetaTables()
        {
                $arr= array();
                $dbc = $this->_connectionID;
@@ -169,7 +169,7 @@ class ADODB_ado extends ADOConnection {
                return $arr;
        }
        
-       function &MetaColumns($table)
+       function MetaColumns($table)
        {
                $table = strtoupper($table);
                $arr = array();
@@ -204,7 +204,7 @@ class ADODB_ado extends ADOConnection {
 
        
        /* returns queryID or false */
-       function &_query($sql,$inputarr=false) 
+       function _query($sql,$inputarr=false) 
        {
                
                $dbc = $this->_connectionID;
@@ -337,7 +337,7 @@ class ADORecordSet_ado extends ADORecordSet {
 
 
        // returns the field object
-       function &FetchField($fieldOffset = -1) {
+       function FetchField($fieldOffset = -1) {
                $off=$fieldOffset+1; // offsets begin at 1
                
                $o= new ADOFieldObject();
@@ -597,7 +597,6 @@ class ADORecordSet_ado extends ADORecordSet {
                                
                                $this->fields[] = $val;
                                break;
-
                        default:
                                $this->fields[] = $f->value; 
                                break;
@@ -610,7 +609,7 @@ class ADORecordSet_ado extends ADORecordSet {
                @$rs->MoveNext(); // @ needed for some versions of PHP!
                
                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                       $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
+                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                }
                return true;
        }
index 5c0bf0f4cd959d74722ad6cc0f059d4bef29f625..d914b93829ef1a39eec77525aee3844e5ebaa1db 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -101,6 +101,9 @@ class ADODB_ado extends ADOConnection {
                
                if ($argProvider) $dbc->Provider = $argProvider;        
 
+               if ($argProvider) $argHostname = "PROVIDER=$argProvider;DRIVER={SQL Server};SERVER=$argHostname";       
+               
+
                if ($argDatabasename) $argHostname .= ";DATABASE=$argDatabasename";             
                if ($argUsername) $argHostname .= ";$u=$argUsername";
                if ($argPassword)$argHostname .= ";$p=$argPassword";
@@ -167,7 +170,7 @@ class ADODB_ado extends ADOConnection {
 
 */
        
-       function &MetaTables()
+       function MetaTables()
        {
                $arr= array();
                $dbc = $this->_connectionID;
@@ -189,7 +192,7 @@ class ADODB_ado extends ADOConnection {
                return $arr;
        }
        
-       function &MetaColumns($table)
+       function MetaColumns($table)
        {
                $table = strtoupper($table);
                $arr= array();
@@ -221,7 +224,7 @@ class ADODB_ado extends ADOConnection {
        }
        
        /* returns queryID or false */
-       function &_query($sql,$inputarr=false) 
+       function _query($sql,$inputarr=false) 
        {
                try { // In PHP5, all COM errors are exceptions, so to maintain old behaviour...
                
@@ -367,7 +370,7 @@ class ADORecordSet_ado extends ADORecordSet {
 
 
        // returns the field object
-       function &FetchField($fieldOffset = -1) {
+       function FetchField($fieldOffset = -1) {
                $off=$fieldOffset+1; // offsets begin at 1
                
                $o= new ADOFieldObject();
@@ -640,7 +643,7 @@ class ADORecordSet_ado extends ADORecordSet {
                @$rs->MoveNext(); // @ needed for some versions of PHP!
                
                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                       $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
+                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                }
                return true;
        }
index 989a3c40ef50d3d8cddc0f54078fad91529a5266..05cb0e7ce6d8fb8f86a567ace180e51ee0bf7487 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
index 72a42c064a801f777db56939c20c9862a2c73536..5a73e64b94f090f8bad002f43f3b109ec7e1b7e6 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
index 99fe6548e528e01792a2ad8290f76ac92a1d0120..040834eaedff7f6a2479326de8ca9ce2889755da 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -55,7 +55,7 @@ class ADODB_borland_ibase extends ADODB_ibase {
        //              SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
        // Firebird uses
        //              SELECT FIRST 5 SKIP 2 col1, col2 FROM TABLE
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
        {
                if ($nrows > 0) {
                        if ($offset <= 0) $str = " ROWS $nrows "; 
index 764b4b0024e8bdfb2d61517c36020fd578ccdb18..f699c045fdd4795df00a2d1ae343899c8c4deb07 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -50,7 +50,7 @@ class ADODB_csv extends ADOConnection {
                        return $this->_affectedrows;
        }
   
-       function &MetaDatabases()
+       function MetaDatabases()
        {
                return false;
        }
@@ -72,14 +72,14 @@ class ADODB_csv extends ADOConnection {
                return true;
        }
        
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
                return false;
        }
                
                
        // parameters use PostgreSQL convention, not MySQL
-       function &SelectLimit($sql,$nrows=-1,$offset=-1)
+       function SelectLimit($sql,$nrows=-1,$offset=-1)
        {
        global $ADODB_FETCH_MODE;
        
@@ -108,13 +108,13 @@ class ADODB_csv extends ADOConnection {
                
                        $rs->databaseType='csv';                
                        $rs->fetchMode = ($this->fetchMode !== false) ?  $this->fetchMode : $ADODB_FETCH_MODE;
-                       $rs->connection = &$this;
+                       $rs->connection = $this;
                }
                return $rs;
        }
        
        // returns queryID or false
-       function &_Execute($sql,$inputarr=false)
+       function _Execute($sql,$inputarr=false)
        {
        global $ADODB_FETCH_MODE;
        
@@ -166,7 +166,7 @@ class ADODB_csv extends ADOConnection {
                        $this->_affectedrows = $rs->affectedrows;
                        $this->_insertid = $rs->insertid;
                        $rs->databaseType='csv';
-                       $rs->connection = &$this;
+                       $rs->connection = $this;
                }
                return $rs;
        }
index 228eadb68f24ed432ae7737d1743144af55b476e..e99c71ef20e700aaa5516257ef74aac1e952396a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-  V4.98 13 Feb 2008  (c) 2006 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2006 John Lim (jlim#natsoft.com.my). All rights reserved.
 
   This is a version of the ADODB driver for DB2.  It uses the 'ibm_db2' PECL extension
   for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
@@ -335,7 +335,7 @@ class ADODB_db2 extends ADOConnection {
                
                if (!$rs) return false;
                
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $rs->Close();
                $arr2 = array();
                for ($i=0; $i < sizeof($arr); $i++) {
@@ -390,7 +390,7 @@ class ADODB_db2 extends ADOConnection {
        }
        
        
-       function &MetaTables($ttype=false,$schema=false)
+       function MetaTables($ttype=false,$schema=false)
        {
        global $ADODB_FETCH_MODE;
        
@@ -406,7 +406,7 @@ class ADODB_db2 extends ADOConnection {
                        return $false;
                }
                
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                
                $rs->Close();
                $arr2 = array();
@@ -495,7 +495,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
                }
        }
        
-       function &MetaColumns($table)
+       function MetaColumns($table)
        {
        global $ADODB_FETCH_MODE;
        
@@ -511,7 +511,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
                $qid = db2_columns($this->_connectionID, "", $schema, $table, $colname);
                if (empty($qid)) return $false;
                
-               $rs =& new ADORecordSet_db2($qid);
+               $rs = new ADORecordSet_db2($qid);
                $ADODB_FETCH_MODE = $savem;
                
                if (!$rs) return $false;
@@ -563,7 +563,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2
              $qid = db2_primary_keys($this->_connectionID, "", $schema, $table);
                if (empty($qid)) return $false;
                
-               $rs =& new ADORecordSet_db2($qid);
+               $rs = new ADORecordSet_db2($qid);
                $ADODB_FETCH_MODE = $savem;
                
                if (!$rs) return $retarr;
@@ -719,7 +719,7 @@ class ADORecordSet_db2 extends ADORecordSet {
 
 
        // returns the field object
-       function &FetchField($offset = -1) 
+       function FetchField($offset = -1) 
        {
                $o= new ADOFieldObject();
                $o->name = @db2_field_name($this->_queryID,$offset);
@@ -761,10 +761,10 @@ class ADORecordSet_db2 extends ADORecordSet {
        }
        
        // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
-       function &GetArrayLimit($nrows,$offset=-1) 
+       function GetArrayLimit($nrows,$offset=-1) 
        {
                if ($offset <= 0) {
-                       $rs =& $this->GetArray($nrows);
+                       $rs = $this->GetArray($nrows);
                        return $rs;
                }
                $savem = $this->fetchMode;
@@ -773,7 +773,7 @@ class ADORecordSet_db2 extends ADORecordSet {
                $this->fetchMode = $savem;
                
                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                       $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                }
                
                $results = array();
@@ -795,7 +795,7 @@ class ADORecordSet_db2 extends ADORecordSet {
                        $this->fields = @db2_fetch_array($this->_queryID);
                        if ($this->fields) {
                                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                                       $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+                                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                                }
                                return true;
                        }
@@ -811,7 +811,7 @@ class ADORecordSet_db2 extends ADORecordSet {
                $this->fields = db2_fetch_array($this->_queryID);
                if ($this->fields) {
                        if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                               $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+                               $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                        }
                        return true;
                }
index 412534c68a3ebe93f09ff7529ebcd38d1e4f0098..3c8a15a280787eee754464a4b3c1e1b8ac46e1d4 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ @version V5.04a 25 Mar 2008  (c) 2000-2008 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. 
@@ -37,7 +37,7 @@ class ADODB_fbsql extends ADOConnection {
                        return fbsql_affected_rows($this->_connectionID);
        }
   
-       function &MetaDatabases()
+       function MetaDatabases()
        {
                $qid = fbsql_list_dbs($this->_connectionID);
                $arr = array();
@@ -80,7 +80,7 @@ class ADODB_fbsql extends ADOConnection {
                return true;    
        }
        
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
                if ($this->metaColumnsSQL) {
                        
@@ -187,7 +187,7 @@ class ADORecordSet_fbsql extends ADORecordSet{
        
 
 
-       function &FetchField($fieldOffset = -1) {
+       function FetchField($fieldOffset = -1) {
                if ($fieldOffset != -1) {
                        $o =  @fbsql_fetch_field($this->_queryID, $fieldOffset);
                        //$o->max_length = -1; // fbsql returns the max length less spaces -- so it is unrealiable
index 4a1db9ab68137e38887874afd25b0138d8b7d1d6..41b1d7be1a01360fcf8214372fdbdd8599b12825 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -44,7 +44,7 @@ class ADODB_firebird extends ADODB_ibase {
        // Note that Interbase 6.5 uses this ROWS instead - don't you love forking wars!
        //              SELECT col1, col2 FROM table ROWS 5 -- get 5 rows 
        //              SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
        {
                $nrows = (integer) $nrows;
                $offset = (integer) $offset;
@@ -54,9 +54,9 @@ class ADODB_firebird extends ADODB_ibase {
                
                $sql = preg_replace('/^[ \t]*select/i',$str,$sql); 
                if ($secs)
-                       $rs =& $this->CacheExecute($secs,$sql,$inputarr);
+                       $rs = $this->CacheExecute($secs,$sql,$inputarr);
                else
-                       $rs =& $this->Execute($sql,$inputarr);
+                       $rs = $this->Execute($sql,$inputarr);
                        
                return $rs;
        }
index 146c7b18e044364a7ed6212ed147e56439daba51..05bbead64fa7890512fab165631ea8e3bc7ec4b2 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.  
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -159,17 +159,17 @@ class ADODB_ibase extends ADOConnection {
        
        // there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
        // it appears that ibase extension cannot support multiple concurrent queryid's
-       function &_Execute($sql,$inputarr=false) 
+       function _Execute($sql,$inputarr=false) 
        {
        global $ADODB_COUNTRECS;
        
                if ($this->_logsql) {
                        $savecrecs = $ADODB_COUNTRECS;
                        $ADODB_COUNTRECS = true; // force countrecs
-                       $ret =& ADOConnection::_Execute($sql,$inputarr);
+                       $ret = ADOConnection::_Execute($sql,$inputarr);
                        $ADODB_COUNTRECS = $savecrecs;
                } else {
-                       $ret =& ADOConnection::_Execute($sql,$inputarr);
+                       $ret = ADOConnection::_Execute($sql,$inputarr);
                }
                return $ret;
        }
@@ -187,7 +187,7 @@ class ADODB_ibase extends ADOConnection {
                return $ret;
        }
        
-       function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+       function MetaIndexes ($table, $primary = FALSE, $owner=false)
        {
         // save old fetch mode
         global $ADODB_FETCH_MODE;
@@ -326,7 +326,7 @@ class ADODB_ibase extends ADOConnection {
                        if (is_array($iarr)) {
                                if  (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
                                        if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
-                                       $fnarr =& array_merge( array($sql) , $iarr);
+                                       $fnarr = array_merge( array($sql) , $iarr);
                                        $ret = call_user_func_array($fn,$fnarr);
                                } else {
                                        switch(sizeof($iarr)) {
@@ -348,7 +348,7 @@ class ADODB_ibase extends ADOConnection {
                        if (is_array($iarr)) {  
                                if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
                                        if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
-                                       $fnarr =& array_merge( array($conn,$sql) , $iarr);
+                                       $fnarr = array_merge( array($conn,$sql) , $iarr);
                                        $ret = call_user_func_array($fn,$fnarr);
                                } else {
                                        switch(sizeof($iarr)) {
@@ -476,7 +476,7 @@ class ADODB_ibase extends ADOConnection {
        }
        //OPN STUFF end
                // returns array of ADOFieldObjects for current table
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
        global $ADODB_FETCH_MODE;
                
@@ -743,7 +743,7 @@ class ADORecordset_ibase extends ADORecordSet
                        fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
                        fetchField() is retrieved.              */
 
-       function &FetchField($fieldOffset = -1)
+       function FetchField($fieldOffset = -1)
        {
                         $fld = new ADOFieldObject;
                         $ibf = ibase_field_info($this->_queryID,$fieldOffset);
@@ -822,9 +822,9 @@ class ADORecordset_ibase extends ADORecordSet
                
                $this->fields = $f;
                if ($this->fetchMode == ADODB_FETCH_ASSOC) {
-                       $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
+                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                } else if ($this->fetchMode == ADODB_FETCH_BOTH) {
-                       $this->fields =& array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));
+                       $this->fields = array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));
                }
                return true;
        }
index f8766f74c2f060214eb83b92969bad88027c9adb..964a2fc8eeab828b440b7d3371c613aedd41658c 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+* @version V5.04a 25 Mar 2008  (c) 2000-2008 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.
index 59cf39f8ed5e855bef3698da97b6d56337008135..d36f9d1598f3de01c335cc601455527b7936471b 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim. All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim. 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.
@@ -147,7 +147,7 @@ class ADODB_informix72 extends ADOConnection {
        }
 
    
-    function &MetaColumns($table)
+    function MetaColumns($table)
        {
        global $ADODB_FETCH_MODE;
        
@@ -199,7 +199,7 @@ class ADODB_informix72 extends ADOConnection {
                return $false;
        }
        
-   function &xMetaColumns($table)
+   function xMetaColumns($table)
    {
                return ADOConnection::MetaColumns($table,false);
    }
@@ -219,7 +219,7 @@ class ADODB_informix72 extends ADOConnection {
 
                $rs = $this->Execute($sql);
                if (!$rs || $rs->EOF)  return false;
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $a = array();
                foreach($arr as $v) {
                        $coldest=$this->metaColumnNames($v["tabname"]);
@@ -362,7 +362,7 @@ class ADORecordset_informix72 extends ADORecordSet {
                Get column information in the Recordset object. fetchField() can be used in order to obtain information about
                fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
                fetchField() is retrieved.      */
-       function &FetchField($fieldOffset = -1)
+       function FetchField($fieldOffset = -1)
        {
                if (empty($this->_fieldprops)) {
                        $fp = ifx_fieldproperties($this->_queryID);
index 147cd9eda40b5d0d70a2c52ef44a08ad9b50d8e1..30156a2a5a8a93114301cd955374d3aa63bcacc7 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -39,15 +39,16 @@ class ADODB_ldap extends ADOConnection {
 
        # Options configuration information
        var $LDAP_CONNECT_OPTIONS;
-       
+
        # error on binding, eg. "Binding: invalid credentials"
        var $_bind_errmsg = "Binding: %s";
-
+       
        function ADODB_ldap() 
        {               
        }
                
        // returns true or false
+       
        function _connect( $host, $username, $password, $ldapbase)
        {
        global $LDAP_CONNECT_OPTIONS;
@@ -79,7 +80,7 @@ class ADODB_ldap extends ADOConnection {
                }
                
                if (!$bind) {
-                       $e = sprintf($this->_bind_errmsg,ldap_error($this->_connectionID));;
+                       $e = sprintf($this->_bind_errmsg,ldap_error($this->_connectionID));
                        $this->_errorMsg = $e;
                        if ($this->debug) ADOConnection::outp($e);
                        return false;
@@ -152,10 +153,10 @@ class ADODB_ldap extends ADOConnection {
        function _query($sql,$inputarr)
        {
                $rs = @ldap_search( $this->_connectionID, $this->database, $sql );
-               $this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql.': '. ldap_error($this->_connectionID);
+               $this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql.': '.ldap_error($this->_connectionID);
                return $rs; 
        }
-       
+
        function ErrorMsg()
        {
                return $this->_errorMsg;
@@ -165,7 +166,7 @@ class ADODB_ldap extends ADOConnection {
        {
                return @ldap_errno($this->_connectionID);
        }
-
+       
     /* closes the LDAP connection */
        function _close()
        {
@@ -323,7 +324,7 @@ class ADORecordSet_ldap extends ADORecordSet{
     /*
     Return whole recordset as a multi-dimensional associative array
        */
-       function &GetAssoc($force_array = false, $first2cols = false) 
+       function GetAssoc($force_array = false, $first2cols = false) 
        {
                $records = $this->_numOfRows;
         $results = array();
@@ -343,7 +344,7 @@ class ADORecordSet_ldap extends ADORecordSet{
                return $results; 
        }
     
-    function &GetRowAssoc()
+    function GetRowAssoc()
        {
         $results = array();
         foreach ( $this->fields as $k=>$v ) {
index c76c841e91e331adb3e77344b31bac59f632eae5..2048f5fcf2af74d48280ea99f5b70ec00bff0e58 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -14,6 +14,7 @@ Set tabs to 4 for best viewing.
        
 */
 
+
 // security - hide paths
 if (!defined('ADODB_DIR')) die();
 
@@ -33,11 +34,6 @@ if (!defined('ADODB_DIR')) die();
 //      http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
 // Alternatively use:
 //        CONVERT(char(12),datecol,120)
-//
-// Also if your month is showing as month-1, 
-//   e.g. Jan 13, 2002 is showing as 13/0/2002, then see
-//     http://phplens.com/lens/lensforum/msgs.php?id=7048&x=1
-//   it's a localisation problem.
 //----------------------------------------------------------------
 
 
@@ -205,14 +201,14 @@ class ADODB_mssql extends ADOConnection {
        }
        
 
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                if ($nrows > 0 && $offset <= 0) {
                        $sql = preg_replace(
                                '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
-                       $rs =& $this->Execute($sql,$inputarr);
+                       $rs = $this->Execute($sql,$inputarr);
                } else
-                       $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+                       $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
        
                return $rs;
        }
@@ -333,7 +329,7 @@ class ADODB_mssql extends ADOConnection {
        }
        
        
-       function &MetaIndexes($table,$primary=false)
+       function MetaIndexes($table,$primary=false)
        {
                $table = $this->qstr($table);
 
@@ -390,7 +386,7 @@ from sysforeignkeys
 where upper(object_name(fkeyid)) = $table
 order by constraint_name, referenced_table_name, keyno";
                
-               $constraints =& $this->GetArray($sql);
+               $constraints = $this->GetArray($sql);
                
                $ADODB_FETCH_MODE = $save;
                
@@ -436,7 +432,7 @@ order by constraint_name, referenced_table_name, keyno";
 
        // "Stein-Aksel Basma" <basma@accelero.no>
        // tested with MSSQL 2000
-       function &MetaPrimaryKeys($table)
+       function MetaPrimaryKeys($table)
        {
        global $ADODB_FETCH_MODE;
        
@@ -461,14 +457,14 @@ order by constraint_name, referenced_table_name, keyno";
        }
 
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
                if ($mask) {
                        $save = $this->metaTablesSQL;
                        $mask = $this->qstr(($mask));
                        $this->metaTablesSQL .= " AND name like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                if ($mask) {
                        $this->metaTablesSQL = $save;
@@ -727,12 +723,12 @@ order by constraint_name, referenced_table_name, keyno";
        }
        
        // mssql uses a default date like Dec 30 2000 12:00AM
-       function UnixDate($v)
+       static function UnixDate($v)
        {
                return ADORecordSet_array_mssql::UnixDate($v);
        }
        
-       function UnixTimeStamp($v)
+       static function UnixTimeStamp($v)
        {
                return ADORecordSet_array_mssql::UnixTimeStamp($v);
        }       
@@ -804,7 +800,7 @@ class ADORecordset_mssql extends ADORecordSet {
                fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
                fetchField() is retrieved.      */
 
-       function &FetchField($fieldOffset = -1) 
+       function FetchField($fieldOffset = -1) 
        {
                if ($fieldOffset != -1) {
                        $f = @mssql_fetch_field($this->_queryID, $fieldOffset);
@@ -922,12 +918,12 @@ class ADORecordset_mssql extends ADORecordSet {
                return $rez;
        }
        // mssql uses a default date like Dec 30 2000 12:00AM
-       function UnixDate($v)
+       static function UnixDate($v)
        {
                return ADORecordSet_array_mssql::UnixDate($v);
        }
        
-       function UnixTimeStamp($v)
+       static function UnixTimeStamp($v)
        {
                return ADORecordSet_array_mssql::UnixTimeStamp($v);
        }
@@ -942,7 +938,7 @@ class ADORecordSet_array_mssql extends ADORecordSet_array {
        }
        
                // mssql uses a default date like Dec 30 2000 12:00AM
-       function UnixDate($v)
+       static function UnixDate($v)
        {
        
                if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
@@ -973,7 +969,7 @@ class ADORecordSet_array_mssql extends ADORecordSet_array {
                return  mktime(0,0,0,$themth,$theday,$rr[3]);
        }
        
-       function UnixTimeStamp($v)
+       static function UnixTimeStamp($v)
        {
        
                if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
index 504bea484d8bd903f0342aa188b1fff2f4b61c77..1d7845e5d7ff8d65d064b825bf367d7c545658fa 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+* @version V5.04a 25 Mar 2008  (c) 2000-2008 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.
index 7260dfb6beb29f889e559e8fcc34aa120a5053b0..a8b7e5a63e01be787a846cde20a2e09e4fce9f74 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -58,7 +58,7 @@ class ADODB_mysql extends ADOConnection {
        }
        
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {       
                $save = $this->metaTablesSQL;
                if ($showSchema && is_string($showSchema)) {
@@ -69,14 +69,14 @@ class ADODB_mysql extends ADOConnection {
                        $mask = $this->qstr($mask);
                        $this->metaTablesSQL .= " like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                $this->metaTablesSQL = $save;
                return $ret;
        }
        
        
-       function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+       function MetaIndexes ($table, $primary = FALSE, $owner=false)
        {
         // save old fetch mode
         global $ADODB_FETCH_MODE;
@@ -133,7 +133,6 @@ class ADODB_mysql extends ADOConnection {
        function qstr($s,$magic_quotes=false)
        {
                if (is_null($s)) return 'NULL';
-
                if (!$magic_quotes) {
                
                        if (ADODB_PHPVER >= 0x4300) {
@@ -160,7 +159,7 @@ class ADODB_mysql extends ADOConnection {
        function GetOne($sql,$inputarr=false)
        {
                if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) {
-                       $rs =& $this->SelectLimit($sql,1,-1,$inputarr);
+                       $rs = $this->SelectLimit($sql,1,-1,$inputarr);
                        if ($rs) {
                                $rs->Close();
                                if ($rs->EOF) return false;
@@ -182,7 +181,7 @@ class ADODB_mysql extends ADOConnection {
                        return mysql_affected_rows($this->_connectionID);
        }
   
-       // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
+        // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
        // Reference on Last_Insert_ID on the recommended way to simulate sequences
        var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
        var $_genSeqSQL = "create table %s (id int not null)";
@@ -230,7 +229,7 @@ class ADODB_mysql extends ADOConnection {
                return $this->genID;
        }
        
-       function &MetaDatabases()
+       function MetaDatabases()
        {
                $qid = mysql_list_dbs($this->_connectionID);
                $arr = array();
@@ -395,7 +394,7 @@ class ADODB_mysql extends ADOConnection {
                return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
        }
        
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
                $this->_findschema($table,$schema);
                if ($schema) {
@@ -449,9 +448,9 @@ class ADODB_mysql extends ADOConnection {
                        $fld->primary_key = ($rs->fields[3] == 'PRI');
                        $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
                        $fld->binary = (strpos($type,'blob') !== false);
-                       $fld->unsigned = (strpos($type,'unsigned') !== false);  
+                       $fld->unsigned = (strpos($type,'unsigned') !== false);
                        $fld->zerofill = (strpos($type,'zerofill') !== false);
-                       
+
                        if (!$fld->binary) {
                                $d = $rs->fields[4];
                                if ($d != '' && $d != 'NULL') {
@@ -486,16 +485,16 @@ class ADODB_mysql extends ADOConnection {
        }
        
        // parameters use PostgreSQL convention, not MySQL
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
        {
                $offsetStr =($offset>=0) ? ((integer)$offset)."," : '';
                // jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
                if ($nrows < 0) $nrows = '18446744073709551615'; 
                
                if ($secs)
-                       $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
+                       $rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
                else
-                       $rs =& $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
+                       $rs = $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
                return $rs;
        }
        
@@ -631,28 +630,28 @@ class ADORecordSet_mysql extends ADORecordSet{
                $this->_numOfFields = @mysql_num_fields($this->_queryID);
        }
        
-       function &FetchField($fieldOffset = -1) 
+       function FetchField($fieldOffset = -1) 
        {       
                if ($fieldOffset != -1) {
                        $o = @mysql_fetch_field($this->_queryID, $fieldOffset);
                        $f = @mysql_field_flags($this->_queryID,$fieldOffset);
-                       $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com)
+                       if ($o) $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com)
                        //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
-                       $o->binary = (strpos($f,'binary')!== false);
+                       if ($o) $o->binary = (strpos($f,'binary')!== false);
                }
                else if ($fieldOffset == -1) {  /*      The $fieldOffset argument is not provided thus its -1   */
                        $o = @mysql_fetch_field($this->_queryID);
-               $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
+                       if ($o) $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
                //$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
                }
                        
                return $o;
        }
 
-       function &GetRowAssoc($upper=true)
+       function GetRowAssoc($upper=true)
        {
                if ($this->fetchMode == MYSQL_ASSOC && !$upper) $row = $this->fields;
-               else $row =& ADORecordSet::GetRowAssoc($upper);
+               else $row = ADORecordSet::GetRowAssoc($upper);
                return $row;
        }
        
index 0070c917d105f8be760d7ffdaa6727fe71521afc..7315d0c9d0207af1a68157c64a84e65a2d0c89cd 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -144,7 +144,7 @@ class ADODB_mysqli extends ADOConnection {
        function GetOne($sql,$inputarr=false)
        {
                $ret = false;
-               $rs = &$this->Execute($sql,$inputarr);
+               $rs = $this->Execute($sql,$inputarr);
                if ($rs) {      
                        if (!$rs->EOF) $ret = reset($rs->fields);
                        $rs->Close();
@@ -198,7 +198,7 @@ class ADODB_mysqli extends ADOConnection {
        {
                if ($this->transCnt==0) $this->BeginTrans();
                if ($where) $where = ' where '.$where;
-               $rs =& $this->Execute("select $flds from $tables $where for update");
+               $rs = $this->Execute("select $flds from $tables $where for update");
                return !empty($rs); 
        }
        
@@ -251,6 +251,7 @@ class ADODB_mysqli extends ADOConnection {
        // Reference on Last_Insert_ID on the recommended way to simulate sequences
        var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
        var $_genSeqSQL = "create table %s (id int not null)";
+       var $_genSeqCountSQL = "select count(*) from %s";
        var $_genSeq2SQL = "insert into %s values (%s)";
        var $_dropSeqSQL = "drop table %s";
        
@@ -290,10 +291,10 @@ class ADODB_mysqli extends ADOConnection {
                return $this->genID;
        }
        
-       function &MetaDatabases()
+       function MetaDatabases()
        {
                $query = "SHOW DATABASES";
-               $ret =& $this->Execute($query);
+               $ret = $this->Execute($query);
                if ($ret && is_object($ret)){
                   $arr = array();
                        while (!$ret->EOF){
@@ -307,7 +308,7 @@ class ADODB_mysqli extends ADOConnection {
        }
 
          
-       function &MetaIndexes ($table, $primary = FALSE)
+       function MetaIndexes ($table, $primary = FALSE)
        {
                // save old fetch mode
                global $ADODB_FETCH_MODE;
@@ -462,7 +463,7 @@ class ADODB_mysqli extends ADOConnection {
 //             return "from_unixtime(unix_timestamp($date)+$fraction)";
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {       
                $save = $this->metaTablesSQL;
                if ($showSchema && is_string($showSchema)) {
@@ -473,7 +474,7 @@ class ADODB_mysqli extends ADOConnection {
                        $mask = $this->qstr($mask);
                        $this->metaTablesSQL .= " like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                $this->metaTablesSQL = $save;
                return $ret;
@@ -521,7 +522,7 @@ class ADODB_mysqli extends ADOConnection {
            return  $foreign_keys;
        }
        
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
                $false = false;
                if (!$this->metaColumnsSQL)
@@ -610,7 +611,7 @@ class ADODB_mysqli extends ADOConnection {
        }
        
        // parameters use PostgreSQL convention, not MySQL
-       function &SelectLimit($sql,
+       function SelectLimit($sql,
                              $nrows = -1,
                              $offset = -1,
                              $inputarr = false, 
@@ -620,9 +621,9 @@ class ADODB_mysqli extends ADOConnection {
                if ($nrows < 0) $nrows = '18446744073709551615';
                
                if ($secs)
-                       $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr);
+                       $rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr );
                else
-                       $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr);
+                       $rs = $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr );
                        
                return $rs;
        }
@@ -816,7 +817,7 @@ class ADORecordSet_mysqli extends ADORecordSet{
 131072 = MYSQLI_BINCMP_FLAG
 */
 
-       function &FetchField($fieldOffset = -1) 
+       function FetchField($fieldOffset = -1) 
        {       
                $fieldnr = $fieldOffset;
                if ($fieldOffset != -1) {
@@ -834,11 +835,11 @@ class ADORecordSet_mysqli extends ADORecordSet{
                return $o;
        }
 
-       function &GetRowAssoc($upper = true)
+       function GetRowAssoc($upper = true)
        {
                if ($this->fetchMode == MYSQLI_ASSOC && !$upper) 
                  return $this->fields;
-               $row =& ADORecordSet::GetRowAssoc($upper);
+               $row = ADORecordSet::GetRowAssoc($upper);
                return $row;
        }
        
@@ -1027,12 +1028,12 @@ class ADORecordSet_mysqli extends ADORecordSet{
 }
 
 class ADORecordSet_array_mysqli extends ADORecordSet_array {
+  
   function ADORecordSet_array_mysqli($id=-1,$mode=false) 
   {
     $this->ADORecordSet_array($id,$mode);
   }
   
-
        function MetaType($t, $len = -1, $fieldobj = false)
        {
                if (is_object($t)) {
@@ -1130,4 +1131,4 @@ class ADORecordSet_array_mysqli extends ADORecordSet_array {
   
 }
 
-?>
+?>
\ No newline at end of file
diff --git a/lib/adodb/drivers/adodb-mysqlpo.inc.php b/lib/adodb/drivers/adodb-mysqlpo.inc.php
new file mode 100644 (file)
index 0000000..37b1b80
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+
+/*
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
+  Set tabs to 8.
+  
+  MySQL code that supports transactions. For MySQL 3.23 or later.
+  Code from James Poon <jpoon88@yahoo.com>
+  
+  Requires mysql client. Works on Windows and Unix.
+*/
+
+// security - hide paths
+if (!defined('ADODB_DIR')) die();
+
+include_once(ADODB_DIR."/drivers/adodb-mysql.inc.php");
+
+
+class ADODB_mysqlt extends ADODB_mysql {
+       var $databaseType = 'mysqlt';
+       var $ansiOuter = true; // for Version 3.23.17 or later
+       var $hasTransactions = true;
+       var $autoRollback = true; // apparently mysql does not autorollback properly 
+       
+       function ADODB_mysqlt() 
+       {                       
+       global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 'ext_';
+       }
+       
+       function BeginTrans()
+       {         
+               if ($this->transOff) return true;
+               $this->transCnt += 1;
+               $this->Execute('SET AUTOCOMMIT=0');
+               $this->Execute('BEGIN');
+               return true;
+       }
+       
+       function CommitTrans($ok=true) 
+       {
+               if ($this->transOff) return true; 
+               if (!$ok) return $this->RollbackTrans();
+               
+               if ($this->transCnt) $this->transCnt -= 1;
+               $this->Execute('COMMIT');
+               $this->Execute('SET AUTOCOMMIT=1');
+               return true;
+       }
+       
+       function RollbackTrans()
+       {
+               if ($this->transOff) return true;
+               if ($this->transCnt) $this->transCnt -= 1;
+               $this->Execute('ROLLBACK');
+               $this->Execute('SET AUTOCOMMIT=1');
+               return true;
+       }
+       
+       function RowLock($tables,$where='',$flds='1 as adodb_ignore') 
+       {
+               if ($this->transCnt==0) $this->BeginTrans();
+               if ($where) $where = ' where '.$where;
+               $rs = $this->Execute("select $flds from $tables $where for update");
+               return !empty($rs); 
+       }
+       
+}
+
+class ADORecordSet_mysqlt extends ADORecordSet_mysql{  
+       var $databaseType = "mysqlt";
+       
+       function ADORecordSet_mysqlt($queryID,$mode=false) 
+       {
+               if ($mode === false) { 
+                       global $ADODB_FETCH_MODE;
+                       $mode = $ADODB_FETCH_MODE;
+               }
+               
+               switch ($mode)
+               {
+               case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
+               case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
+               
+               case ADODB_FETCH_DEFAULT:
+               case ADODB_FETCH_BOTH:
+               default: $this->fetchMode = MYSQL_BOTH; break;
+               }
+       
+               $this->adodbFetchMode = $mode;
+               $this->ADORecordSet($queryID);  
+       }
+       
+       function MoveNext()
+       {
+               if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
+                       $this->_currentRow += 1;
+                       return true;
+               }
+               if (!$this->EOF) {
+                       $this->_currentRow += 1;
+                       $this->EOF = true;
+               }
+               return false;
+       }
+}
+
+class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {    
+
+       function ADORecordSet_ext_mysqlt($queryID,$mode=false) 
+       {
+               if ($mode === false) { 
+                       global $ADODB_FETCH_MODE;
+                       $mode = $ADODB_FETCH_MODE;
+               }
+               switch ($mode)
+               {
+               case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
+               case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
+               
+               case ADODB_FETCH_DEFAULT:
+               case ADODB_FETCH_BOTH:
+               default: 
+                       $this->fetchMode = MYSQL_BOTH; break;
+               }
+               $this->adodbFetchMode = $mode;
+               $this->ADORecordSet($queryID);  
+       }
+       
+       function MoveNext()
+       {
+               return adodb_movenext($this);
+       }
+}
+
+?>
\ No newline at end of file
index 6badabdf1ec14f80e67d5be0cc609a7c52dcf2a5..8812f2b1ce233f0202d60b90229919587e1750c7 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -80,7 +80,7 @@ class ADODB_mysqlt extends ADODB_mysql {
        {
                if ($this->transCnt==0) $this->BeginTrans();
                if ($where) $where = ' where '.$where;
-               $rs =& $this->Execute("select $flds from $tables $where for update");
+               $rs = $this->Execute("select $flds from $tables $where for update");
                return !empty($rs); 
        }
        
index 7db95b4b0e4604753e8a8c6f67baaa8c5249ff93..07256336fe7cb45e2457092e581fb9bb037222e7 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
  
   First cut at the Netezza Driver by Josh Eldridge joshuae74#hotmail.com
  Based on the previous postgres drivers.
@@ -53,7 +53,7 @@ class ADODB_netezza extends ADODB_postgres64 {
        
        }
        
-       function &MetaColumns($table,$upper=true) 
+       function MetaColumns($table,$upper=true) 
        {
        
        // Changed this function to support Netezza which has no concept of keys
@@ -67,7 +67,7 @@ class ADODB_netezza extends ADODB_postgres64 {
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
                
-               $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+               $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
                if (isset($savem)) $this->SetFetchMode($savem);
                $ADODB_FETCH_MODE = $save;
                
index b4b8e95c8b6af4016b5c9ab767e0957b2c1334a9..cce7e6b20e6e1577b87d98e06c33480bb92067b3 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-  version V4.98 13 Feb 2008 (c) 2000-2008 John Lim. All rights reserved.
+  version V5.04a 25 Mar 2008  (c) 2000-2008 John Lim. All rights reserved.
 
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
@@ -83,11 +83,11 @@ class ADODB_oci8 extends ADOConnection {
        var $firstrows = true; // enable first rows optimization on SelectLimit()
        var $selectOffsetAlg1 = 100; // when to use 1st algorithm of selectlimit.
        var $NLS_DATE_FORMAT = 'YYYY-MM-DD';  // To include time, use 'RRRR-MM-DD HH24:MI:SS'
-       var $dateformat = 'YYYY-MM-DD'; // for DBDate()
+       var $dateformat = 'YYYY-MM-DD'; // DBDate format
        var $useDBDateFormatForTextInput=false;
        var $datetime = false; // MetaType('DATE') returns 'D' (datetime==false) or 'T' (datetime == true)
        var $_refLOBs = array();
-       
+               
        // var $ansiOuter = true; // if oracle9
     
        function ADODB_oci8() 
@@ -96,8 +96,8 @@ class ADODB_oci8 extends ADOConnection {
                if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
        }
        
-       /*  Function &MetaColumns($table) added by smondino@users.sourceforge.net*/
-       function &MetaColumns($table) 
+       /*  function MetaColumns($table) added by smondino@users.sourceforge.net*/
+       function MetaColumns($table) 
        {
        global $ADODB_FETCH_MODE;
        
@@ -141,7 +141,7 @@ class ADODB_oci8 extends ADOConnection {
        
        function Time()
        {
-               $rs =& $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
+               $rs = $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
                if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
                
                return false;
@@ -310,14 +310,14 @@ NATSOFT.DOMAIN =
                return $this->GetOne("select $flds from $tables where $where for update");
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
                if ($mask) {
                        $save = $this->metaTablesSQL;
                        $mask = $this->qstr(strtoupper($mask));
                        $this->metaTablesSQL .= " AND upper(table_name) like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                if ($mask) {
                        $this->metaTablesSQL = $save;
@@ -326,7 +326,7 @@ NATSOFT.DOMAIN =
        }
        
        // Mark Newnham 
-       function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+       function MetaIndexes ($table, $primary = FALSE, $owner=false)
        {
         // save old fetch mode
         global $ADODB_FETCH_MODE;
@@ -563,7 +563,7 @@ NATSOFT.DOMAIN =
         This implementation does not appear to work with oracle 8.0.5 or earlier. Comment
         out this function then, and the slower SelectLimit() in the base class will be used.
        */
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                // seems that oracle only supports 1 hint comment in 8i
                if ($this->firstrows) {
@@ -573,7 +573,7 @@ NATSOFT.DOMAIN =
                                $sql = preg_replace('/^[ \t\n]*select/i','SELECT /*+FIRST_ROWS*/',$sql);
                }
                
-               if ($offset < $this->selectOffsetAlg1 && 0 < $nrows  && $nrows < 1000) {
+               if ($offset < $this->selectOffsetAlg1 && 0 < $nrows && $nrows < 1000) {
                        if ($nrows > 0) {       
                                if ($offset > 0) $nrows += $offset;
                                //$inputarr['adodb_rownum'] = $nrows;
@@ -587,7 +587,7 @@ NATSOFT.DOMAIN =
                        }
                        // note that $nrows = 0 still has to work ==> no rows returned
 
-                       $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+                       $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
                        return $rs;
                        
                } else {
@@ -651,8 +651,8 @@ NATSOFT.DOMAIN =
                                $inputarr['adodb_nrows'] = $nrows;
                                $inputarr['adodb_offset'] = $offset;
                                
-                       if ($secs2cache>0) $rs =& $this->CacheExecute($secs2cache, $sql,$inputarr);
-                       else $rs =& $this->Execute($sql,$inputarr);
+                       if ($secs2cache>0) $rs = $this->CacheExecute($secs2cache, $sql,$inputarr);
+                       else $rs = $this->Execute($sql,$inputarr);
                        return $rs;
                }
        
@@ -745,17 +745,19 @@ NATSOFT.DOMAIN =
         * @param [inputarr]    holds the input data to bind to. Null elements will be set to null.
         * @return              RecordSet or false
         */
-       function &Execute($sql,$inputarr=false) 
+       function Execute($sql,$inputarr=false) 
        {
                if ($this->fnExecute) {
                        $fn = $this->fnExecute;
-                       $ret =& $fn($this,$sql,$inputarr);
+                       $ret = $fn($this,$sql,$inputarr);
                        if (isset($ret)) return $ret;
                }
                if ($inputarr) {
                        #if (!is_array($inputarr)) $inputarr = array($inputarr);
+                       
                        $element0 = reset($inputarr);
                        
+                       if (!$this->_bindInputArray) {
                        # is_object check because oci8 descriptors can be passed in
                        if (is_array($element0) && !is_object(reset($element0))) {
                                if (is_string($sql))
@@ -764,15 +766,48 @@ NATSOFT.DOMAIN =
                                        $stmt = $sql;
                                        
                                foreach($inputarr as $arr) {
-                                       $ret =& $this->_Execute($stmt,$arr);
+                                       $ret = $this->_Execute($stmt,$arr);
                                        if (!$ret) return $ret;
                                }
                        } else {
-                               $ret =& $this->_Execute($sql,$inputarr);
+                               $sqlarr = explode(':',$sql);
+                               $sql = '';
+                               $lastnomatch = -2;
+                               #var_dump($sqlarr);echo "<hr>";var_dump($inputarr);echo"<hr>";
+                               foreach($sqlarr as $k => $str) {
+                                               if ($k == 0) { $sql = $str; continue; }
+                                               // we need $lastnomatch because of the following datetime, 
+                                               // eg. '10:10:01', which causes code to think that there is bind param :10 and :1
+                                               $ok = preg_match('/^([0-9]*)/', $str, $arr); 
+                       
+                                               if (!$ok) $sql .= $str;
+                                               else {
+                                                       $at = $arr[1];
+                                                       if (isset($inputarr[$at]) || is_null($inputarr[$at])) {
+                                                               if ((strlen($at) == strlen($str) && $k < sizeof($arr)-1)) {
+                                                                       $sql .= ':'.$str;
+                                                                       $lastnomatch = $k;
+                                                               } else if ($lastnomatch == $k-1) {
+                                                                       $sql .= ':'.$str;
+                                                               } else {
+                                                                       if (is_null($inputarr[$at])) $sql .= 'null';
+                                                                       else $sql .= $this->qstr($inputarr[$at]);
+                                                                       $sql .= substr($str, strlen($at));
+                                                               }
+                                                       } else {
+                                                               $sql .= ':'.$str;
+                                                       }
+                                                       
+                                               }
+                                       }
+                                       $inputarr = false;
+                               }
                        }
+                       $ret = $this->_Execute($sql,$inputarr);
+                       
                        
                } else {
-                       $ret =& $this->_Execute($sql,false);
+                       $ret = $this->_Execute($sql,false);
                }
 
                return $ret;
@@ -823,7 +858,7 @@ NATSOFT.DOMAIN =
                                array('VAR1' => 'Mr Bean'));
                        
        */
-       function &ExecuteCursor($sql,$cursorName='rs',$params=false)
+       function ExecuteCursor($sql,$cursorName='rs',$params=false)
        {
                if (is_array($sql)) $stmt = $sql;
                else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate OCINewCursor
@@ -840,7 +875,7 @@ NATSOFT.DOMAIN =
                } else
                        $hasref = false;
                        
-               $rs =& $this->Execute($stmt);
+               $rs = $this->Execute($stmt);
                if ($rs) {
                        if ($rs->databaseType == 'array') OCIFreeCursor($stmt[4]);
                        else if ($hasref) $rs->_refcursor = $stmt[4];
@@ -900,7 +935,7 @@ NATSOFT.DOMAIN =
                $this->_refLOBs[$numlob]['LOB'] = OCINewDescriptor($this->_connectionID, oci_lob_desc($type));
                        $this->_refLOBs[$numlob]['TYPE'] = $isOutput;
                        
-                       $tmp = &$this->_refLOBs[$numlob]['LOB'];
+                       $tmp = $this->_refLOBs[$numlob]['LOB'];
                $rez = OCIBindByName($stmt[1], ":".$name, $tmp, -1, $type);
                        if ($this->debug) {
                                ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (".$name.") binded");
@@ -910,12 +945,12 @@ NATSOFT.DOMAIN =
                        if ($isOutput == false) {
                                $var = $this->BlobEncode($var);
                                $tmp->WriteTemporary($var);
-                               $this->_refLOBs[$numlob]['VAR'] = &$var;
+                               $this->_refLOBs[$numlob]['VAR'] = $var;
                                if ($this->debug) {
                                        ADOConnection::outp("<b>Bind</b>: LOB has been written to temp");
                                }
                        } else {
-                               $this->_refLOBs[$numlob]['VAR'] = &$var;
+                               $this->_refLOBs[$numlob]['VAR'] = $var;
                        }
                        $rez = $tmp;
                } else {
@@ -986,7 +1021,7 @@ NATSOFT.DOMAIN =
                                $bindpos = $sql[3];
                                if (isset($this->_bind[$bindpos])) {
                                // all tied up already
-                                       $bindarr = &$this->_bind[$bindpos];
+                                       $bindarr = $this->_bind[$bindpos];
                                } else {
                                // one statement to bind them all
                                        $bindarr = array();
@@ -994,7 +1029,7 @@ NATSOFT.DOMAIN =
                                                $bindarr[$k] = $v;
                                                OCIBindByName($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
                                        }
-                                       $this->_bind[$bindpos] = &$bindarr;
+                                       $this->_bind[$bindpos] = $bindarr;
                                }
                        }
                } else {
@@ -1014,7 +1049,13 @@ NATSOFT.DOMAIN =
                                        else
                                                OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
                                        
-                                       if ($this->debug==99) echo "name=:$k",' var='.$inputarr[$k][0],' len='.$v[1],' type='.$v[2],'<br>';
+                                       if ($this->debug==99) {
+                                               if (is_object($v[0])) 
+                                                       echo "name=:$k",' len='.$v[1],' type='.$v[2],'<br>';
+                                               else
+                                                       echo "name=:$k",' var='.$inputarr[$k][0],' len='.$v[1],' type='.$v[2],'<br>';
+                                               
+                                       }
                                } else {
                                        $len = -1;
                                        if ($v === ' ') $len = 1;
@@ -1123,7 +1164,7 @@ SELECT /*+ RULE */ distinct b.column_name
 
                $rs = $this->Execute($sql);
                if ($rs && !$rs->EOF) {
-                       $arr =& $rs->GetArray();
+                       $arr = $rs->GetArray();
                        $a = array();
                        foreach($arr as $v) {
                                $a[] = reset($v);
@@ -1154,7 +1195,7 @@ SELECT /*+ RULE */ distinct b.column_name
        from {$tabp}constraints
        where constraint_type = 'R' and table_name = $table $owner";
                
-               $constraints =& $this->GetArray($sql);
+               $constraints = $this->GetArray($sql);
                $arr = false;
                foreach($constraints as $constr) {
                        $cons = $this->qstr($constr[0]);
@@ -1319,7 +1360,7 @@ class ADORecordset_oci8 extends ADORecordSet {
        }
        
        /* For some reason, OCIcolumnname fails when called after _initrs() so we cache it */
-       function &FetchField($fieldOffset = -1)
+       function FetchField($fieldOffset = -1)
        {
                return $this->_fieldobjs[$fieldOffset];
        }
@@ -1357,7 +1398,7 @@ class ADORecordset_oci8 extends ADORecordSet {
        
        /*
        # does not work as first record is retrieved in _initrs(), so is not included in GetArray()
-       function &GetArray($nRows = -1) 
+       function GetArray($nRows = -1) 
        {
        global $ADODB_OCI8_GETARRAY;
        
@@ -1376,7 +1417,7 @@ class ADORecordset_oci8 extends ADORecordSet {
                                if (ADODB_ASSOC_CASE != 2 || $this->databaseType != 'oci8') break;
                                
                                $ncols = @OCIfetchstatement($this->_queryID, $assoc, 0, $nRows, OCI_FETCHSTATEMENT_BY_ROW);
-                               $results =& array_merge(array($this->fields),$assoc);
+                               $results = array_merge(array($this->fields),$assoc);
                                return $results;
                        
                        default:
@@ -1384,16 +1425,16 @@ class ADORecordset_oci8 extends ADORecordSet {
                        }
                }
                        
-               $results =& ADORecordSet::GetArray($nRows);
+               $results = ADORecordSet::GetArray($nRows);
                return $results;
                
        } */
        
        /* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
-       function &GetArrayLimit($nrows,$offset=-1) 
+       function GetArrayLimit($nrows,$offset=-1) 
        {
                if ($offset <= 0) {
-                       $arr =& $this->GetArray($nrows);
+                       $arr = $this->GetArray($nrows);
                        return $arr;
                }
                $arr = array();
index 3528c7b062142e759092e3caeec206abbc7e0d10..b1c75b148a428424d6b94aecf7ddb5f87ec07261 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008  (c) 2000-2008 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. 
@@ -26,7 +26,7 @@ class ADODB_oci805 extends ADODB_oci8 {
                $this->ADODB_oci8();
        }
        
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                // seems that oracle only supports 1 hint comment in 8i
                if (strpos($sql,'/*+') !== false)
index 174d15ce3cc1a69f7c37754d58c2679904b3ecf8..33c7eeebc851a6140a2d11e56653f46bae6345a6 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim. All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim. 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.
@@ -98,7 +98,7 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
        }
        
        // lowercase field names...
-       function &_FetchField($fieldOffset = -1)
+       function _FetchField($fieldOffset = -1)
        {
                 $fld = new ADOFieldObject;
                 $fieldOffset += 1;
@@ -149,7 +149,7 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
        }       
        
        /* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
-       function &GetArrayLimit($nrows,$offset=-1) 
+       function GetArrayLimit($nrows,$offset=-1) 
        {
                if ($offset <= 0) {
                        $arr = $this->GetArray($nrows);
index a524fb75c067bd9a19761a80c40cd89d4cb3f1b3..38099920ac927da8e96d08c1dee87d3877add14d 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -252,7 +252,7 @@ class ADODB_odbc extends ADOConnection {
                if (!$rs) return false;
                $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
                
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $rs->Close();
                //print_r($arr);
                $arr2 = array();
@@ -264,7 +264,7 @@ class ADODB_odbc extends ADOConnection {
        
        
        
-       function &MetaTables($ttype=false)
+       function MetaTables($ttype=false)
        {
        global $ADODB_FETCH_MODE;
        
@@ -281,7 +281,7 @@ class ADODB_odbc extends ADOConnection {
                }
                $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
                
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                //print_r($arr);
                
                $rs->Close();
@@ -370,7 +370,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
                }
        }
        
-       function &MetaColumns($table)
+       function MetaColumns($table)
        {
        global $ADODB_FETCH_MODE;
        
@@ -422,7 +422,7 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od
                }
                if (empty($qid)) return $false;
                
-               $rs =& new ADORecordSet_odbc($qid);
+               $rs = new ADORecordSet_odbc($qid);
                $ADODB_FETCH_MODE = $savem;
                
                if (!$rs) return $false;
@@ -614,7 +614,7 @@ class ADORecordSet_odbc extends ADORecordSet {
 
 
        // returns the field object
-       function &FetchField($fieldOffset = -1) 
+       function FetchField($fieldOffset = -1) 
        {
                
                $off=$fieldOffset+1; // offsets begin at 1
@@ -661,10 +661,10 @@ class ADORecordSet_odbc extends ADORecordSet {
        }
        
        // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
-       function &GetArrayLimit($nrows,$offset=-1) 
+       function GetArrayLimit($nrows,$offset=-1) 
        {
                if ($offset <= 0) {
-                       $rs =& $this->GetArray($nrows);
+                       $rs = $this->GetArray($nrows);
                        return $rs;
                }
                $savem = $this->fetchMode;
@@ -673,7 +673,7 @@ class ADORecordSet_odbc extends ADORecordSet {
                $this->fetchMode = $savem;
                
                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                       $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                }
                
                $results = array();
@@ -700,7 +700,7 @@ class ADORecordSet_odbc extends ADORecordSet {
                        }
                        if ($rez) {
                                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                                       $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+                                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                                }
                                return true;
                        }
@@ -721,7 +721,7 @@ class ADORecordSet_odbc extends ADORecordSet {
                }
                if ($rez) {
                        if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                               $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+                               $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
                        }
                        return true;
                }
index e5826960d08a7e41e7b0d65838a7a0f3da6c9515..3a3449ff3b42c5183a12755aa6335206988aee2c 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -140,7 +140,7 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
                return $this->GetOne("select $flds from $tables where $where for update");
        }
        
-       function &MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%")
+       function MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%")
        {
        global $ADODB_FETCH_MODE;
        
@@ -157,7 +157,7 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
                }
                $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
                
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                //print_r($arr);
                
                $rs->Close();
@@ -184,7 +184,7 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
                return $arr2;
        }
 
-       function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+       function MetaIndexes ($table, $primary = FALSE, $owner=false)
        {
         // save old fetch mode
         global $ADODB_FETCH_MODE;
@@ -278,20 +278,20 @@ class ADODB_ODBC_DB2 extends ADODB_odbc {
        } 
  
        
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
        {
                $nrows = (integer) $nrows;
                if ($offset <= 0) {
                // could also use " OPTIMIZE FOR $nrows ROWS "
                        if ($nrows >= 0) $sql .=  " FETCH FIRST $nrows ROWS ONLY ";
-                       $rs =& $this->Execute($sql,$inputArr);
+                       $rs = $this->Execute($sql,$inputArr);
                } else {
                        if ($offset > 0 && $nrows < 0);
                        else {
                                $nrows += $offset;
                                $sql .=  " FETCH FIRST $nrows ROWS ONLY ";
                        }
-                       $rs =& ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
+                       $rs = ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
                }
                
                return $rs;
index 7c4c93668e45d9376c11dc10b5e38f40f2dd69a4..5754ee0151082f9b66c3a0316e86f4bf951d616a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -93,7 +93,7 @@ from sysforeignkeys
 where upper(object_name(fkeyid)) = $table
 order by constraint_name, referenced_table_name, keyno";
                
-               $constraints =& $this->GetArray($sql);
+               $constraints = $this->GetArray($sql);
                
                $ADODB_FETCH_MODE = $save;
                
@@ -115,14 +115,14 @@ order by constraint_name, referenced_table_name, keyno";
                return $arr2;
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
                if ($mask) {$this->debug=1;
                        $save = $this->metaTablesSQL;
                        $mask = $this->qstr($mask);
                        $this->metaTablesSQL .= " AND name like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                if ($mask) {
                        $this->metaTablesSQL = $save;
@@ -130,14 +130,14 @@ order by constraint_name, referenced_table_name, keyno";
                return $ret;
        }
        
-       function &MetaColumns($table)
+       function MetaColumns($table)
        {
                $arr = ADOConnection::MetaColumns($table);
                return $arr;
        }
        
        
-       function &MetaIndexes($table,$primary=false)
+       function MetaIndexes($table,$primary=false)
        {
                $table = $this->qstr($table);
 
@@ -196,7 +196,7 @@ order by constraint_name, referenced_table_name, keyno";
        
        // "Stein-Aksel Basma" <basma@accelero.no>
        // tested with MSSQL 2000
-       function &MetaPrimaryKeys($table)
+       function MetaPrimaryKeys($table)
        {
        global $ADODB_FETCH_MODE;
        
@@ -220,14 +220,14 @@ order by constraint_name, referenced_table_name, keyno";
                return $false;    
        }
        
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                if ($nrows > 0 && $offset <= 0) {
                        $sql = preg_replace(
                                '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
-                       $rs =& $this->Execute($sql,$inputarr);
+                       $rs = $this->Execute($sql,$inputarr);
                } else
-                       $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+                       $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
                        
                return $rs;
        }
index 7296e875f5228d4fcda1aaf69724d274f46ab3df..6f2bd5b28396f5ea335a2bd161a25e974d59ff51 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -36,7 +36,7 @@ class  ADODB_odbc_oracle extends ADODB_odbc {
                $this->ADODB_odbc();
        }
                
-       function &MetaTables() 
+       function MetaTables() 
        {
                $false = false;
                $rs = $this->Execute($this->metaTablesSQL);
@@ -50,7 +50,7 @@ class  ADODB_odbc_oracle extends ADODB_odbc {
                return $arr2;
        }
        
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
        global $ADODB_FETCH_MODE;
        
index 64def5e2e13227ac198468bf217fa8d80ff3bc34..e9fe830feaac9589e1c8c931d25340640705156d 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt.
@@ -273,7 +273,7 @@ class ADODB_odbtp extends ADOConnection{
                return true;
        }
        
-       function &MetaTables($ttype='',$showSchema=false,$mask=false)
+       function MetaTables($ttype='',$showSchema=false,$mask=false)
        {
        global $ADODB_FETCH_MODE;
 
@@ -281,7 +281,7 @@ class ADODB_odbtp extends ADOConnection{
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                if ($this->fetchMode !== false) $savefm = $this->SetFetchMode(false);
                
-               $arr =& $this->GetArray("||SQLTables||||$ttype");
+               $arr = $this->GetArray("||SQLTables||||$ttype");
                
                if (isset($savefm)) $this->SetFetchMode($savefm);
                $ADODB_FETCH_MODE = $savem;
@@ -295,7 +295,7 @@ class ADODB_odbtp extends ADOConnection{
                return $arr2;
        }
        
-       function &MetaColumns($table,$upper=true)
+       function MetaColumns($table,$upper=true)
        {
        global $ADODB_FETCH_MODE;
 
@@ -341,13 +341,13 @@ class ADODB_odbtp extends ADOConnection{
                return $retarr;
        }
 
-       function &MetaPrimaryKeys($table, $owner='')
+       function MetaPrimaryKeys($table, $owner='')
        {
        global $ADODB_FETCH_MODE;
 
                $savem = $ADODB_FETCH_MODE;
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-               $arr =& $this->GetArray("||SQLPrimaryKeys||$owner|$table");
+               $arr = $this->GetArray("||SQLPrimaryKeys||$owner|$table");
                $ADODB_FETCH_MODE = $savem;
 
                //print_r($arr);
@@ -358,13 +358,13 @@ class ADODB_odbtp extends ADOConnection{
                return $arr2;
        }
 
-       function &MetaForeignKeys($table, $owner='', $upper=false)
+       function MetaForeignKeys($table, $owner='', $upper=false)
        {
        global $ADODB_FETCH_MODE;
 
                $savem = $ADODB_FETCH_MODE;
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-               $constraints =& $this->GetArray("||SQLForeignKeys|||||$owner|$table");
+               $constraints = $this->GetArray("||SQLForeignKeys|||||$owner|$table");
                $ADODB_FETCH_MODE = $savem;
 
                $arr = false;
@@ -424,13 +424,13 @@ class ADODB_odbtp extends ADOConnection{
                return $ret;
        }
 
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                // TOP requires ORDER BY for Visual FoxPro
                if( $this->odbc_driver == ODB_DRIVER_FOXPRO ) {
                        if (!preg_match('/ORDER[ \t\r\n]+BY/is',$sql)) $sql .= ' ORDER BY 1';
                }
-               $ret =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+               $ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
                return $ret;
        }
 
@@ -602,7 +602,7 @@ class ADORecordSet_odbtp extends ADORecordSet {
                }
        }
 
-       function &FetchField($fieldOffset = 0)
+       function FetchField($fieldOffset = 0)
        {
                $off=$fieldOffset; // offsets begin at 0
                $o= new ADOFieldObject();
index 389f2cba3adb79544aae7e261c8d511522c68778..5af24c0f97f122c9a8ca378c72362f6a31a68be9 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-       V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+       V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt.
index 65b04caa6ddc541773e88ead7755de55001a2e96..addc549207346b976e46c8f4cf74569c5df78d65 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -248,7 +248,7 @@ class ADORecordset_oracle extends ADORecordSet {
                           fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
                           fetchField() is retrieved.           */
 
-          function &FetchField($fieldOffset = -1)
+          function FetchField($fieldOffset = -1)
           {
                        $fld = new ADOFieldObject;
                        $fld->name = ora_columnname($this->_queryID, $fieldOffset);
index 5d43b587794be4c0b70340fe51d361303e5e1c68..f7ee6d0e9a1089480d701073b72fcaf19c09e5b6 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -64,6 +64,9 @@ function adodb_pdo_type($t)
 
 
 
+
+
+
 class ADODB_pdo extends ADOConnection {
        var $databaseType = "pdo";      
        var $dataProvider = "pdo";
@@ -89,7 +92,7 @@ class ADODB_pdo extends ADOConnection {
        
        function _UpdatePDO()
        {
-               $d = &$this->_driver;
+               $d = $this->_driver;
                $this->fmtDate = $d->fmtDate;
                $this->fmtTimeStamp = $d->fmtTimeStamp;
                $this->replaceQuote = $d->replaceQuote;
@@ -112,7 +115,7 @@ class ADODB_pdo extends ADOConnection {
                if (!empty($this->_driver->_hasdual)) $sql = "select $this->sysTimeStamp from dual";
                else $sql = "select $this->sysTimeStamp";
                
-               $rs =& $this->_Execute($sql);
+               $rs = $this->_Execute($sql);
                if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
                
                return false;
@@ -355,8 +358,6 @@ class ADODB_pdo extends ADOConnection {
        }
 }
 
-
-
 class ADODB_pdo_base extends ADODB_pdo {
 
        var $sysDate = "'?'";
@@ -391,7 +392,6 @@ class ADODB_pdo_base extends ADODB_pdo {
        }
 }
 
-
 class ADOPDOStatement {
 
        var $databaseType = "pdo";              
@@ -508,7 +508,7 @@ class ADORecordSet_pdo extends ADORecordSet {
        }
 
        // returns the field object
-       function &FetchField($fieldOffset = -1) 
+       function FetchField($fieldOffset = -1) 
        {
                $off=$fieldOffset+1; // offsets begin at 1
                
index 2a9958c7fee6b218caa10695005ab53404b411d6..a6830942720ae67cabcd6c4989cb070cc1f138d8 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
index c24c010519d13f7b9ca7c2907369f7180a759f74..70b73b0174f4930781aa5c5d01053488e12fa21a 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -18,7 +18,7 @@ class ADODB_pdo_mysql extends ADODB_pdo {
        var $hasGenID = true;
        var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
        var $_dropSeqSQL = "drop table %s";
-       
+
        var $nameQuote = '`';
 
        function _init($parentDriver)
@@ -48,7 +48,7 @@ class ADODB_pdo_mysql extends ADODB_pdo {
                return $arr;
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {       
                $save = $this->metaTablesSQL;
                if ($showSchema && is_string($showSchema)) {
@@ -59,7 +59,7 @@ class ADODB_pdo_mysql extends ADODB_pdo {
                        $mask = $this->qstr($mask);
                        $this->metaTablesSQL .= " like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                $this->metaTablesSQL = $save;
                return $ret;
@@ -76,7 +76,7 @@ class ADODB_pdo_mysql extends ADODB_pdo {
                $this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
        }
        
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
                $this->_findschema($table,$schema);
                if ($schema) {
@@ -156,16 +156,16 @@ class ADODB_pdo_mysql extends ADODB_pdo {
                
        
        // parameters use PostgreSQL convention, not MySQL
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
        {
                $offsetStr =($offset>=0) ? "$offset," : '';
                // jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
                if ($nrows < 0) $nrows = '18446744073709551615'; 
                
                if ($secs)
-                       $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
+                       $rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
                else
-                       $rs =& $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
+                       $rs = $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
                return $rs;
        }
 }
index c3a016d3852a4b908ad68db31fb9bc35ca7d6bd4..b5f5868a4aa6941d21372fabb270b73d7580fd13 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -32,14 +32,14 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
                }
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
                if ($mask) {
                        $save = $this->metaTablesSQL;
                        $mask = $this->qstr(strtoupper($mask));
                        $this->metaTablesSQL .= " AND table_name like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                if ($mask) {
                        $this->metaTablesSQL = $save;
@@ -47,7 +47,7 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
                return $ret;
        }
        
-       function &MetaColumns($table) 
+       function MetaColumns($table) 
        {
        global $ADODB_FETCH_MODE;
        
index 1215ad8a0684462b0cbe10608d912796b9bc6339..1bf137f8c3bb4567d573b5e71884e5967e2b963b 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -69,19 +69,19 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
                return $arr;
        }
        
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
        {
                 $offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
                 $limitStr  = ($nrows >= 0)  ? " LIMIT $nrows" : '';
                 if ($secs2cache)
-                       $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
                 else
-                       $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
                
                return $rs;
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
                $info = $this->ServerInfo();
                if ($info['version'] >= 7.3) {
@@ -104,7 +104,7 @@ select tablename,'T' from pg_tables where tablename like $mask
  union 
 select viewname,'V' from pg_views where viewname like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                if ($mask) {
                        $this->metaTablesSQL = $save;
@@ -112,7 +112,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                return $ret;
        }
        
-       function &MetaColumns($table,$normalize=true) 
+       function MetaColumns($table,$normalize=true) 
        {
        global $ADODB_FETCH_MODE;
        
@@ -125,8 +125,8 @@ select viewname,'V' from pg_views where viewname like $mask";
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
                
-               if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
-               else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+               if ($schema) $rs = $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
+               else $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
                if (isset($savem)) $this->SetFetchMode($savem);
                $ADODB_FETCH_MODE = $save;
                
@@ -144,7 +144,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                        
                        $rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
                        // fetch all result in once for performance.
-                       $keys =& $rskey->GetArray();
+                       $keys = $rskey->GetArray();
                        if (isset($savem)) $this->SetFetchMode($savem);
                        $ADODB_FETCH_MODE = $save;
                        
index c3a30631e4b8f49861dbf4f7fc7fbc93437dedf5..916ad98eca34ec12436117d5c324214b46d539e6 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 8b2dea2e2c88d3eda5a44c78501a1afdd4a97080..c0e8c76efadbf012ce2e30c409e8493def60439a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -201,7 +201,7 @@ a different OID if a database must be reloaded. */
                return @pg_Exec($this->_connectionID, "rollback");
        }
        
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+       function MetaTables($ttype=false,$showSchema=false,$mask=false) 
        {
                $info = $this->ServerInfo();
                if ($info['version'] >= 7.3) {
@@ -224,7 +224,7 @@ select tablename,'T' from pg_tables where tablename like $mask
  union 
 select viewname,'V' from pg_views where viewname like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
                
                if ($mask) {
                        $this->metaTablesSQL = $save;
@@ -464,7 +464,7 @@ select viewname,'V' from pg_views where viewname like $mask";
        // for schema support, pass in the $table param "$schema.$tabname".
        // converts field names to lowercase, $upper is ignored
        // see http://phplens.com/lens/lensforum/msgs.php?id=14018 for more info
-       function &MetaColumns($table,$normalize=true) 
+       function MetaColumns($table,$normalize=true) 
        {
        global $ADODB_FETCH_MODE;
        
@@ -478,8 +478,8 @@ select viewname,'V' from pg_views where viewname like $mask";
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
                
-               if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
-               else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+               if ($schema) $rs = $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
+               else $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
                if (isset($savem)) $this->SetFetchMode($savem);
                $ADODB_FETCH_MODE = $save;
                
@@ -496,7 +496,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                        
                        $rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
                        // fetch all result in once for performance.
-                       $keys =& $rskey->GetArray();
+                       $keys = $rskey->GetArray();
                        if (isset($savem)) $this->SetFetchMode($savem);
                        $ADODB_FETCH_MODE = $save;
                        
@@ -578,7 +578,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                
        }
 
-         function &MetaIndexes ($table, $primary = FALSE)
+         function MetaIndexes ($table, $primary = FALSE)
       {
          global $ADODB_FETCH_MODE;
                 
@@ -886,10 +886,10 @@ class ADORecordSet_postgres64 extends ADORecordSet{
                $this->ADORecordSet($queryID);
        }
        
-       function &GetRowAssoc($upper=true)
+       function GetRowAssoc($upper=true)
        {
                if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
-               $row =& ADORecordSet::GetRowAssoc($upper);
+               $row = ADORecordSet::GetRowAssoc($upper);
                return $row;
        }
 
@@ -925,7 +925,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
                 return $this->fields[$this->bind[strtoupper($colname)]];
        }
 
-       function &FetchField($off = 0) 
+       function FetchField($off = 0) 
        {
                // offsets begin at 0
                
index b5c64dcb12636ceef7eef440015904d6c326e035..ded804ec5093001a8292c9cb9042174b7b88360a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -34,14 +34,14 @@ class ADODB_postgres7 extends ADODB_postgres64 {
        
        // the following should be compat with postgresql 7.2, 
        // which makes obsolete the LIMIT limit,offset syntax
-        function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
+        function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
         {
                 $offsetStr = ($offset >= 0) ? " OFFSET ".((integer)$offset) : '';
                 $limitStr  = ($nrows >= 0)  ? " LIMIT ".((integer)$nrows) : '';
                 if ($secs2cache)
-                       $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
                 else
-                       $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
                
                return $rs;
         }
@@ -72,11 +72,11 @@ class ADODB_postgres7 extends ADODB_postgres64 {
                ORDER BY
                        t.tgrelid';
                
-               $rs =& $this->Execute($sql);
+               $rs = $this->Execute($sql);
                
                if (!$rs || $rs->EOF) return false;
                
-               $arr =& $rs->GetArray();
+               $arr = $rs->GetArray();
                $a = array();
                foreach($arr as $v) {
                        $data = explode(chr(0), $v['args']);
index 7ab0be770f899c9e75286180b55a5fa0ee47fdeb..08267ecc9d85d0061a1eeb9895f77d6e9f0af69b 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 1eb74f793cfe319353836fe1c8f7c7c377fd0b65..581d83fc49bebf1f9fdf801ed1b2fffcd0c240d1 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
index 3ee9f10044c00bb9113258c5e4991384bce13944..41ad9cc42d837c8e4ed1ef36f2d8ad2f4262bcc1 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -53,7 +53,7 @@ class ADODB_SAPDB extends ADODB_odbc {
                return $this->GetCol("SELECT columnname FROM COLUMNS WHERE tablename=$table AND mode='KEY' ORDER BY pos");
        }
                
-       function &MetaIndexes ($table, $primary = FALSE)
+       function MetaIndexes ($table, $primary = FALSE)
        {
                $table = $this->Quote(strtoupper($table));
 
@@ -92,7 +92,7 @@ class ADODB_SAPDB extends ADODB_odbc {
         return $indexes;
        }
        
-       function &MetaColumns ($table)
+       function MetaColumns ($table)
        {
                global $ADODB_FETCH_MODE;
                $save = $ADODB_FETCH_MODE;
index c842a765259827055719edc8600ff48bba0462d3..dbb6e98db6bb199d00946ea9b477eb0b19da281e 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-version V4.98 13 Feb 2008 (c) 2000-2008  John Lim (jlim#natsoft.com.my).  All rights
+version V5.04a 25 Mar 2008  (c) 2000-2008  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, 
index b9c45c2e2a08201965c0727c6cda82ad936a6f24..845b92f535115be331c14f5fb68617c7669002a5 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -78,7 +78,7 @@ class ADODB_sqlite extends ADOConnection {
        }
        
        // mark newnham
-       function &MetaColumns($tab)
+       function MetaColumns($tab)
        {
          global $ADODB_FETCH_MODE;
          $false = false;
@@ -190,14 +190,14 @@ class ADODB_sqlite extends ADOConnection {
                return $rez;
        }
        
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
        {
                $offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
                $limitStr  = ($nrows >= 0)  ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : '');
                if ($secs2cache)
-                       $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
                else
-                       $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+                       $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
                        
                return $rs;
        }
@@ -261,7 +261,7 @@ class ADODB_sqlite extends ADOConnection {
                return @sqlite_close($this->_connectionID);
        }
 
-       function &MetaIndexes($table, $primary = FALSE, $owner=false)
+       function MetaIndexes($table, $primary = FALSE, $owner=false)
        {
                $false = false;
                // save old fetch mode
@@ -350,7 +350,7 @@ class ADORecordset_sqlite extends ADORecordSet {
        }
 
 
-       function &FetchField($fieldOffset = -1)
+       function FetchField($fieldOffset = -1)
        {
                $fld = new ADOFieldObject;
                $fld->name = sqlite_field_name($this->_queryID, $fieldOffset);
index 58e071d7f8695dde28d441e7d2c7c6e01909313c..2555eeae19580e7ed54c4a604cef2370e3add923 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
index ef6df6be6dc6232dd26f79636dcc984bb6748224..d8ba4009537974291825c967c2086a4064f7814f 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim. All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim. 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. 
@@ -151,10 +151,10 @@ class ADODB_sybase extends ADOConnection {
        }
        
        // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
-       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
+       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 
        {
                if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
-                       $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+                       $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
                        return $rs;
                }
                
@@ -165,7 +165,7 @@ class ADODB_sybase extends ADOConnection {
                if ($offset > 0 && $cnt) $cnt += $offset;
                
                $this->Execute("set rowcount $cnt"); 
-               $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0);
+               $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0);
                $this->Execute("set rowcount 0");
                
                return $rs;
@@ -300,7 +300,7 @@ class ADORecordset_sybase extends ADORecordSet {
                Get column information in the Recordset object. fetchField() can be used in order to obtain information about
                fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
                fetchField() is retrieved.      */
-       function &FetchField($fieldOffset = -1) 
+       function FetchField($fieldOffset = -1) 
        {
                if ($fieldOffset != -1) {
                        $o = @sybase_fetch_field($this->_queryID, $fieldOffset);
index 95cb2d249509046854b65c6315a32fa9cc1ea57f..5360c2a46c32a907d09b3d322cf199c99567cb04 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+  V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -25,7 +25,7 @@ class ADODB_sybase_ase extends ADODB_sybase {
        }
        
        // split the Views, Tables and procedures.
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+       function MetaTables($ttype=false,$showSchema=false,$mask=false)
        {
                $false = false;
                if ($this->metaTablesSQL) {
@@ -43,7 +43,7 @@ class ADODB_sybase_ase extends ADODB_sybase {
                        if ($rs === false || !method_exists($rs, 'GetArray')){
                                        return $false;
                        }
-                       $arr =& $rs->GetArray();
+                       $arr = $rs->GetArray();
 
                        $arr2 = array();
                        foreach($arr as $key=>$value){
@@ -71,7 +71,7 @@ class ADODB_sybase_ase extends ADODB_sybase {
        }
 
        // fix a bug which prevent the metaColumns query to be executed for Sybase ASE
-       function &MetaColumns($table,$upper=false) 
+       function MetaColumns($table,$upper=false) 
        {
                $false = false;
                if (!empty($this->metaColumnsSQL)) {
@@ -81,7 +81,7 @@ class ADODB_sybase_ase extends ADODB_sybase {
 
                        $retarr = array();
                        while (!$rs->EOF) {
-                               $fld =& new ADOFieldObject();
+                               $fld = new ADOFieldObject();
                                $fld->name = $rs->Fields('field_name');
                                $fld->type = $rs->Fields('type');
                                $fld->max_length = $rs->Fields('width');
index 92cbb661dd24c0a1ab908180fb17f0cf78d0cc9e..3b13aef61d80306a9f0261c54d82990484e54ba3 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. 
@@ -55,7 +55,7 @@ class ADODB_vfp extends ADODB_odbc {
 
        
        // TOP requires ORDER BY for VFP
-       function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+       function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                $this->hasTop = preg_match('/ORDER[ \t\r\n]+BY/is',$sql) ? 'top' : false;
                $ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
index ea6d3b4c9343cfe4c4188011b21d26cc9ec84d74..7b0479b556a957579a91c0590ed31b1254bf34e8 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -58,7 +58,7 @@ class perf_db2 extends adodb_perf{
 
        function perf_db2(&$conn)
        {
-               $this->conn =& $conn;
+               $this->conn = $conn;
        }
        
        function Explain($sql,$partial=false)
index aa8bad65864a1687e265debde4b20aef08894eb2..504533cb4fdfac716bc6954185461a9266caac22 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -63,7 +63,7 @@ class perf_informix extends adodb_perf{
        
        function perf_informix(&$conn)
        {
-               $this->conn =& $conn;
+               $this->conn = $conn;
        }
 
 }
index c7d6c9155463701f169f62c1f29261b03858e4f4..6dd12c74807a0aaa3f6cb17955054d681165681e 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -71,7 +71,7 @@ class perf_mssql extends adodb_perf{
                        $this->sql1 = 'sql1';
                        //$this->explain = false;
                }
-               $this->conn =& $conn;
+               $this->conn = $conn;
        }
        
        function Explain($sql,$partial=false)
@@ -96,7 +96,7 @@ class perf_mssql extends adodb_perf{
                
                $save = $ADODB_FETCH_MODE;
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-               $rs =& $this->conn->Execute($sql);
+               $rs = $this->conn->Execute($sql);
                //adodb_printr($rs);
                $ADODB_FETCH_MODE = $save;
                if ($rs) {
index 001802bdb1edfffa03a62c7cbdf03d4f66422692..9f35e1cf76ceb7c51cc1764e6cf3eb4e9271f9ed 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -83,7 +83,7 @@ class perf_mysql extends adodb_perf{
        
        function perf_mysql(&$conn)
        {
-               $this->conn =& $conn;
+               $this->conn = $conn;
        }
        
        function Explain($sql,$partial=false)
index b3869378a20948d2ec60ca9599bdac1c17aceca8..751280516fcaa017676fdcb288786c140ccc5825 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -109,7 +109,7 @@ AND    b.name = 'sorts (memory)'",
                        where name = 'free memory' and pool = 'shared pool'",
                'Percentage of data cache actually in use - should be over 85%'),
                
-                               'shared pool utilization ratio' => array('RATIOU', 
+               'shared pool utilization ratio' => array('RATIOU', 
                'select round((sga.bytes/case when p.value=0 then sga.bytes else to_number(p.value) end)*100,2)
                from v$sgastat sga, v$parameter p
                where sga.name = \'free memory\' and sga.pool = \'shared pool\'
@@ -156,7 +156,7 @@ having count(*) > 100)",'These are sql statements that should be using bind vari
                'random page cost' => array('COST',
                        "select value from v\$parameter where name = 'optimizer_index_cost_adj'",
                        '=WarnPageCost'),
-       
+               
        'Backup',
                'Achivelog Mode' => array('BACKUP', 'select log_mode from v$database', 'To turn on archivelog:<br>
        <pre>
@@ -185,7 +185,7 @@ FROM v\$parameter v1, v\$parameter v2 WHERE v1.name='log_archive_dest' AND v2.na
                $savelog = $conn->LogSQL(false);        
                $this->version = $conn->ServerInfo();
                $conn->LogSQL($savelog);        
-               $this->conn =& $conn;
+               $this->conn = $conn;
        }
        
        function WarnPageCost($val)
@@ -229,7 +229,7 @@ FROM v\$parameter v1, v\$parameter v2 WHERE v1.name='log_archive_dest' AND v2.na
        function Explain($sql,$partial=false) 
        {
                $savelog = $this->conn->LogSQL(false);
-               $rs =& $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
+               $rs = $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
                if (!$rs) {
                        echo "<p><b>Missing PLAN_TABLE</b></p>
 <pre>
@@ -282,7 +282,7 @@ CREATE TABLE PLAN_TABLE (
                $this->conn->BeginTrans();
                $id = "ADODB ".microtime();
 
-               $rs =& $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
+               $rs = $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
                $m = $this->conn->ErrorMsg();
                if ($m) {
                        $this->conn->RollbackTrans();
@@ -290,7 +290,7 @@ CREATE TABLE PLAN_TABLE (
                        $s .= "<p>$m</p>";
                        return $s;
                }
-               $rs =& $this->conn->Execute("
+               $rs = $this->conn->Execute("
                select 
   '<pre>'||lpad('--', (level-1)*2,'-') || trim(operation) || ' ' || trim(options)||'</pre>'  as Operation, 
   object_name,COST,CARDINALITY,bytes
@@ -310,7 +310,7 @@ CONNECT BY prior id=parent_id and statement_id='$id'");
        {
                if ($this->version['version'] < 9) return 'Oracle 9i or later required';
                
-                $rs =& $this->conn->Execute("
+                $rs = $this->conn->Execute("
 select  a.size_for_estimate as cache_mb_estimate,
        case when a.size_factor=1 then 
                '&lt;&lt;= current'
@@ -438,7 +438,7 @@ order by
                if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
                
                $savelog = $this->conn->LogSQL(false);
-               $rs =& $this->conn->SelectLimit($sql);
+               $rs = $this->conn->SelectLimit($sql);
                $this->conn->LogSQL($savelog);
                
                if (isset($savem)) $this->conn->SetFetchMode($savem);
@@ -509,7 +509,7 @@ order by
                if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
                
                $savelog = $this->conn->LogSQL(false);
-               $rs =& $this->conn->Execute($sql);
+               $rs = $this->conn->Execute($sql);
                $this->conn->LogSQL($savelog);
                
                if (isset($savem)) $this->conn->SetFetchMode($savem);
@@ -525,7 +525,6 @@ order by
        
        function clearsql() 
        {
-       $this->conn->debug=1;
                $perf_table = adodb_perf::table();
        // using the naive "delete from $perf_table where created<".$this->conn->sysTimeStamp will cause the table to lock, possibly
        // for a long time
@@ -546,5 +545,6 @@ END;";
 
                $ok = $this->conn->Execute($sql);
        }
+       
 }
 ?>
\ No newline at end of file
index 2f351da1c1c4d21fe99d8544f9949bdb49b22809..87436443fdc2d008a444f39e43828176eb92d1aa 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /* 
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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. See License.txt. 
@@ -89,7 +89,7 @@ class perf_postgres extends adodb_perf{
        
        function perf_postgres(&$conn)
        {
-               $this->conn =& $conn;
+               $this->conn = $conn;
        }
        
        var $optimizeTableLow  = 'VACUUM %s'; 
@@ -121,8 +121,6 @@ class perf_postgres extends adodb_perf{
            return $conn->Execute($sql) !== false;  
        }
        
-
-       
        function Explain($sql,$partial=false)
        {
                $save = $this->conn->LogSQL(false);
index fb50375d300ef138c3f1b3d79bab0e35463e5268..df243db77044eba7616d3aa052a6182e711abc67 100644 (file)
@@ -1,4 +1,4 @@
-Description of ADODB v4.98 library import into Moodle
+Description of ADODB V5.04a library import into Moodle
 
 Removed:
  * contrib/
index cf705c90738d1f04bee33bb119714a7a1e76a94e..7033a806f5e56e5b8bae04c7f63148bf1dc8b6a1 100644 (file)
        }
        $rs = RSFilter($rs,'do_ucwords');
  */
-function &RSFilter($rs,$fn)
+function RSFilter($rs,$fn)
 {
        if ($rs->databaseType != 'array') {
                if (!$rs->connection) return false;
                
-               $rs = &$rs->connection->_rs2rs($rs);
+               $rs = $rs->connection->_rs2rs($rs);
        }
        $rows = $rs->RecordCount();
        for ($i=0; $i < $rows; $i++) {
index c58428b4ff033603f151a577734d9a01e355bb5c..a820102d2e3788a068e8816216172a3254b7598f 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index de0ad8b697d3585b1aa50fec22cae173caf27741..5bb4e16d377dd4095737df75f6dcbc81befb88e3 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index 600e89e51887bc55b37a30b9e2240a8870dca6a1..b9cde1fbd7a1ebd828e707ddcf2607c36975de80 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index 92961ef715b8b91005ad01e9a8f7ff9bb5bcba75..07e2943150d8779df4e2f798d2b9cc04829398f4 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index 63f7dbc625ec8bf6938b92efa028c93c8f5ceb18..ea57ef4a2b97bd55b16267b3bc3fb675fe767618 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index 4044079b211cc8f9168f53be3fdcc864bc077153..04a74781c588e5984e126edc3372a5267d0e5459 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
@@ -21,14 +21,14 @@ class ADODB_Encrypt_MD5 {
        /**
         */
        function write($data, $key) {
-               $md5crypt =& new MD5Crypt();
+               $md5crypt = new MD5Crypt();
                return $md5crypt->encrypt($data, $key);
        }
 
        /**
         */
        function read($data, $key) {
-               $md5crypt =& new MD5Crypt();
+               $md5crypt = new MD5Crypt();
                return $md5crypt->decrypt($data, $key);
        }
 
index 5446b5764080b0024202912fcdd796ac73798aac..b3b89cad2a859e62846d8cce2ffbcd058ae081ea 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index c876002bbee87dda9c45243538594a35540ea207..16f603e339b77cfae4d6c7671255867b96d23e85 100644 (file)
@@ -1,32 +1,32 @@
-<?php
-if (!defined('ADODB_SESSION')) die();
-
-include_once ADODB_SESSION . '/crypt.inc.php';
-
-
-/**
-
- */
-
-class ADODB_Encrypt_SHA1 {
-
-       function write($data, $key) 
-       {
-               $sha1crypt =& new SHA1Crypt();
-               return $sha1crypt->encrypt($data, $key);
-
-       }
-
-
-       function read($data, $key) 
-       {
-               $sha1crypt =& new SHA1Crypt();
-               return $sha1crypt->decrypt($data, $key);
-
-       }
-}
-
-
-
-return 1;
+<?php\r
+if (!defined('ADODB_SESSION')) die();\r
+\r
+include_once ADODB_SESSION . '/crypt.inc.php';\r
+\r
+\r
+/**\r
+\r
+ */\r
+\r
+class ADODB_Encrypt_SHA1 {\r
+\r
+       function write($data, $key) \r
+       {\r
+               $sha1crypt = new SHA1Crypt();\r
+               return $sha1crypt->encrypt($data, $key);\r
+\r
+       }\r
+\r
+\r
+       function read($data, $key) \r
+       {\r
+               $sha1crypt = new SHA1Crypt();\r
+               return $sha1crypt->decrypt($data, $key);\r
+\r
+       }\r
+}\r
+\r
+\r
+\r
+return 1;\r
 ?>
\ No newline at end of file
index 8abd32faeac685d7dcab18602b1881021166d4fb..603e3d15e5aad08b73048f35cea7c6245332f7e2 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index 1c4efd17b1401c1bc2c8cf6bb89e3cb476fced53..c9f39afae546af56f4738f55e921193ccf379220 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
index 5f6d33f90b171efde5a5aebb9acb830e4e733942..94ebf996002afe0a839a26ec2a4e25629e10a5bd 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
@@ -59,7 +59,7 @@ function adodb_unserialize( $serialized_string )
 */
 function adodb_session_regenerate_id() 
 {
-       $conn =& ADODB_Session::_conn();
+       $conn = ADODB_Session::_conn();
        if (!$conn) return false;
 
        $old_id = session_id();
@@ -72,7 +72,7 @@ function adodb_session_regenerate_id()
                //@session_start();
        }
        $new_id = session_id();
-       $ok =& $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
+       $ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
        
        /* it is possible that the update statement fails due to a collision */
        if (!$ok) {
@@ -95,7 +95,7 @@ function adodb_session_create_table($schemaFile=null,$conn = null)
 {
     // set default values
     if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema.xml';
-    if ($conn===null) $conn =& ADODB_Session::_conn();
+    if ($conn===null) $conn = ADODB_Session::_conn();
 
        if (!$conn) return 0;
 
@@ -421,7 +421,7 @@ class ADODB_Session {
 
        /*!
        */
-       function &_conn($conn=null) {
+       function _conn($conn=null) {
                return $GLOBALS['ADODB_SESS_CONN'];
        }
 
@@ -463,7 +463,7 @@ class ADODB_Session {
        /*!
        */
        function _dumprs($rs) {
-               $conn   =& ADODB_Session::_conn();
+               $conn   = ADODB_Session::_conn();
                $debug  = ADODB_Session::debug();
 
                if (!$conn) {
@@ -515,7 +515,7 @@ class ADODB_Session {
        */
        function open($save_path, $session_name, $persist = null) 
        {
-               $conn =& ADODB_Session::_conn();
+               $conn = ADODB_Session::_conn();
 
                if ($conn) {
                        return true;
@@ -539,7 +539,7 @@ class ADODB_Session {
 #              assert('$driver');
 #              assert('$host');
 
-               $conn =& ADONewConnection($driver);
+               $conn = ADONewConnection($driver);
 
                if ($debug) {
                        $conn->debug = true;
@@ -557,7 +557,7 @@ class ADODB_Session {
                        $ok = $conn->Connect($host, $user, $password, $database);
                }
 
-               if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
+               if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn;
                else
                        ADOConnection::outp('<p>Session: connection failed</p>', false);
                
@@ -571,7 +571,7 @@ class ADODB_Session {
        function close() 
        {
 /*
-               $conn =& ADODB_Session::_conn();
+               $conn = ADODB_Session::_conn();
                if ($conn) $conn->Close();
 */
                return true;
@@ -582,7 +582,7 @@ class ADODB_Session {
        */
        function read($key) 
        {
-               $conn   =& ADODB_Session::_conn();
+               $conn   = ADODB_Session::_conn();
                $data   = ADODB_Session::dataFieldName();
                $filter = ADODB_Session::filter();
                $table  = ADODB_Session::table();
@@ -601,10 +601,10 @@ class ADODB_Session {
                  developer has commited elsewhere... :(
                 */
                #if (ADODB_Session::Lock())
-               #       $rs =& $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), $data);
+               #       $rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), $data);
                #else
                
-                       $rs =& $conn->Execute($sql);
+                       $rs = $conn->Execute($sql);
                //ADODB_Session::_dumprs($rs);
                if ($rs) {
                        if ($rs->EOF) {
@@ -641,7 +641,7 @@ class ADODB_Session {
                if (!empty($ADODB_SESSION_READONLY)) return;
                
                $clob                   = ADODB_Session::clob();
-               $conn                   =& ADODB_Session::_conn();
+               $conn                   = ADODB_Session::_conn();
                $crc                    = ADODB_Session::_crc();
                $data                   = ADODB_Session::dataFieldName();
                $debug                  = ADODB_Session::debug();
@@ -680,7 +680,7 @@ class ADODB_Session {
                        
                        
                        $sql = "UPDATE $table SET expiry = ".$conn->Param('0').",expireref=".$conn->Param('1')." WHERE $binary sesskey = ".$conn->Param('2')." AND expiry >= ".$conn->Param('3');
-                       $rs =& $conn->Execute($sql,array($expiry,$expirevar,$key,time()));
+                       $rs = $conn->Execute($sql,array($expiry,$expirevar,$key,time()));
                        return true;
                }
                $val = rawurlencode($val);
@@ -723,7 +723,7 @@ class ADODB_Session {
                        $conn->StartTrans();
                        $expiryref = $conn->qstr($arr['expireref']);
                        // do we insert or update? => as for sesskey
-                       $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = $qkey");
+                       $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = $qkey");
                        if ($rs && reset($rs->fields) > 0) {
                                $sql = "UPDATE $table SET expiry = $expiry, $data = $lob_value, expireref=$expiryref WHERE  sesskey = $qkey";
                        } else {
@@ -733,10 +733,10 @@ class ADODB_Session {
                        
 
                        $err = '';
-                       $rs1 =& $conn->Execute($sql);
+                       $rs1 = $conn->Execute($sql);
                        if (!$rs1) $err = $conn->ErrorMsg()."\n";
                        
-                       $rs2 =& $conn->UpdateBlob($table, $data, $val, " sesskey=$qkey", strtoupper($clob));
+                       $rs2 = $conn->UpdateBlob($table, $data, $val, " sesskey=$qkey", strtoupper($clob));
                        if (!$rs2) $err .= $conn->ErrorMsg()."\n";
                        
                        $rs = ($rs && $rs2) ? true : false;
@@ -751,7 +751,7 @@ class ADODB_Session {
                        // properly unless select statement executed in Win2000
                        if ($conn->databaseType == 'access') {
                                $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
-                               $rs =& $conn->Execute($sql);
+                               $rs = $conn->Execute($sql);
                                ADODB_Session::_dumprs($rs);
                                if ($rs) {
                                        $rs->Close();
@@ -767,7 +767,7 @@ class ADODB_Session {
        /*!
        */
        function destroy($key) {
-               $conn                   =& ADODB_Session::_conn();
+               $conn                   = ADODB_Session::_conn();
                $table                  = ADODB_Session::table();
                $expire_notify  = ADODB_Session::expireNotify();
 
@@ -785,7 +785,7 @@ class ADODB_Session {
                        $fn = next($expire_notify);
                        $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
                        $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
-                       $rs =& $conn->Execute($sql);
+                       $rs = $conn->Execute($sql);
                        ADODB_Session::_dumprs($rs);
                        $conn->SetFetchMode($savem);
                        if (!$rs) {
@@ -802,7 +802,7 @@ class ADODB_Session {
                }
 
                $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
-               $rs =& $conn->Execute($sql);
+               $rs = $conn->Execute($sql);
                ADODB_Session::_dumprs($rs);
 
                return $rs ? true : false;
@@ -812,7 +812,7 @@ class ADODB_Session {
        */
        function gc($maxlifetime) 
        {
-               $conn                   =& ADODB_Session::_conn();
+               $conn                   = ADODB_Session::_conn();
                $debug                  = ADODB_Session::debug();
                $expire_notify  = ADODB_Session::expireNotify();
                $optimize               = ADODB_Session::optimize();
@@ -832,7 +832,7 @@ class ADODB_Session {
                        $fn = next($expire_notify);
                        $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
                        $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time";
-                       $rs =& $conn->Execute($sql);
+                       $rs = $conn->Execute($sql);
                        ADODB_Session::_dumprs($rs);
                        $conn->SetFetchMode($savem);
                        if ($rs) {
@@ -853,14 +853,14 @@ class ADODB_Session {
                
                        if (1) {
                                $sql = "SELECT sesskey FROM $table WHERE expiry < $time";
-                               $arr =& $conn->GetAll($sql);
+                               $arr = $conn->GetAll($sql);
                                foreach ($arr as $row) {
                                        $sql2 = "DELETE FROM $table WHERE sesskey=".$conn->Param('0');
                                        $conn->Execute($sql2,array($row[0]));
                                }
                        } else {
                                $sql = "DELETE FROM $table WHERE expiry < $time";
-                               $rs =& $conn->Execute($sql);
+                               $rs = $conn->Execute($sql);
                                ADODB_Session::_dumprs($rs);
                                if ($rs) $rs->Close();
                        }
@@ -893,7 +893,7 @@ class ADODB_Session {
                        }
                        $sql .= " FROM $table";
 
-                       $rs =& $conn->SelectLimit($sql, 1);
+                       $rs = $conn->SelectLimit($sql, 1);
                        if ($rs && !$rs->EOF) {
                                $dbts = reset($rs->fields);
                                $rs->Close();
index f765891138e84f5dd4dbc633ab982537babbf41d..e853933e9824255ab09fe2fc3f2205029cd8c6ac 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.02 24 Sept 2007   (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
          Contributed by Ross Smith (adodb@netebb.com). 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
@@ -89,7 +89,7 @@ function adodb_unserialize( $serialized_string )
 */
 function adodb_session_regenerate_id() 
 {
-       $conn =& ADODB_Session::_conn();
+       $conn = ADODB_Session::_conn();
        if (!$conn) return false;
 
        $old_id = session_id();
@@ -102,7 +102,7 @@ function adodb_session_regenerate_id()
                //@session_start();
        }
        $new_id = session_id();
-       $ok =& $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
+       $ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
        
        /* it is possible that the update statement fails due to a collision */
        if (!$ok) {
@@ -125,7 +125,7 @@ function adodb_session_create_table($schemaFile=null,$conn = null)
 {
     // set default values
     if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema2.xml';
-    if ($conn===null) $conn =& ADODB_Session::_conn();
+    if ($conn===null) $conn = ADODB_Session::_conn();
 
        if (!$conn) return 0;
 
@@ -154,7 +154,7 @@ class ADODB_Session {
        */
        /*!
        */
-       function driver($driver = null) 
+       static function driver($driver = null) 
        {
                static $_driver = 'mysql';
                static $set = false;
@@ -174,7 +174,7 @@ class ADODB_Session {
 
        /*!
        */
-       function host($host = null) {
+       static function host($host = null) {
                static $_host = 'localhost';
                static $set = false;
 
@@ -193,7 +193,7 @@ class ADODB_Session {
 
        /*!
        */
-       function user($user = null) 
+       static function user($user = null) 
        {
                static $_user = 'root';
                static $set = false;
@@ -213,7 +213,7 @@ class ADODB_Session {
 
        /*!
        */
-       function password($password = null) 
+       static function password($password = null) 
        {
                static $_password = '';
                static $set = false;
@@ -233,7 +233,7 @@ class ADODB_Session {
 
        /*!
        */
-       function database($database = null) 
+       static function database($database = null) 
        {
                static $_database = '';
                static $set = false;
@@ -252,7 +252,7 @@ class ADODB_Session {
 
        /*!
        */
-       function persist($persist = null) 
+       static function persist($persist = null) 
        {
                static $_persist = true;
 
@@ -265,7 +265,7 @@ class ADODB_Session {
 
        /*!
        */
-       function lifetime($lifetime = null) 
+       static function lifetime($lifetime = null) 
        {
                static $_lifetime;
                static $set = false;
@@ -293,7 +293,7 @@ class ADODB_Session {
 
        /*!
        */
-       function debug($debug = null) 
+       static function debug($debug = null) 
        {
                static $_debug = false;
                static $set = false;
@@ -303,7 +303,7 @@ class ADODB_Session {
 
                        $conn = ADODB_Session::_conn();
                        if ($conn) {
-                               $conn->debug = $_debug;
+                               #$conn->debug = $_debug;
                        }
                        $set = true;
                } elseif (!$set) {
@@ -318,7 +318,7 @@ class ADODB_Session {
 
        /*!
        */
-       function expireNotify($expire_notify = null) 
+       static function expireNotify($expire_notify = null) 
        {
                static $_expire_notify;
                static $set = false;
@@ -338,7 +338,7 @@ class ADODB_Session {
 
        /*!
        */
-       function table($table = null) 
+       static function table($table = null) 
        {
                static $_table = 'sessions2';
                static $set = false;
@@ -358,7 +358,7 @@ class ADODB_Session {
 
        /*!
        */
-       function optimize($optimize = null) 
+       static function optimize($optimize = null) 
        {
                static $_optimize = false;
                static $set = false;
@@ -378,7 +378,7 @@ class ADODB_Session {
 
        /*!
        */
-       function syncSeconds($sync_seconds = null) {
+       static function syncSeconds($sync_seconds = null) {
                //echo ("<p>WARNING: ADODB_SESSION::syncSeconds is longer used, please remove this function for your code</p>");
                
                return 0;
@@ -386,7 +386,7 @@ class ADODB_Session {
 
        /*!
        */
-       function clob($clob = null) {
+       static function clob($clob = null) {
                static $_clob = false;
                static $set = false;
 
@@ -405,14 +405,14 @@ class ADODB_Session {
 
        /*!
        */
-       function dataFieldName($data_field_name = null) {
+       static function dataFieldName($data_field_name = null) {
                //echo ("<p>WARNING: ADODB_SESSION::dataFieldName() is longer used, please remove this function for your code</p>");
                return '';
        }
 
        /*!
        */
-       function filter($filter = null) {
+       static function filter($filter = null) {
                static $_filter = array();
 
                if (!is_null($filter)) {
@@ -427,7 +427,7 @@ class ADODB_Session {
 
        /*!
        */
-       function encryptionKey($encryption_key = null) {
+       static function encryptionKey($encryption_key = null) {
                static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
 
                if (!is_null($encryption_key)) {
@@ -443,19 +443,13 @@ class ADODB_Session {
 
        /*!
        */
-       function &_conn($conn=null) 
-       {
-               if (isset($GLOBALS['ADODB_SESS_CONN'])) {
-                       $conn =& $GLOBALS['ADODB_SESS_CONN'];
-                       return $conn;
-               }
-               $false = false;
-               return $false;
+       static function _conn($conn=null) {
+               return @$GLOBALS['ADODB_SESS_CONN'];
        }
 
        /*!
        */
-       function _crc($crc = null) {
+       static function _crc($crc = null) {
                static $_crc = false;
 
                if (!is_null($crc)) {
@@ -467,7 +461,7 @@ class ADODB_Session {
 
        /*!
        */
-       function _init() {
+       static function _init() {
                session_module_name('user');
                session_set_save_handler(
                        array('ADODB_Session', 'open'),
@@ -482,7 +476,7 @@ class ADODB_Session {
 
        /*!
        */
-       function _sessionKey() {
+       static function _sessionKey() {
                // use this function to create the encryption key for crypted sessions
                // crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt
                return crypt(ADODB_Session::encryptionKey(), session_id());
@@ -490,8 +484,8 @@ class ADODB_Session {
 
        /*!
        */
-       function _dumprs($rs) {
-               $conn   =& ADODB_Session::_conn();
+       static function _dumprs($rs) {
+               $conn   = ADODB_Session::_conn();
                $debug  = ADODB_Session::debug();
 
                if (!$conn) {
@@ -521,7 +515,7 @@ class ADODB_Session {
        // public methods
        /////////////////////
        
-       function config($driver, $host, $user, $password, $database=false,$options=false)
+       static function config($driver, $host, $user, $password, $database=false,$options=false)
        {
                ADODB_Session::driver($driver);
                ADODB_Session::host($host);
@@ -541,9 +535,9 @@ class ADODB_Session {
 
                If $conn already exists, reuse that connection
        */
-       function open($save_path, $session_name, $persist = null) 
+       static function open($save_path, $session_name, $persist = null) 
        {
-               $conn =& ADODB_Session::_conn();
+               $conn = ADODB_Session::_conn();
 
                if ($conn) {
                        return true;
@@ -567,7 +561,7 @@ class ADODB_Session {
 #              assert('$driver');
 #              assert('$host');
 
-               $conn =& ADONewConnection($driver);
+               $conn = ADONewConnection($driver);
 
                if ($debug) {
                        $conn->debug = true;            
@@ -585,7 +579,7 @@ class ADODB_Session {
                        $ok = $conn->Connect($host, $user, $password, $database);
                }
 
-               if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
+               if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn;
                else
                        ADOConnection::outp('<p>Session: connection failed</p>', false);
                
@@ -596,10 +590,10 @@ class ADODB_Session {
        /*!
                Close the connection
        */
-       function close() 
+       static function close() 
        {
 /*
-               $conn =& ADODB_Session::_conn();
+               $conn = ADODB_Session::_conn();
                if ($conn) $conn->Close();
 */
                return true;
@@ -608,9 +602,9 @@ class ADODB_Session {
        /*
                Slurp in the session variables and return the serialized string
        */
-       function read($key) 
+       static function read($key) 
        {
-               $conn   =& ADODB_Session::_conn();
+               $conn   = ADODB_Session::_conn();
                $filter = ADODB_Session::filter();
                $table  = ADODB_Session::table();
 
@@ -628,10 +622,10 @@ class ADODB_Session {
                  developer has commited elsewhere... :(
                 */
                #if (ADODB_Session::Lock())
-               #       $rs =& $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata);
+               #       $rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata);
                #else
                
-                       $rs =& $conn->Execute($sql);
+                       $rs = $conn->Execute($sql);
                //ADODB_Session::_dumprs($rs);
                if ($rs) {
                        if ($rs->EOF) {
@@ -661,14 +655,14 @@ class ADODB_Session {
 
                If the data has not been modified since the last read(), we do not write.
        */
-       function write($key, $val) 
+       static function write($key, $oval) 
        {
        global $ADODB_SESSION_READONLY;
        
                if (!empty($ADODB_SESSION_READONLY)) return;
                
                $clob                   = ADODB_Session::clob();
-               $conn                   =& ADODB_Session::_conn();
+               $conn                   = ADODB_Session::_conn();
                $crc                    = ADODB_Session::_crc();
                $debug                  = ADODB_Session::debug();
                $driver                 = ADODB_Session::driver();
@@ -680,7 +674,7 @@ class ADODB_Session {
                if (!$conn) {
                        return false;
                }
-       
+               if ($debug) $conn->debug = 1;
                $sysTimeStamp = $conn->sysTimeStamp;
                
                //assert('$table');
@@ -691,7 +685,7 @@ class ADODB_Session {
 
                // crc32 optimization since adodb 2.1
                // now we only update expiry date, thx to sebastian thom in adodb 2.32
-               if ($crc !== false && $crc == (strlen($val) . crc32($val))) {
+               if ($crc !== false && $crc == (strlen($oval) . crc32($oval))) {
                        if ($debug) {
                                echo '<p>Session: Only updating date - crc32 not changed</p>';
                        }
@@ -707,10 +701,10 @@ class ADODB_Session {
                        
                        
                        $sql = "UPDATE $table SET expiry = $expiry ,expireref=".$conn->Param('0').", modified = $sysTimeStamp WHERE $binary sesskey = ".$conn->Param('1')." AND expiry >= $sysTimeStamp";
-                       $rs =& $conn->Execute($sql,array($expirevar,$key));
+                       $rs = $conn->Execute($sql,array($expirevar,$key));
                        return true;
                }
-               $val = rawurlencode($val);
+               $val = rawurlencode($oval);
                foreach ($filter as $f) {
                        if (is_object($f)) {
                                $val = $f->write($val, ADODB_Session::_sessionKey());
@@ -727,7 +721,7 @@ class ADODB_Session {
                } 
 
                if (!$clob) {   // no lobs, simply use replace()
-                       $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
+                       $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
                        if ($rs) $rs->Close();
                                        
                        if ($rs && reset($rs->fields) > 0) {
@@ -739,7 +733,7 @@ class ADODB_Session {
                        }
                        
        
-                       $rs =& $conn->Execute($sql,array($val,$expireref,$key));
+                       $rs = $conn->Execute($sql,array($val,$expireref,$key));
                        
                } else {
                        // what value shall we insert/update for lob row?
@@ -760,7 +754,7 @@ class ADODB_Session {
                        
                        $conn->StartTrans();
                        
-                       $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
+                       $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
                        if ($rs) $rs->Close();
                                        
                        if ($rs && reset($rs->fields) > 0) {
@@ -771,10 +765,11 @@ class ADODB_Session {
                                        VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)";
                        }
                        
-                       $rs =& $conn->Execute($sql,array($expireref,$key));
+                       $rs = $conn->Execute($sql,array($expireref,$key));
                        
                        $qkey = $conn->qstr($key);
                        $rs2 = $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob));
+                       if ($debug) echo "<hr>",htmlspecialchars($oval), "<hr>";
                        $rs = @$conn->CompleteTrans();
                        
                        
@@ -788,7 +783,7 @@ class ADODB_Session {
                        // properly unless select statement executed in Win2000
                        if ($conn->databaseType == 'access') {
                                $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
-                               $rs =& $conn->Execute($sql);
+                               $rs = $conn->Execute($sql);
                                ADODB_Session::_dumprs($rs);
                                if ($rs) {
                                        $rs->Close();
@@ -803,15 +798,16 @@ class ADODB_Session {
 
        /*!
        */
-       function destroy($key) {
-               $conn                   =& ADODB_Session::_conn();
+       static function destroy($key) {
+               $conn                   = ADODB_Session::_conn();
                $table                  = ADODB_Session::table();
                $expire_notify  = ADODB_Session::expireNotify();
 
                if (!$conn) {
                        return false;
                }
-
+               $debug                  = ADODB_Session::debug();
+               if ($debug) $conn->debug = 1;
                //assert('$table');
 
                $qkey = $conn->quote($key);
@@ -822,7 +818,7 @@ class ADODB_Session {
                        $fn = next($expire_notify);
                        $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
                        $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
-                       $rs =& $conn->Execute($sql);
+                       $rs = $conn->Execute($sql);
                        ADODB_Session::_dumprs($rs);
                        $conn->SetFetchMode($savem);
                        if (!$rs) {
@@ -839,7 +835,7 @@ class ADODB_Session {
                }
 
                $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
-               $rs =& $conn->Execute($sql);
+               $rs = $conn->Execute($sql);
                ADODB_Session::_dumprs($rs);
                if ($rs) {
                        $rs->Close();
@@ -850,9 +846,9 @@ class ADODB_Session {
 
        /*!
        */
-       function gc($maxlifetime) 
+       static function gc($maxlifetime) 
        {
-               $conn                   =& ADODB_Session::_conn();
+               $conn                   = ADODB_Session::_conn();
                $debug                  = ADODB_Session::debug();
                $expire_notify  = ADODB_Session::expireNotify();
                $optimize               = ADODB_Session::optimize();
@@ -862,6 +858,10 @@ class ADODB_Session {
                        return false;
                }
 
+
+               $debug                  = ADODB_Session::debug();
+               if ($debug) $conn->debug = 1;
+               
                //assert('$table');
 
                $time = $conn->sysTimeStamp;
@@ -872,7 +872,7 @@ class ADODB_Session {
                        $fn = next($expire_notify);
                        $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
                        $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time";
-                       $rs =& $conn->Execute($sql);
+                       $rs = $conn->Execute($sql);
                        ADODB_Session::_dumprs($rs);
                        $conn->SetFetchMode($savem);
                        if ($rs) {
@@ -893,14 +893,14 @@ class ADODB_Session {
                
                        if (0) {
                                $sql = "SELECT sesskey FROM $table WHERE expiry < $time";
-                               $arr =& $conn->GetAll($sql);
+                               $arr = $conn->GetAll($sql);
                                foreach ($arr as $row) {
                                        $sql2 = "DELETE FROM $table WHERE sesskey=".$conn->Param('0');
                                        $conn->Execute($sql2,array($row[0]));
                                }
                        } else {
                                $sql = "DELETE FROM $table WHERE expiry < $time";
-                               $rs =& $conn->Execute($sql);
+                               $rs = $conn->Execute($sql);
                                ADODB_Session::_dumprs($rs);
                                if ($rs) $rs->Close();
                        }
index 7c2232dae7174068a8b9b4df21f0859b81607880..8ae983f15d4908d90237aadba966d9c6cfd4c110 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V4.98 13 Feb 2008  (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008   (c) 2000-2008 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.
@@ -281,7 +281,7 @@ function adodb_sess_gc($maxlifetime) {
        if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select  TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
        else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
        
-       $rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
+       $rs = $ADODB_SESS_CONN->SelectLimit($sql,1);
        if ($rs && !$rs->EOF) {
        
                $dbts = reset($rs->fields);
index fd760441d00ccd2a1db88060ac160a7f572baaa5..84e5ae0e0e8a77243cf65d7b78cd0a75d7d16d13 100644 (file)
@@ -405,7 +405,7 @@ function adodb_sess_gc($maxlifetime)
        if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select  TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
        else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
        
-       $rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
+       $rs = $ADODB_SESS_CONN->SelectLimit($sql,1);
        if ($rs && !$rs->EOF) {
        
                $dbts = reset($rs->fields);
index deec3105a0292f573af12b6200f91138f81c1559..a3c141dd04ded43711a28ff704cf2d8da2c81cda 100644 (file)
@@ -112,7 +112,7 @@ if (!defined('ADODB_SESSION')) {
 */
 function adodb_session_regenerate_id() 
 {
-       $conn =& ADODB_Session::_conn();
+       $conn = ADODB_Session::_conn();
        if (!$conn) return false;
 
        $old_id = session_id();
@@ -125,7 +125,7 @@ function adodb_session_regenerate_id()
                //@session_start();
        }
        $new_id = session_id();
-       $ok =& $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
+       $ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
        
        /* it is possible that the update statement fails due to a collision */
        if (!$ok) {
@@ -350,7 +350,7 @@ function adodb_sess_gc($maxlifetime)
                $fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
                $savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
                $t = time();
-               $rs =& $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
+               $rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
                $ADODB_SESS_CONN->SetFetchMode($savem);
                if ($rs) {
                        $ADODB_SESS_CONN->BeginTrans();
@@ -394,7 +394,7 @@ function adodb_sess_gc($maxlifetime)
        if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select  TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
        else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
        
-       $rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
+       $rs = $ADODB_SESS_CONN->SelectLimit($sql,1);
        if ($rs && !$rs->EOF) {
        
                $dbts = reset($rs->fields);
index 8be7d2e3d3941a9e137dafc2ba058bd72350cc31..eacd6685bf13a65f3c7b7a904d206777defdc050 100644 (file)
@@ -74,8 +74,8 @@ function _adodb_export(&$rs,$sep,$sepreplace,$fp=false,$addtitles=true,$quote =
                $fieldTypes = $rs->FieldTypesArray();
                reset($fieldTypes);
                while(list(,$o) = each($fieldTypes)) {
-                       
-                       $v = $o->name;
+                       if (!$o) $v = '';
+                       else $v = $o->name;
                        if ($escquote) $v = str_replace($quote,$escquotequote,$v);
                        $v = strip_tags(str_replace("\n", $replaceNewLine, str_replace("\r\n",$replaceNewLine,str_replace($sep,$sepreplace,$v))));
                        $elements[] = $v;
index 44267d2a6f6e6b18d60d85180bd6ce736b02932a..c0135cbc48a89bd240999e7d084a9de483821d1a 100644 (file)
@@ -176,7 +176,7 @@ function arr2html(&$arr,$ztabhtml='',$zheaderarray='')
        
        for ($i=0; $i<sizeof($arr); $i++) {
                $s .= '<TR>';
-               $a = &$arr[$i];
+               $a = $arr[$i];
                if (is_array($a)) 
                        for ($j=0; $j<sizeof($a); $j++) {
                                $val = $a[$j];