diff --git adodb-csvlib.inc.php adodb-csvlib.inc.php
index 65c47f43..3dd61b66 100644
--- adodb-csvlib.inc.php
+++ adodb-csvlib.inc.php
@@ -248,7 +248,7 @@ $ADODB_INCLUDED_CSV = 1;
 		//var_dump($arr);
 		if (!is_array($arr)) {
 			$err = "Recordset had unexpected EOF (in serialized recordset)";
-			if (get_magic_quotes_runtime()) $err .= ". Magic Quotes Runtime should be disabled!";
+			if (false) $err .= ". Magic Quotes Runtime should be disabled!";
 			return $false;
 		}
 		$rs = new $rsclass();
diff --git adodb-datadict.inc.php adodb-datadict.inc.php
index dd2433e9..d91e841e 100644
--- adodb-datadict.inc.php
+++ adodb-datadict.inc.php
@@ -517,11 +517,15 @@ class ADODB_DataDict {
 	{
 		$tabname = $this->TableName ($tabname);
 		if ($flds) {
-			list($lines,$pkey,$idxs) = $this->_GenFields($flds);
+			// Avoid use of SERIAL for existing columns, 2014-04-14
+			// by AS
+			list($lines,$pkey,$idxs) = $this->_GenFields($flds, false, false);
 			// genfields can return FALSE at times
 			if ($lines == null) $lines = array();
 			$first  = current($lines);
 			list(,$column_def) = preg_split("/[\t ]+/",$first,2);
+		} else {
+			$column_def = '';
 		}
 		return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def));
 	}
@@ -594,7 +598,7 @@ class ADODB_DataDict {
 
 
 
-	function _GenFields($flds,$widespacing=false)
+	function _GenFields($flds,$widespacing=false,$allowSerial=true)
 	{
 		if (is_string($flds)) {
 			$padding = '     ';
@@ -683,7 +687,9 @@ class ADODB_DataDict {
 								break;
 				case 'UNSIGNED': $funsigned = true; break;
 				case 'AUTOINCREMENT':
-				case 'AUTO':	$fautoinc = true; $fnotnull = true; break;
+				case 'AUTO':	// Serial type (psql) not allowed in ALTER TABLE statements (2014-04-14 AS)
+						if ($allowSerial) $fautoinc = true;
+						$fnotnull = true; break;
 				case 'KEY':
                 // a primary key col can be non unique in itself (if key spans many cols...)
 				case 'PRIMARY':	$fprimary = $v; $fnotnull = true; /*$funiqueindex = true;*/ break;
@@ -959,6 +965,8 @@ class ADODB_DataDict {
 			return $this->CreateTableSQL($tablename, $flds, $tableoptions);
 		}
 
+		$tableflds = $flds;
+		/* #2343: Null / Not Null column flag changes not respected by this code.
 		if (is_array($flds)) {
 		// Cycle through the update fields, comparing
 		// existing fields to fields to update.
@@ -994,15 +1002,19 @@ class ADODB_DataDict {
 				}
 			}
 			$flds = $holdflds;
-		}
+		} */
 
 
 		// already exists, alter table instead
-		list($lines,$pkey,$idxs) = $this->_GenFields($flds);
+		// (Avoid use of SERIAL when altering existing fields for psql,
+		// 2014-04-14 by AS)
+		list($lines,$pkey,$idxs) = $this->_GenFields($flds, false, false);
 		// genfields can return FALSE at times
 		if ($lines == null) $lines = array();
 		$alter = 'ALTER TABLE ' . $this->TableName($tablename);
 		$sql = array();
+		$addSql = array();
+		$recreate = false;
 
 		foreach ( $lines as $id => $v ) {
 			if ( isset($cols[$id]) && is_object($cols[$id]) ) {
@@ -1011,15 +1023,25 @@ class ADODB_DataDict {
 
 				//  We are trying to change the size of the field, if not allowed, simply ignore the request.
 				// $flds[1] holds the type, $flds[2] holds the size -postnuke addition
+/* #2343: Null / Not Null column flag changes not respected by this code.
 				if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)
 				 && (isset($flds[0][2]) && is_numeric($flds[0][2]))) {
 					if ($this->debug) ADOConnection::outp(sprintf("<h3>%s cannot be changed to %s currently</h3>", $flds[0][0], $flds[0][1]));
 					#echo "<h3>$this->alterCol cannot be changed to $flds currently</h3>";
 					continue;
 	 			}
-				$sql[] = $alter . $this->alterCol . ' ' . $v;
+*/
+				$alter = $this->AlterColumnSQL($tablename, array($id => $tableflds[$id]));
+				if (empty($alter)) {
+					$recreate = true;
+				} else {
+					$sql[] = $alter;
+				}
 			} else {
-				$sql[] = $alter . $this->addCol . ' ' . $v;
+				$add = $this->AddColumnSQL($tablename, array($id => $tableflds[$id]));;
+				unset($tableflds[$id]);
+				$sql[] = $add;
+				$addSql[] = $add;
 			}
 		}
 
@@ -1028,6 +1050,10 @@ class ADODB_DataDict {
 			    if ( !isset($lines[$id]) )
 					$sql[] = $alter . $this->dropCol . ' ' . $v->name;
 		}
+		if ($recreate) {
+			$sql = $this->AlterColumnSQL($tablename, false, $tableflds, $tableoptions);
+			$sql[] = $addSql;
+		}
 		return $sql;
 	}
 } // class
diff --git adodb-perf.inc.php adodb-perf.inc.php
index 064613b9..c3de73c0 100644
--- adodb-perf.inc.php
+++ adodb-perf.inc.php
@@ -696,7 +696,7 @@ Committed_AS:   348732 kB
 
 	// magic quotes
 
-	if (isset($_GET['sql']) && get_magic_quotes_gpc()) {
+	if (isset($_GET['sql']) && false) {
 		$_GET['sql'] = $_GET['sql'] = str_replace(array("\\'",'\"'),array("'",'"'),$_GET['sql']);
 	}
 
@@ -1002,7 +1002,7 @@ Committed_AS:   348732 kB
 
 	function undomq($m)
 	{
-	if (get_magic_quotes_gpc()) {
+	if (false) {
 		// undo the damage
 		$m = str_replace('\\\\','\\',$m);
 		$m = str_replace('\"','"',$m);
diff --git adodb-xmlschema.inc.php adodb-xmlschema.inc.php
index b53d4e28..314a3558 100644
--- adodb-xmlschema.inc.php
+++ adodb-xmlschema.inc.php
@@ -127,7 +127,7 @@ class dbObject {
 	*
 	* @access private
 	*/
-	function _tag_open( &$parser, $tag, $attributes ) {
+	function _tag_open( $parser, $tag, $attributes ) {
 
 	}
 
@@ -136,7 +136,7 @@ class dbObject {
 	*
 	* @access private
 	*/
-	function _tag_cdata( &$parser, $cdata ) {
+	function _tag_cdata( $parser, $cdata ) {
 
 	}
 
@@ -145,7 +145,7 @@ class dbObject {
 	*
 	* @access private
 	*/
-	function _tag_close( &$parser, $tag ) {
+	function _tag_close( $parser, $tag ) {
 
 	}
 
@@ -258,7 +258,7 @@ class dbTable extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_open( &$parser, $tag, $attributes ) {
+	function _tag_open( $parser, $tag, $attributes ) {
 		$this->currentElement = strtoupper( $tag );
 
 		switch( $this->currentElement ) {
@@ -317,7 +317,7 @@ class dbTable extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_cdata( &$parser, $cdata ) {
+	function _tag_cdata( $parser, $cdata ) {
 		switch( $this->currentElement ) {
 			// Table constraint
 			case 'CONSTRAINT':
@@ -341,7 +341,7 @@ class dbTable extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_close( &$parser, $tag ) {
+	function _tag_close( $parser, $tag ) {
 		$this->currentElement = '';
 
 		switch( strtoupper( $tag ) ) {
@@ -657,7 +657,7 @@ class dbIndex extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_open( &$parser, $tag, $attributes ) {
+	function _tag_open( $parser, $tag, $attributes ) {
 		$this->currentElement = strtoupper( $tag );
 
 		switch( $this->currentElement ) {
@@ -684,7 +684,7 @@ class dbIndex extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_cdata( &$parser, $cdata ) {
+	function _tag_cdata( $parser, $cdata ) {
 		switch( $this->currentElement ) {
 			// Index field name
 			case 'COL':
@@ -700,7 +700,7 @@ class dbIndex extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_close( &$parser, $tag ) {
+	function _tag_close( $parser, $tag ) {
 		$this->currentElement = '';
 
 		switch( strtoupper( $tag ) ) {
@@ -799,7 +799,7 @@ class dbData extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_open( &$parser, $tag, $attributes ) {
+	function _tag_open( $parser, $tag, $attributes ) {
 		$this->currentElement = strtoupper( $tag );
 
 		switch( $this->currentElement ) {
@@ -821,7 +821,7 @@ class dbData extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_cdata( &$parser, $cdata ) {
+	function _tag_cdata( $parser, $cdata ) {
 		switch( $this->currentElement ) {
 			// Index field name
 			case 'F':
@@ -837,7 +837,7 @@ class dbData extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_close( &$parser, $tag ) {
+	function _tag_close( $parser, $tag ) {
 		$this->currentElement = '';
 
 		switch( strtoupper( $tag ) ) {
@@ -1016,7 +1016,7 @@ class dbQuerySet extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_open( &$parser, $tag, $attributes ) {
+	function _tag_open( $parser, $tag, $attributes ) {
 		$this->currentElement = strtoupper( $tag );
 
 		switch( $this->currentElement ) {
@@ -1038,7 +1038,7 @@ class dbQuerySet extends dbObject {
 	/**
 	* XML Callback to process CDATA elements
 	*/
-	function _tag_cdata( &$parser, $cdata ) {
+	function _tag_cdata( $parser, $cdata ) {
 		switch( $this->currentElement ) {
 			// Line of queryset SQL data
 			case 'QUERY':
@@ -1054,7 +1054,7 @@ class dbQuerySet extends dbObject {
 	*
 	* @access private
 	*/
-	function _tag_close( &$parser, $tag ) {
+	function _tag_close( $parser, $tag ) {
 		$this->currentElement = '';
 
 		switch( strtoupper( $tag ) ) {
@@ -1304,9 +1304,9 @@ class adoSchema {
 	*/
 	function __construct( $db ) {
 		// Initialize the environment
-		$this->mgq = get_magic_quotes_runtime();
+		$this->mgq = false;
 		if ($this->mgq !== false) {
-			ini_set('magic_quotes_runtime', 0);
+			// ini_set('magic_quotes_runtime', 0);
 		}
 
 		$this->db = $db;
@@ -1649,7 +1649,7 @@ class adoSchema {
 	*
 	* @access private
 	*/
-	function _tag_open( &$parser, $tag, $attributes ) {
+	function _tag_open( $parser, $tag, $attributes ) {
 		switch( strtoupper( $tag ) ) {
 			case 'TABLE':
 				$this->obj = new dbTable( $this, $attributes );
@@ -1672,7 +1672,7 @@ class adoSchema {
 	*
 	* @access private
 	*/
-	function _tag_cdata( &$parser, $cdata ) {
+	function _tag_cdata( $parser, $cdata ) {
 	}
 
 	/**
@@ -1681,7 +1681,7 @@ class adoSchema {
 	* @access private
 	* @internal
 	*/
-	function _tag_close( &$parser, $tag ) {
+	function _tag_close( $parser, $tag ) {
 
 	}
 
@@ -2197,7 +2197,7 @@ class adoSchema {
 	*/
 	function Destroy() {
 		if ($this->mgq !== false) {
-			ini_set('magic_quotes_runtime', $this->mgq );
+			// ini_set('magic_quotes_runtime', $this->mgq );
 		}
 	}
 }
diff --git adodb-xmlschema03.inc.php adodb-xmlschema03.inc.php
index 4d1faad3..8a24339f 100644
--- adodb-xmlschema03.inc.php
+++ adodb-xmlschema03.inc.php
@@ -1408,9 +1408,9 @@ class adoSchema {
 	*/
 	function __construct( $db ) {
 		// Initialize the environment
-		$this->mgq = get_magic_quotes_runtime();
+		$this->mgq = false;
 		if ($this->mgq !== false) {
-			ini_set('magic_quotes_runtime', 0 );
+			// ini_set('magic_quotes_runtime', 0 );
 		}
 
 		$this->db = $db;
@@ -2379,7 +2379,7 @@ class adoSchema {
 	*/
 	function Destroy() {
 		if ($this->mgq !== false) {
-			ini_set('magic_quotes_runtime', $this->mgq );
+			// ini_set('magic_quotes_runtime', $this->mgq );
 		}
 	}
 }
diff --git adodb.inc.php adodb.inc.php
index 8a969b99..5936fcd0 100644
--- adodb.inc.php
+++ adodb.inc.php
@@ -862,7 +862,7 @@ if (!defined('_ADODB_LAYER')) {
 	 * Requested by "Karsten Dambekalns" <k.dambekalns@fishfarm.de>
 	 */
 	function QMagic($s) {
-		return $this->qstr($s,get_magic_quotes_gpc());
+		return $this->qstr($s,false);
 	}
 
 	function q(&$s) {
@@ -2064,7 +2064,7 @@ if (!defined('_ADODB_LAYER')) {
 		if (!$rs) {
 		// no cached rs found
 			if ($this->debug) {
-				if (get_magic_quotes_runtime() && !$this->memCache) {
+				if (false && !$this->memCache) {
 					ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :(");
 				}
 				if ($this->debug !== -1) {
@@ -2956,7 +2956,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 		// undo magic quotes for "
 		$s = str_replace('\\"','"',$s);
 
-		if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) {
+		if ($this->replaceQuote == "\\'") {
 			// ' already quoted, no need to change anything
 			return $s;
 		} else {
@@ -2990,7 +2990,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 		// undo magic quotes for "
 		$s = str_replace('\\"','"',$s);
 
-		if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) {
+		if ($this->replaceQuote == "\\'") {
 			// ' already quoted, no need to change anything
 			return "'$s'";
 		} else {
diff --git datadict/datadict-postgres.inc.php datadict/datadict-postgres.inc.php
index 376da9a6..4711e71c 100644
--- datadict/datadict-postgres.inc.php
+++ datadict/datadict-postgres.inc.php
@@ -148,6 +148,9 @@ class ADODB2_postgres extends ADODB_DataDict {
 				$sql[] = $alter . $v;
 			}
 			if ($not_null) {
+				if (isset($default)) {
+					$sql[] = 'UPDATE '.$tabname.' SET '.$colname.' = '.$this->connection->quote($default).' WHERE '.$colname.' IS NULL';
+				}
 				list($colname) = explode(' ',$v);
 				$sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL';
 			}
@@ -190,7 +193,9 @@ class ADODB2_postgres extends ADODB_DataDict {
 		if ($has_alter_column) {
 			$tabname = $this->TableName($tabname);
 			$sql = array();
-			list($lines,$pkey) = $this->_GenFields($flds);
+			// Avoid use of SERIAL when altering an existing column
+			// 2014-04-14 by AS
+			list($lines,$pkey) = $this->_GenFields($flds, false, false);
 			$set_null = false;
 			foreach($lines as $v) {
 				$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
@@ -311,37 +316,45 @@ class ADODB2_postgres extends ADODB_DataDict {
 	{
 		if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds);
 		$copyflds = array();
+		$insertflds = array();
 		foreach($this->MetaColumns($tabname) as $fld) {
-			if (!$dropflds || !in_array($fld->name,$dropflds)) {
+			if ((!$dropflds || !in_array($fld->name,$dropflds)) && isset($tableflds[strtoupper($fld->name)])) {
 				// we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one
-				if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) &&
+				if (((is_array($tableflds)
+					&& in_array($tableflds[strtoupper($fld->name)]['TYPE'], array('I', 'I2', 'I4', 'I8', 'N', 'F')))
+					|| (!is_array($tableflds)
+					&& preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches))) &&
 					in_array($fld->type,array('varchar','char','text','bytea'))) {
 					$copyflds[] = "to_number($fld->name,'S9999999999999D99')";
 				} else {
 					$copyflds[] = $fld->name;
 				}
+				$insertflds[] = $fld->name;
 				// identify the sequence name and the fld its on
-				if ($fld->primary_key && $fld->has_default &&
-					preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) {
+				if (isset($fld->primary_key) && $fld->primary_key && $fld->has_default &&
+					preg_match("/nextval\('(?:[^']+\.)*([^']+)'::(text|regclass)\)/",$fld->default_value,$matches)) {
 					$seq_name = $matches[1];
 					$seq_fld = $fld->name;
 				}
 			}
 		}
 		$copyflds = implode(', ',$copyflds);
+		$insertflds = implode(', ',$insertflds);
 
 		$tempname = $tabname.'_tmp';
 		$aSql[] = 'BEGIN';		// we use a transaction, to make sure not to loose the content of the table
 		$aSql[] = "SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname";
 		$aSql = array_merge($aSql,$this->DropTableSQL($tabname));
 		$aSql = array_merge($aSql,$this->CreateTableSQL($tabname,$tableflds,$tableoptions));
-		$aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname";
-		if ($seq_name && $seq_fld) {	// if we have a sequence we need to set it again
-			$seq_name = $tabname.'_'.$seq_fld.'_seq';	// has to be the name of the new implicit sequence
+		$aSql[] = "INSERT INTO $tabname ($insertflds) SELECT $copyflds FROM $tempname";
+		if (isset($seq_name) && $seq_name && $seq_fld) {	// if we have a sequence we need to set it again
+			// $seq_name = $tabname.'_'.$seq_fld.'_seq';	// has to be the name of the new implicit sequence
+			$seq_name = $this->makeObjectName($tabname, $seq_fld, 'seq');
 			$aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname";
 		}
 		$aSql[] = "DROP TABLE $tempname";
 		// recreate the indexes, if they not contain one of the droped columns
+		/* FIXME 2005-08-01 KJ - Temporarily disabled for XML schema upgrades
 		foreach($this->MetaIndexes($tabname) as $idx_name => $idx_data)
 		{
 			if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) {
@@ -349,10 +362,87 @@ class ADODB2_postgres extends ADODB_DataDict {
 					$idx_data['unique'] ? array('UNIQUE') : False));
 			}
 		}
+		*/
 		$aSql[] = 'COMMIT';
 		return $aSql;
 	}
 
+	/* --- Added by Alec 2005-09-14:
+	 In PostgreSQL <7.3, SERIAL columns can't be used because they
+	impose UNIQUE constraints on the column. In the best case (when
+			we want a UNIQUE constraint), this means that the index is
+	created twice -- once by ADODB, once by PostgreSQL -- and in
+	the worst case, an unwanted UNIQUE condition is imposed.
+
+	The makeObjectName function was ported from PostgreSQL 7.1's
+	analyse.c.
+	--- */
+
+	function makeObjectName($name1, $name2, $typename) {
+		$overhead = 0;
+
+		$name1chars = strlen($name1);
+		if ($name2) {
+			$name2chars = strlen($name2);
+			$overhead++; /* allow for separating underscore */
+		}
+		else $name2chars = 0;
+
+		if ($typename) $overhead += strlen($typename) + 1;
+
+		$availchars = 64 - 1 - $overhead; /* --- 32 = default NAMEDATALEN in PostgreSQL --- */
+
+		/*
+		 * If we must truncate, preferentially truncate the longer name. This
+		* logic could be expressed without a loop, but it's simple and
+		* obvious as a loop.
+		*/
+		while ($name1chars + $name2chars > $availchars) {
+			if ($name1chars > $name2chars) $name1chars--;
+			else $name2chars--;
+		}
+
+		/* Now construct the string using the chosen lengths */
+		$name = substr($name1, 0, $name1chars);
+
+		if ($name2) $name .= '_' . substr($name2, 0, $name2chars);
+		if ($typename) $name .= '_' . $typename;
+
+		return $name;
+	}
+
+	function CreateTableSQL($tabname, $flds, $tableoptions=false) {
+		$sql = ADODB_DataDict::CreateTableSQL($tabname, $flds, $tableoptions);
+
+		if (7.3 > (float) @$this->serverInfo['version']) {
+			foreach ($flds as $fld) {
+				$fld = _array_change_key_case($fld);
+
+				$isAutoInc = false;
+				foreach($fld as $attr => $v) switch ($attr) {
+					case 'AUTOINCREMENT':
+					case 'AUTO':
+						$isAutoInc = true;
+						break;
+					case 'NAME':
+						$fname = $v;
+						break;
+				}
+
+				if (isset($fname) && $isAutoInc) {
+					// This field is an AUTOINCREMENT. Create a sequence
+					// for it.
+					$sequenceName = $this->makeObjectName($tabname, $fname, 'seq');
+					array_unshift($sql, "CREATE SEQUENCE $sequenceName");
+					array_push($sql, "ALTER TABLE $tabname ALTER COLUMN $fname SET DEFAULT nextval('$sequenceName')");
+				}
+			}
+		}
+		return $sql;
+	}
+
+	/* --- End additions by Alec --- */
+
 	function DropTableSQL($tabname)
 	{
 		$sql = ADODB_DataDict::DropTableSQL($tabname);
@@ -367,6 +457,19 @@ class ADODB2_postgres extends ADODB_DataDict {
 	function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
 	{
 		if ($fautoinc) {
+			// Added by Alec 2005-09-14: With PostgreSQL < 7.3, we cannot
+			// use the SERIAL type because it forces the use of a unique
+			// index on that column; at best, this causes duplicate indexes
+			// to be created. At worst, it causes UNIQUE constraints to be
+			// put on columns that shouldn't have them.
+
+			if (7.3 > (float) @$this->serverInfo['version']) {
+				$ftype = 'INTEGER';
+				return '';
+			}
+
+			// ---
+
 			$ftype = 'SERIAL';
 			return '';
 		}
@@ -382,15 +485,22 @@ class ADODB2_postgres extends ADODB_DataDict {
 	// this is still necessary if postgres < 7.3 or the SERIAL was created on an earlier version!!!
 	function _DropAutoIncrement($tabname)
 	{
-		$tabname = $this->connection->quote('%'.$tabname.'%');
+		// FIXME This Code
+		$seq = false;
+		foreach($this->MetaColumns($tabname) as $fld) {
+			if (isset($fld->primary_key) && $fld->primary_key && $fld->has_default &&
+				preg_match("/nextval\('[\"]?(?:[^'\"]+\.)*([^'\"]+)[\"]?'::(?:text|regclass)\)/",$fld->default_value,$matches)) {
+				$seq = $matches[1];
+			}
+		}
 
-		$seq = $this->connection->GetOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'");
+		//$seq = $this->connection->GetOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'");
 
 		// check if a tables depends on the sequenz and it therefor cant and dont need to be droped separatly
 		if (!$seq || $this->connection->GetOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) {
 			return False;
 		}
-		return "DROP SEQUENCE ".$seq;
+		return "DROP SEQUENCE IF EXISTS ".$seq;
 	}
 
 	function RenameTableSQL($tabname,$newname)
diff --git drivers/adodb-postgres64.inc.php drivers/adodb-postgres64.inc.php
index b555fd55..de28d90e 100644
--- drivers/adodb-postgres64.inc.php
+++ drivers/adodb-postgres64.inc.php
@@ -96,8 +96,8 @@ class ADODB_postgres64 extends ADOConnection{
 	var $hasAffectedRows = true;
 	var $hasLimit = false;	// set to true for pgsql 7 only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
 	// below suggested by Freek Dijkstra
-	var $true = 'TRUE';		// string that represents TRUE for a database
-	var $false = 'FALSE';		// string that represents FALSE for a database
+	var $true = '1';		// string that represents TRUE for a database
+	var $false = '0';		// string that represents FALSE for a database
 	var $fmtDate = "'Y-m-d'";	// used by DBDate() as the default date format used by the database
 	var $fmtTimeStamp = "'Y-m-d H:i:s'"; // used by DBTimeStamp as the default timestamp fmt.
 	var $hasMoveFirst = true;
@@ -144,30 +144,43 @@ class ADODB_postgres64 extends ADOConnection{
 		return " coalesce($field, $ifNull) ";
 	}
 
-	// get the last id - never tested
-	function pg_insert_id($tablename,$fieldname)
-	{
-		$result=pg_query($this->_connectionID, 'SELECT last_value FROM '. $tablename .'_'. $fieldname .'_seq');
-		if ($result) {
-			$arr = @pg_fetch_row($result,0);
-			pg_free_result($result);
-			if (isset($arr[0])) return $arr[0];
-		}
-		return false;
-	}
-
 	/**
-	 * Warning from http://www.php.net/manual/function.pg-getlastoid.php:
-	 * Using a OID as a unique identifier is not generally wise.
-	 * Unless you are very careful, you might end up with a tuple having
-	 * a different OID if a database must be reloaded.
+	 * Get the last inserted ID for the specified table and column.
+	 * @param $table string Optional table name
+	 * @param $id string Optional column name
 	 */
-	function _insertid($table,$column)
-	{
-		if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
-		$oid = pg_getlastoid($this->_resultid);
-		// to really return the id, we need the table and column-name, else we can only return the oid != id
-		return empty($table) || empty($column) ? $oid : $this->GetOne("SELECT $column FROM $table WHERE oid=".(int)$oid);
+	function _insertid($table,$column) {
+		// If no table is specified, we can use LASTVAL()
+		if ($table === '') {
+			$result = pg_exec('SELECT LASTVAL()');
+			$row = pg_fetch_row($result, 0);
+			return $row[0];
+		}
+
+		// If this is PostgreSQL >= 8.0 and a column is specified, use pg_get_serial_sequence
+		$info = $this->ServerInfo();
+		if ($column !== '' && $info['version'] >= 8.0) {
+			$result = pg_exec("SELECT CURRVAL(pg_get_serial_sequence('$table', '$column'))");
+			$row = pg_fetch_row($result, 0);
+			return $row[0];
+		}
+
+		// Try to identify the sequence name from the column descriptions
+		foreach($this->MetaColumns($table) as $fld) {
+			if (
+				isset($fld->primary_key) && $fld->primary_key && $fld->has_default &&
+				preg_match("/nextval\('(?:[^']+\.)*([^']+)'::(text|regclass)\)/",$fld->default_value,$matches) &&
+				($fld->name == $column || $column == '') // Field matches specified value or none given
+			) {
+				$result = pg_exec('SELECT CURRVAL(\'' . $matches[1] . '\')');
+				$row = pg_fetch_row($result, 0);
+assert($row[0] != 0);
+				return $row[0];
+			}
+		}
+
+		// Unable to identify sequence to use.
+		assert(false);
 	}
 
 	function _affectedrows()
@@ -564,6 +577,9 @@ class ADODB_postgres64 extends ADOConnection{
 			$fld->name = $rs->fields[0];
 			$fld->type = $rs->fields[1];
 			$fld->max_length = $rs->fields[2];
+			$fld->primary_key = false;
+			$fld->auto_increment = false;
+			$fld->scale = null;
 			$fld->attnum = $rs->fields[6];
 
 			if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
@@ -1049,6 +1065,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
 
 	function _close()
 	{
+		if (!is_resource($this->_queryID)) return true;
 		return @pg_free_result($this->_queryID);
 	}
 
diff --git scripts/.gitignore scripts/.gitignore
deleted file mode 100644
index 3e0e62b2..00000000
--- scripts/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Python byte code
-*.pyc
diff --git scripts/TARADO5.BAT scripts/TARADO5.BAT
deleted file mode 100644
index bf25ef99..00000000
--- scripts/TARADO5.BAT
+++ /dev/null
@@ -1,49 +0,0 @@
-@rem REQUIRES P:\INSTALLS\CMDUTILS
-
-echo Don't forget to strip LF's !!!!!!!!!!!
-pause
-
-
-set VER=518a
-
-d:
-cd \inetpub\wwwroot\php
-
-@del /s /q zadodb\*.*
-@mkdir zadodb
-
-@REM not for release -- make sure in VSS
-attrib -r adodb5\drivers\adodb-text.inc.php
-del adodb5\*.bak
-del adodb5\drivers\*.bak
-del adodb5\hs~*.*
-del adodb5\drivers\hs~*.*
-del adodb5\tests\hs~*.*
-del adodb5\drivers\adodb-text.inc.php
-del adodb5\.#*
-del adodb5\replicate\replicate-steps.php
-del adodb5\replicate\test*.php
-del adodb5\adodb-lite.inc.php
-attrib -r adodb5\*.php
-del adodb5\cute_icons_for_site\*.png
-
-del tmp.tar
-del adodb5*.tgz
-del adodb5*.zip
-
-@mkdir adodb5\docs
-move /y adodb5\*.htm adodb5\docs
-
-@rem CREATE TAR FILE
-tar -f adodb%VER%.tar -c adodb5/*.* adodb5/perf/*.* adodb5/session/*.*  adodb5/pear/*.txt adodb5/pear/Auth/Container/ADOdb.php adodb5/session/old/*.* adodb5/drivers/*.* adodb5/lang/*.* adodb5/tests/*.* adodb5/cute_icons_for_site/*.* adodb5/datadict/*.* adodb5/contrib/*.* adodb5/xsl/*.* adodb5/docs/*.*
-
-@rem CREATE ZIP FILE
-cd zadodb
-tar -xf ..\adodb%VER%.TAR
-zip -r ..\adodb%VER%.zip adodb5
-cd ..
-
-@rem CREATE TGZ FILE, THE RENAME CHANGES UPPERCASE TO LOWERCASE
-gzip -v ADODB%VER%.tar -S .tgz -9
-rename ADODB%VER%.tar.TGZ adodb%VER%.tgz
-
diff --git scripts/buildrelease.py scripts/buildrelease.py
deleted file mode 100755
index 0b37b97b..00000000
--- scripts/buildrelease.py
+++ /dev/null
@@ -1,270 +0,0 @@
-#!/usr/bin/python -u
-'''
-    ADOdb release build script
-
-    - Create release tag if it does not exist
-    - Copy release files to target directory
-    - Generate zip/tar balls
-    -
-'''
-
-import errno
-import getopt
-import re
-import os
-from os import path
-import shutil
-import subprocess
-import sys
-import tempfile
-
-import updateversion
-
-
-# ADOdb Repository reference
-origin_repo = "https://github.com/ADOdb/ADOdb.git"
-release_branch = "master"
-release_prefix = "adodb"
-
-# Directories and files to exclude from release tarballs
-exclude_list = (".git*",
-                "replicate",
-                "scripts",
-                "tests",
-                # There are no png files in there...
-                # "cute_icons_for_site/*.png",
-                "hs~*.*",
-                "adodb-text.inc.php",
-                # This file does not exist in current repo
-                # 'adodb-lite.inc.php'
-                )
-
-# Command-line options
-options = "hb:dfk"
-long_options = ["help", "branch", "debug", "fresh", "keep"]
-
-# Global flags
-debug_mode = False
-fresh_clone = False
-cleanup = True
-
-
-def usage():
-    print '''Usage: %s [options] version release_path
-
-    Parameters:
-        version                 ADOdb version to bundle (e.g. v5.19)
-        release_path            Where to save the release tarballs
-
-    Options:
-        -h | --help             Show this usage message
-
-        -b | --branch <branch>  Use specified branch (defaults to '%s' for '.0'
-                                releases, or 'hotfix/<version>' for patches)
-        -d | --debug            Debug mode (ignores upstream: no fetch, allows
-                                build even if local branch is not in sync)
-        -f | --fresh            Create a fresh clone of the repository
-        -k | --keep             Keep build directories after completion
-                                (useful for debugging)
-''' % (
-        path.basename(__file__),
-        release_branch
-    )
-#end usage()
-
-
-def set_version_and_tag(version):
-    '''
-    '''
-    global release_branch, debug_mode, fresh_clone, cleanup
-
-    # Delete existing tag to force creation in debug mode
-    if debug_mode:
-        try:
-            updateversion.tag_delete(version)
-        except:
-            pass
-
-    # Checkout release branch
-    subprocess.call("git checkout %s" % release_branch, shell=True)
-
-    if not debug_mode:
-        # Make sure we're up-to-date, ignore untracked files
-        ret = subprocess.check_output(
-            "git status --branch --porcelain --untracked-files=no",
-            shell=True
-        )
-        if not re.search(release_branch + "$", ret):
-            print "\nERROR: branch must be aligned with upstream"
-            sys.exit(4)
-
-    # Update the code, create commit and tag
-    updateversion.version_set(version)
-
-    # Make sure we don't delete the modified repo
-    if fresh_clone:
-        cleanup = False
-
-
-def main():
-    global release_branch, debug_mode, fresh_clone, cleanup
-
-   # Get command-line options
-    try:
-        opts, args = getopt.gnu_getopt(sys.argv[1:], options, long_options)
-    except getopt.GetoptError, err:
-        print str(err)
-        usage()
-        sys.exit(2)
-
-    if len(args) < 2:
-        usage()
-        print "ERROR: please specify the version and release_path"
-        sys.exit(1)
-
-    for opt, val in opts:
-        if opt in ("-h", "--help"):
-            usage()
-            sys.exit(0)
-
-        elif opt in ("-b", "--branch"):
-            release_branch = val
-
-        elif opt in ("-d", "--debug"):
-            debug_mode = True
-
-        elif opt in ("-f", "--fresh"):
-            fresh_clone = True
-
-        elif opt in ("-k", "--keep"):
-            cleanup = False
-
-    # Mandatory parameters
-    version = updateversion.version_check(args[0])
-    release_path = args[1]
-
-    # Default release branch
-    if updateversion.version_is_patch(version):
-        release_branch = 'hotfix/' + version
-
-    # -------------------------------------------------------------------------
-    # Start the build
-    #
-    global release_prefix
-
-    print "Building ADOdb release %s into '%s'\n" % (
-        version,
-        release_path
-    )
-
-    if debug_mode:
-        print "DEBUG MODE: ignoring upstream repository status"
-
-    if fresh_clone:
-        # Create a new repo clone
-        print "Cloning a new repository"
-        repo_path = tempfile.mkdtemp(prefix=release_prefix + "-",
-                                     suffix=".git")
-        subprocess.call(
-            "git clone %s %s" % (origin_repo, repo_path),
-            shell=True
-        )
-        os.chdir(repo_path)
-    else:
-        repo_path = subprocess.check_output('git root', shell=True).rstrip()
-        os.chdir(repo_path)
-
-        # Check for any uncommitted changes
-        try:
-            subprocess.check_output(
-                "git diff --exit-code && "
-                "git diff --cached --exit-code",
-                shell=True
-                )
-        except:
-            print "ERROR: there are uncommitted changes in the repository"
-            sys.exit(3)
-
-        # Update the repository
-        if not debug_mode:
-            print "Updating repository in '%s'" % os.getcwd()
-            try:
-                subprocess.check_output("git fetch", shell=True)
-            except:
-                print "ERROR: unable to fetch\n"
-                sys.exit(3)
-
-    # Check existence of Tag for version in repo, create if not found
-    try:
-        updateversion.tag_check(version)
-        if debug_mode:
-            set_version_and_tag(version)
-    except:
-        set_version_and_tag(version)
-
-    # Copy files to release dir
-    release_files = release_prefix + version.split(".")[0]
-    release_tmp_dir = path.join(release_path, release_files)
-    print "Copying release files to '%s'" % release_tmp_dir
-    retry = True
-    while True:
-        try:
-            shutil.copytree(
-                repo_path,
-                release_tmp_dir,
-                ignore=shutil.ignore_patterns(*exclude_list)
-            )
-            break
-        except OSError, err:
-            # First try and file exists, try to delete dir
-            if retry and err.errno == errno.EEXIST:
-                print "WARNING: Directory '%s' exists, delete it and retry" % (
-                    release_tmp_dir
-                )
-                shutil.rmtree(release_tmp_dir)
-                retry = False
-                continue
-            else:
-                # We already tried to delete or some other error occured
-                raise
-
-    # Create tarballs
-    print "Creating release tarballs..."
-    release_name = release_prefix + '-' + version
-    print release_prefix, version, release_name
-
-    os.chdir(release_path)
-    print "- tar"
-    subprocess.call(
-        "tar -czf %s.tar.gz %s" % (release_name, release_files),
-        shell=True
-    )
-    print "- zip"
-    subprocess.call(
-        "zip -rq %s.zip %s" % (release_name, release_files),
-        shell=True
-    )
-
-    if cleanup:
-        print "Deleting working directories"
-        shutil.rmtree(release_tmp_dir)
-        if fresh_clone:
-            shutil.rmtree(repo_path)
-    else:
-        print "\nThe following working directories were kept:"
-        if fresh_clone:
-            print "- '%s' (repo clone)" % repo_path
-        print "- '%s' (release temp dir)" % release_tmp_dir
-        print "Delete them manually when they are no longer needed."
-
-    # Done
-    print "\nADOdb release %s build complete, files saved in '%s'." % (
-        version,
-        release_path
-    )
-    print "Don't forget to generate a README file with the changelog"
-
-#end main()
-
-if __name__ == "__main__":
-    main()
diff --git scripts/updateversion.py scripts/updateversion.py
deleted file mode 100755
index 0c39fd53..00000000
--- scripts/updateversion.py
+++ /dev/null
@@ -1,399 +0,0 @@
-#!/usr/bin/python -u
-'''
-    ADOdb version update script
-
-    Updates the version number, and release date in all php and html files
-'''
-
-from datetime import date
-import getopt
-import os
-from os import path
-import re
-import subprocess
-import sys
-
-
-# ADOdb version validation regex
-# These are used by sed - they are not PCRE !
-_version_dev = "dev"
-_version_regex = "[Vv]?([0-9]\.[0-9]+)(\.([0-9]+))?(-?%s)?" % _version_dev
-_release_date_regex = "[0-9?]+-.*-[0-9]+"
-_changelog_file = "docs/changelog.md"
-
-_tag_prefix = "v"
-
-
-# Command-line options
-options = "hct"
-long_options = ["help", "commit", "tag"]
-
-
-def usage():
-    print '''Usage: %s version
-
-    Parameters:
-        version                 ADOdb version, format: [v]X.YY[a-z|dev]
-
-    Options:
-        -c | --commit           Automatically commit the changes
-        -t | --tag              Create a tag for the new release
-        -h | --help             Show this usage message
-''' % (
-        path.basename(__file__)
-    )
-#end usage()
-
-
-def version_is_dev(version):
-    ''' Returns true if version is a development release
-    '''
-    return version.endswith(_version_dev)
-
-
-def version_is_patch(version):
-    ''' Returns true if version is a patch release (i.e. X.Y.Z with Z > 0)
-    '''
-    return not version.endswith('.0')
-
-
-def version_parse(version):
-    ''' Breakdown the version into groups (Z and -dev are optional)
-        1:(X.Y), 2:(.Z), 3:(Z), 4:(-dev)
-    '''
-    return re.match(r'^%s$' % _version_regex, version)
-
-
-def version_check(version):
-    ''' Checks that the given version is valid, exits with error if not.
-        Returns the SemVer-normalized version without the "v" prefix
-        - add '.0' if missing patch bit
-        - add '-' before dev release suffix if needed
-    '''
-    vparse = version_parse(version)
-    if not vparse:
-        usage()
-        print "ERROR: invalid version ! \n"
-        sys.exit(1)
-
-    vnorm = vparse.group(1)
-
-    # Add .patch version component
-    if vparse.group(2):
-        vnorm += vparse.group(2)
-    else:
-        # None was specified, assume a .0 release
-        vnorm += '.0'
-
-    # Normalize version number
-    if version_is_dev(version):
-        vnorm += '-' + _version_dev
-
-    return vnorm
-
-
-def get_release_date(version):
-    ''' Returns the release date in DD-MMM-YYYY format
-        For development releases, DD-MMM will be ??-???
-    '''
-    # Development release
-    if version_is_dev(version):
-        date_format = "??-???-%Y"
-    else:
-        date_format = "%d-%b-%Y"
-
-    # Define release date
-    return date.today().strftime(date_format)
-
-
-def sed_script(version):
-    ''' Builds sed script to update version information in source files
-    '''
-
-    # Version number and release date
-    script = r"s/{}\s+(-?)\s+{}/v{} \5 {}/".format(
-        _version_regex,
-        _release_date_regex,
-        version,
-        get_release_date(version)
-    )
-
-    return script
-
-
-def sed_filelist():
-    ''' Build list of files to update
-    '''
-    dirlist = []
-    for root, dirs, files in os.walk(".", topdown=True):
-        # Filter files by extensions
-        files = [
-            f for f in files
-            if re.search(r'\.(php|html?)$', f, re.IGNORECASE)
-            ]
-        for fname in files:
-            dirlist.append(path.join(root, fname))
-
-    return dirlist
-
-
-def tag_name(version):
-    return _tag_prefix + version
-
-
-def tag_check(version):
-    ''' Checks if the tag for the specified version exists in the repository
-        by attempting to check it out
-        Throws exception if not
-    '''
-    subprocess.check_call(
-        "git checkout --quiet " + tag_name(version),
-        stderr=subprocess.PIPE,
-        shell=True)
-    print "Tag '%s' already exists" % tag_name(version)
-
-
-def tag_delete(version):
-    ''' Deletes the specified tag
-    '''
-    subprocess.check_call(
-        "git tag --delete " + tag_name(version),
-        stderr=subprocess.PIPE,
-        shell=True)
-
-
-def tag_create(version):
-    ''' Creates the tag for the specified version
-        Returns True if tag created
-    '''
-    print "Creating release tag '%s'" % tag_name(version)
-    result = subprocess.call(
-        "git tag --sign --message '%s' %s" % (
-            "ADOdb version %s released %s" % (
-                version,
-                get_release_date(version)
-            ),
-            tag_name(version)
-        ),
-        shell=True
-    )
-    return result == 0
-
-
-def section_exists(filename, version, print_message=True):
-    ''' Checks given file for existing section with specified version
-    '''
-    script = True
-    for i, line in enumerate(open(filename)):
-        if re.search(r'^## ' + version, line):
-            if print_message:
-                print "  Existing section for v%s found," % version,
-            return True
-    return False
-
-
-def version_get_previous(version):
-    ''' Returns the previous version number
-        Don't decrease major versions (raises exception)
-    '''
-    vprev = version.split('.')
-    item = len(vprev) - 1
-
-    while item > 0:
-        val = int(vprev[item])
-        if val > 0:
-            vprev[item] = str(val - 1)
-            break
-        else:
-            item -= 1
-
-    if item == 0:
-        raise ValueError('Refusing to decrease major version number')
-
-    return '.'.join(vprev)
-
-
-def update_changelog(version):
-    ''' Updates the release date in the Change Log
-    '''
-    print "Updating Changelog"
-
-    vparse = version_parse(version)
-
-    # Version number without '-dev' suffix
-    version_release = vparse.group(1) + vparse.group(2)
-    version_previous = version_get_previous(version_release)
-
-    if not section_exists(_changelog_file, version_previous, False):
-        raise ValueError(
-            "ERROR: previous version %s does not exist in changelog" %
-            version_previous
-            )
-
-    # Check if version already exists in changelog
-    version_exists = section_exists(_changelog_file, version_release)
-    if (not version_exists
-            and not version_is_patch(version)
-            and not version_is_dev(version)):
-        version += '-' + _version_dev
-
-    release_date = get_release_date(version)
-
-    # Development release
-    # Insert a new section for next release before the most recent one
-    if version_is_dev(version):
-        # Check changelog file for existing section
-        if version_exists:
-            print "nothing to do"
-            return
-
-        # No existing section found, insert new one
-        if version_is_patch(version_release):
-            print "  Inserting new section for hotfix release v%s" % version
-        else:
-            print "  Inserting new section for v%s" % version_release
-            # Adjust previous version number (remove patch component)
-            version_previous = version_parse(version_previous).group(1)
-        script = "1,/^## {0}/s/^## {0}.*$/## {1} - {2}\\n\\n\\0/".format(
-            version_previous,
-            version_release,
-            release_date
-            )
-
-    # Stable release (X.Y.0)
-    # Replace the 1st occurence of markdown level 2 header matching version
-    # and release date patterns
-    elif not version_is_patch(version):
-        print "  Updating release date for v%s" % version
-        script = r"s/^(## ){0}(\.0)? - {1}.*$/\1{2} - {3}/".format(
-            vparse.group(1),
-            _release_date_regex,
-            version,
-            release_date
-            )
-
-    # Hotfix release (X.Y.[0-9])
-    # Insert a new section for the hotfix release before the most recent
-    # section for version X.Y and display a warning message
-    else:
-        if version_exists:
-            print 'updating release date'
-            script = "s/^## {0}.*$/## {1} - {2}/".format(
-                version.replace('.', '\.'),
-                version,
-                release_date
-                )
-        else:
-            print "  Inserting new section for hotfix release v%s" % version
-            script = "1,/^## {0}/s/^## {0}.*$/## {1} - {2}\\n\\n\\0/".format(
-                version_previous,
-                version,
-                release_date
-                )
-
-        print "  WARNING: review '%s' to ensure added section is correct" % (
-            _changelog_file
-            )
-
-    subprocess.call(
-        "sed -r -i '%s' %s " % (
-            script,
-            _changelog_file
-        ),
-        shell=True
-    )
-#end update_changelog
-
-
-def version_set(version, do_commit=True, do_tag=True):
-    ''' Bump version number and set release date in source files
-    '''
-    print "Preparing version bump commit"
-
-    update_changelog(version)
-
-    print "Updating version and date in source files"
-    subprocess.call(
-        "sed -r -i '%s' %s " % (
-            sed_script(version),
-            " ".join(sed_filelist())
-        ),
-        shell=True
-    )
-    print "Version set to %s" % version
-
-    if do_commit:
-        # Commit changes
-        print "Committing"
-        commit_ok = subprocess.call(
-            "git commit --all --message '%s'" % (
-                "Bump version to %s" % version
-            ),
-            shell=True
-        )
-
-        if do_tag:
-            tag_ok = tag_create(version)
-        else:
-            tag_ok = False
-
-        if commit_ok == 0:
-            print '''
-NOTE: you should carefully review the new commit, making sure updates
-to the files are correct and no additional changes are required.
-If everything is fine, then the commit can be pushed upstream;
-otherwise:
- - Make the required corrections
- - Amend the commit ('git commit --all --amend' ) or create a new one'''
-
-            if tag_ok:
-                print ''' - Drop the tag ('git tag --delete %s')
- - run this script again
-''' % (
-                    tag_name(version)
-                )
-
-    else:
-        print "Note: changes have been staged but not committed."
-#end version_set()
-
-
-def main():
-    # Get command-line options
-    try:
-        opts, args = getopt.gnu_getopt(sys.argv[1:], options, long_options)
-    except getopt.GetoptError, err:
-        print str(err)
-        usage()
-        sys.exit(2)
-
-    if len(args) < 1:
-        usage()
-        print "ERROR: please specify the version"
-        sys.exit(1)
-
-    do_commit = False
-    do_tag = False
-
-    for opt, val in opts:
-        if opt in ("-h", "--help"):
-            usage()
-            sys.exit(0)
-
-        elif opt in ("-c", "--commit"):
-            do_commit = True
-
-        elif opt in ("-t", "--tag"):
-            do_tag = True
-
-    # Mandatory parameters
-    version = version_check(args[0])
-
-    # Let's do it
-    os.chdir(subprocess.check_output('git root', shell=True).rstrip())
-    version_set(version, do_commit, do_tag)
-#end main()
-
-
-if __name__ == "__main__":
-    main()
diff --git scripts/uploadrelease.py scripts/uploadrelease.py
deleted file mode 100755
index 5b295cbb..00000000
--- scripts/uploadrelease.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/python -u
-'''
-    ADOdb release upload script
-'''
-
-from distutils.version import LooseVersion
-import getopt
-import glob
-import os
-from os import path
-import re
-import subprocess
-import sys
-
-
-# Directories and files to exclude from release tarballs
-sf_files = "frs.sourceforge.net:/home/frs/project/adodb/"
-rsync_cmd = "rsync -vP --rsh ssh {opt} {src} {usr}@{dst}"
-
-# Command-line options
-options = "hn"
-long_options = ["help", "dry-run"]
-
-
-def usage():
-    print '''Usage: %s [options] username [release_path]
-
-    This script will upload the files in the given directory (or the
-    current one if unspecified) to Sourceforge.
-
-    Parameters:
-        username                Sourceforge user account
-        release_path            Location of the release files to upload
-                                (see buildrelease.py)
-
-    Options:
-        -h | --help             Show this usage message
-        -n | --dry-run          Do not upload the files
-''' % (
-        path.basename(__file__)
-    )
-#end usage()
-
-
-def call_rsync(usr, opt, src, dst):
-    ''' Calls rsync to upload files with given parameters
-        usr = ssh username
-        opt = options
-        src = source directory
-        dst = target directory
-    '''
-    global dry_run
-
-    command = rsync_cmd.format(usr=usr, opt=opt, src=src, dst=dst)
-
-    if dry_run:
-        print command
-    else:
-        subprocess.call(command, shell=True)
-
-
-def get_release_version():
-    ''' Get the version number from the zip file to upload
-    '''
-    try:
-        zipfile = glob.glob('adodb-*.zip')[0]
-    except IndexError:
-        print "ERROR: release zip file not found in '%s'" % release_path
-        sys.exit(1)
-
-    try:
-        version = re.search(
-            "^adodb-([\d]+\.[\d]+\.[\d]+)\.zip$",
-            zipfile
-            ).group(1)
-    except AttributeError:
-        print "ERROR: unable to extract version number from '%s'" % zipfile
-        print "       Only 3 groups of digits separated by periods are allowed"
-        sys.exit(1)
-
-    return version
-
-
-def sourceforge_target_dir(version):
-    ''' Returns the sourceforge target directory
-        Base directory as defined in sf_files global variable, plus
-        - if version >= 5.21: adodb-X.Y
-        - for older versions: adodb-XYZ-for-php5
-    '''
-    # Keep only X.Y (discard patch number)
-    short_version = version.rsplit('.', 1)[0]
-
-    directory = 'adodb-php5-only/'
-    if LooseVersion(version) >= LooseVersion('5.21'):
-        directory += "adodb-" + short_version
-    else:
-        directory += "adodb-{}-for-php5".format(short_version.replace('.', ''))
-
-    return directory
-
-
-def process_command_line():
-    ''' Retrieve command-line options and set global variables accordingly
-    '''
-    global upload_files, upload_doc, dry_run, username, release_path
-
-    # Get command-line options
-    try:
-        opts, args = getopt.gnu_getopt(sys.argv[1:], options, long_options)
-    except getopt.GetoptError, err:
-        print str(err)
-        usage()
-        sys.exit(2)
-
-    if len(args) < 1:
-        usage()
-        print "ERROR: please specify the Sourceforge user and release_path"
-        sys.exit(1)
-
-    # Default values for flags
-    dry_run = False
-
-    for opt, val in opts:
-        if opt in ("-h", "--help"):
-            usage()
-            sys.exit(0)
-
-        elif opt in ("-n", "--dry-run"):
-            dry_run = True
-
-    # Mandatory parameters
-    username = args[0]
-
-    # Change to release directory, current if not specified
-    try:
-        release_path = args[1]
-        os.chdir(release_path)
-    except IndexError:
-        release_path = os.getcwd()
-
-
-def upload_release_files():
-    ''' Upload release files from source directory to SourceForge
-    '''
-    version = get_release_version()
-    target = sf_files + sourceforge_target_dir(version)
-
-    print
-    print "Uploading release files..."
-    print "  Source:", release_path
-    print "  Target: " + target
-    print
-    call_rsync(
-        username,
-        "",
-        path.join(release_path, "*"),
-        target
-    )
-
-
-def main():
-    process_command_line()
-
-    # Start upload process
-    print "ADOdb release upload script"
-
-    upload_release_files()
-
-#end main()
-
-if __name__ == "__main__":
-    main()
diff --git tests/benchmark.php tests/benchmark.php
deleted file mode 100644
index 7be23bb2..00000000
--- tests/benchmark.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-
-<html>
-<head>
-	<title>ADODB Benchmarks</title>
-</head>
-
-<body>
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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.
-
-  Benchmark code to test the speed to the ADODB library with different databases.
-  This is a simplistic benchmark to be used as the basis for further testing.
-  It should not be used as proof of the superiority of one database over the other.
-*/
-
-$testmssql = true;
-//$testvfp = true;
-$testoracle = true;
-$testado = true;
-$testibase = true;
-$testaccess = true;
-$testmysql = true;
-$testsqlite = true;;
-
-set_time_limit(240); // increase timeout
-
-include("../tohtml.inc.php");
-include("../adodb.inc.php");
-
-function testdb(&$db,$createtab="create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)")
-{
-GLOBAL $ADODB_version,$ADODB_FETCH_MODE;
-
-	adodb_backtrace();
-
-	$max = 100;
-	$sql = 'select * from ADOXYZ';
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-
-	//print "<h3>ADODB Version: $ADODB_version Host: <i>$db->host</i> &nbsp; Database: <i>$db->database</i></h3>";
-
-	// perform query once to cache results so we are only testing throughput
-	$rs = $db->Execute($sql);
-	if (!$rs){
-		print "Error in recordset<p>";
-		return;
-	}
-	$arr = $rs->GetArray();
-	//$db->debug = true;
-	global $ADODB_COUNTRECS;
-	$ADODB_COUNTRECS = false;
-	$start = microtime();
-	for ($i=0; $i < $max; $i++) {
-		$rs = $db->Execute($sql);
-		$arr = $rs->GetArray();
-	   //		 print $arr[0][1];
-	}
-	$end =  microtime();
-	$start = explode(' ',$start);
-	$end = explode(' ',$end);
-
-	//print_r($start);
-	//print_r($end);
-
-	  //  print_r($arr);
-	$total = $end[0]+trim($end[1]) - $start[0]-trim($start[1]);
-	printf ("<p>seconds = %8.2f for %d iterations each with %d records</p>",$total,$max, sizeof($arr));
-	flush();
-
-
-		//$db->Close();
-}
-include("testdatabases.inc.php");
-
-?>
-
-
-</body>
-</html>
diff --git tests/client.php tests/client.php
deleted file mode 100644
index 0144519c..00000000
--- tests/client.php
+++ /dev/null
@@ -1,199 +0,0 @@
-<html>
-<body bgcolor=white>
-<?php
-/**
- * @version   v5.20.18  28-Jun-2020
- * @copyright (c) 2001-2013 John Lim (jlim#natsoft.com). All rights reserved.
- * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
- * 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
- */
-
- // documentation on usage is at http://adodb.org/dokuwiki/doku.php?id=v5:proxy:proxy_index
-
- echo PHP_VERSION,'<br>';
- var_dump(parse_url('odbc_mssql://userserver/'));
- die();
-
-include('../adodb.inc.php');
-include('../tohtml.inc.php');
-
- function send2server($url,$sql)
- {
-	$url .= '?sql='.urlencode($sql);
-	print "<p>$url</p>";
-	$rs = csv2rs($url,$err);
-	if ($err) print $err;
-	return $rs;
- }
-
- function print_pre($s)
- {
- 	print "<pre>";print_r($s);print "</pre>";
- }
-
-
-$serverURL = 'http://localhost/php/phplens/adodb/server.php';
-$testhttp = false;
-
-$sql1 = "insertz into products (productname) values ('testprod 1')";
-$sql2 = "insert into products (productname) values ('testprod 1')";
-$sql3 = "insert into products (productname) values ('testprod 2')";
-$sql4 = "delete from products where productid>80";
-$sql5 = 'select * from products';
-
-if ($testhttp) {
-	print "<a href=#c>Client Driver Tests</a><p>";
-	print "<h3>Test Error</h3>";
-	$rs = send2server($serverURL,$sql1);
-	print_pre($rs);
-	print "<hr />";
-
-	print "<h3>Test Insert</h3>";
-
-	$rs = send2server($serverURL,$sql2);
-	print_pre($rs);
-	print "<hr />";
-
-	print "<h3>Test Insert2</h3>";
-
-	$rs = send2server($serverURL,$sql3);
-	print_pre($rs);
-	print "<hr />";
-
-	print "<h3>Test Delete</h3>";
-
-	$rs = send2server($serverURL,$sql4);
-	print_pre($rs);
-	print "<hr />";
-
-
-	print "<h3>Test Select</h3>";
-	$rs = send2server($serverURL,$sql5);
-	if ($rs) rs2html($rs);
-
-	print "<hr />";
-}
-
-
-print "<a name=c><h1>CLIENT Driver Tests</h1>";
-$conn = ADONewConnection('csv');
-$conn->Connect($serverURL);
-$conn->debug = true;
-
-print "<h3>Bad SQL</h3>";
-
-$rs = $conn->Execute($sql1);
-
-print "<h3>Insert SQL 1</h3>";
-$rs = $conn->Execute($sql2);
-
-print "<h3>Insert SQL 2</h3>";
-$rs = $conn->Execute($sql3);
-
-print "<h3>Select SQL</h3>";
-$rs = $conn->Execute($sql5);
-if ($rs) rs2html($rs);
-
-print "<h3>Delete SQL</h3>";
-$rs = $conn->Execute($sql4);
-
-print "<h3>Select SQL</h3>";
-$rs = $conn->Execute($sql5);
-if ($rs) rs2html($rs);
-
-
-/* EXPECTED RESULTS FOR HTTP TEST:
-
-Test Insert
-http://localhost/php/adodb/server.php?sql=insert+into+products+%28productname%29+values+%28%27testprod%27%29
-
-adorecordset Object
-(
-	[dataProvider] => native
-	[fields] =>
-	[blobSize] => 64
-	[canSeek] =>
-	[EOF] => 1
-	[emptyTimeStamp] =>
-	[emptyDate] =>
-	[debug] =>
-	[timeToLive] => 0
-	[bind] =>
-	[_numOfRows] => -1
-	[_numOfFields] => 0
-	[_queryID] => 1
-	[_currentRow] => -1
-	[_closed] =>
-	[_inited] =>
-	[sql] => insert into products (productname) values ('testprod')
-	[affectedrows] => 1
-	[insertid] => 81
-)
-
-
---------------------------------------------------------------------------------
-
-Test Insert2
-http://localhost/php/adodb/server.php?sql=insert+into+products+%28productname%29+values+%28%27testprod%27%29
-
-adorecordset Object
-(
-	[dataProvider] => native
-	[fields] =>
-	[blobSize] => 64
-	[canSeek] =>
-	[EOF] => 1
-	[emptyTimeStamp] =>
-	[emptyDate] =>
-	[debug] =>
-	[timeToLive] => 0
-	[bind] =>
-	[_numOfRows] => -1
-	[_numOfFields] => 0
-	[_queryID] => 1
-	[_currentRow] => -1
-	[_closed] =>
-	[_inited] =>
-	[sql] => insert into products (productname) values ('testprod')
-	[affectedrows] => 1
-	[insertid] => 82
-)
-
-
---------------------------------------------------------------------------------
-
-Test Delete
-http://localhost/php/adodb/server.php?sql=delete+from+products+where+productid%3E80
-
-adorecordset Object
-(
-	[dataProvider] => native
-	[fields] =>
-	[blobSize] => 64
-	[canSeek] =>
-	[EOF] => 1
-	[emptyTimeStamp] =>
-	[emptyDate] =>
-	[debug] =>
-	[timeToLive] => 0
-	[bind] =>
-	[_numOfRows] => -1
-	[_numOfFields] => 0
-	[_queryID] => 1
-	[_currentRow] => -1
-	[_closed] =>
-	[_inited] =>
-	[sql] => delete from products where productid>80
-	[affectedrows] => 2
-	[insertid] => 0
-)
-
-[more stuff deleted]
- .
- .
- .
-*/
diff --git tests/pdo.php tests/pdo.php
deleted file mode 100644
index 31ca5969..00000000
--- tests/pdo.php
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-error_reporting(E_ALL);
-include('../adodb.inc.php');
-
-echo "<pre>";
-try {
-	echo "New Connection\n";
-
-
-	$dsn = 'pdo_mysql://root:@localhost/northwind?persist';
-
-	if (!empty($dsn)) {
-		$DB = NewADOConnection($dsn) || die("CONNECT FAILED");
-		$connstr = $dsn;
-	} else {
-
-		$DB = NewADOConnection('pdo');
-
-		echo "Connect\n";
-
-		$u = ''; $p = '';
-		/*
-		$connstr = 'odbc:nwind';
-
-		$connstr = 'oci:';
-		$u = 'scott';
-		$p = 'natsoft';
-
-
-		$connstr ="sqlite:d:\inetpub\adodb\sqlite.db";
-		*/
-
-		$connstr = "mysql:dbname=northwind";
-		$u = 'root';
-
-		$connstr = "pgsql:dbname=test";
-		$u = 'tester';
-		$p = 'test';
-
-		$DB->Connect($connstr,$u,$p) || die("CONNECT FAILED");
-
-	}
-
-	echo "connection string=$connstr\n Execute\n";
-
-	//$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$rs = $DB->Execute("select * from ADOXYZ where id<3");
-	if  ($DB->ErrorNo()) echo "*** errno=".$DB->ErrorNo() . " ".($DB->ErrorMsg())."\n";
-
-
-	//print_r(get_class_methods($DB->_stmt));
-
-	if (!$rs) die("NO RS");
-
-	echo "Meta\n";
-	for ($i=0; $i < $rs->NumCols(); $i++) {
-		var_dump($rs->FetchField($i));
-		echo "<br>";
-	}
-
-	echo "FETCH\n";
-	$cnt = 0;
-	while (!$rs->EOF) {
-		adodb_pr($rs->fields);
-		$rs->MoveNext();
-		if ($cnt++ > 1000) break;
-	}
-
-	echo "<br>--------------------------------------------------------<br>\n\n\n";
-
-	$stmt = $DB->PrepareStmt("select * from ADOXYZ");
-
-	$rs = $stmt->Execute();
-	$cols = $stmt->NumCols(); // execute required
-
-	echo "COLS = $cols";
-	for($i=1;$i<=$cols;$i++) {
-		$v = $stmt->_stmt->getColumnMeta($i);
-		var_dump($v);
-	}
-
-	echo "e=".$stmt->ErrorNo() . " ".($stmt->ErrorMsg())."\n";
-	while ($arr = $rs->FetchRow()) {
-		adodb_pr($arr);
-	}
-	die("DONE\n");
-
-} catch (exception $e) {
-	echo "<pre>";
-	echo $e;
-	echo "</pre>";
-}
diff --git tests/test-active-record.php tests/test-active-record.php
deleted file mode 100644
index 59471620..00000000
--- tests/test-active-record.php
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-
-	include_once('../adodb.inc.php');
-	include_once('../adodb-active-record.inc.php');
-
-	// uncomment the following if you want to test exceptions
-	if (@$_GET['except']) {
-		if (PHP_VERSION >= 5) {
-			include('../adodb-exceptions.inc.php');
-			echo "<h3>Exceptions included</h3>";
-		}
-	}
-
-	$db = NewADOConnection('mysql://root@localhost/northwind?persist');
-	$db->debug=1;
-	ADOdb_Active_Record::SetDatabaseAdapter($db);
-
-
-	$db->Execute("CREATE TEMPORARY TABLE `persons` (
-	                `id` int(10) unsigned NOT NULL auto_increment,
-	                `name_first` varchar(100) NOT NULL default '',
-	                `name_last` varchar(100) NOT NULL default '',
-	                `favorite_color` varchar(100) NOT NULL default '',
-	                PRIMARY KEY  (`id`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-	$db->Execute("CREATE TEMPORARY TABLE `children` (
-	                `id` int(10) unsigned NOT NULL auto_increment,
-					`person_id` int(10) unsigned NOT NULL,
-	                `name_first` varchar(100) NOT NULL default '',
-	                `name_last` varchar(100) NOT NULL default '',
-	                `favorite_pet` varchar(100) NOT NULL default '',
-	                PRIMARY KEY  (`id`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-	class Person extends ADOdb_Active_Record{ function ret($v) {return $v;} }
-	$person = new Person();
-	ADOdb_Active_Record::$_quoteNames = '111';
-
-	echo "<p>Output of getAttributeNames: ";
-	var_dump($person->getAttributeNames());
-
-	/**
-	 * Outputs the following:
-	 * array(4) {
-	 *    [0]=>
-	 *    string(2) "id"
-	 *    [1]=>
-	 *    string(9) "name_first"
-	 *    [2]=>
-	 *    string(8) "name_last"
-	 *    [3]=>
-	 *    string(13) "favorite_color"
-	 *  }
-	 */
-
-	$person = new Person();
-	$person->name_first = 'Andi';
-	$person->name_last  = 'Gutmans';
-	$person->save(); // this save() will fail on INSERT as favorite_color is a must fill...
-
-
-	$person = new Person();
-	$person->name_first     = 'Andi';
-	$person->name_last      = 'Gutmans';
-	$person->favorite_color = 'blue';
-	$person->save(); // this save will perform an INSERT successfully
-
-	echo "<p>The Insert ID generated:"; print_r($person->id);
-
-	$person->favorite_color = 'red';
-	$person->save(); // this save() will perform an UPDATE
-
-	$person = new Person();
-	$person->name_first     = 'John';
-	$person->name_last      = 'Lim';
-	$person->favorite_color = 'lavender';
-	$person->save(); // this save will perform an INSERT successfully
-
-	// load record where id=2 into a new ADOdb_Active_Record
-	$person2 = new Person();
-	$person2->Load('id=2');
-
-	$activeArr = $db->GetActiveRecordsClass($class = "Person",$table = "Persons","id=".$db->Param(0),array(2));
-	$person2 = $activeArr[0];
-	echo "<p>Name (should be John): ",$person->name_first, " <br> Class (should be Person): ",get_class($person2),"<br>";
-
-	$db->Execute("insert into children (person_id,name_first,name_last) values (2,'Jill','Lim')");
-	$db->Execute("insert into children (person_id,name_first,name_last) values (2,'Joan','Lim')");
-	$db->Execute("insert into children (person_id,name_first,name_last) values (2,'JAMIE','Lim')");
-
-	$newperson2 = new Person();
-	$person2->HasMany('children','person_id');
-	$person2->Load('id=2');
-	$person2->name_last='green';
-	$c = $person2->children;
-	$person2->save();
-
-	if (is_array($c) && sizeof($c) == 3 && $c[0]->name_first=='Jill' && $c[1]->name_first=='Joan'
-		&& $c[2]->name_first == 'JAMIE') echo "OK Loaded HasMany</br>";
-	else {
-		var_dump($c);
-		echo "error loading hasMany should have 3 array elements Jill Joan Jamie<br>";
-	}
-
-	class Child extends ADOdb_Active_Record{};
-	$ch = new Child('children',array('id'));
-	$ch->BelongsTo('person','person_id','id');
-	$ch->Load('id=1');
-	if ($ch->name_first !== 'Jill') echo "error in Loading Child<br>";
-
-	$p = $ch->person;
-	if ($p->name_first != 'John') echo "Error loading belongsTo<br>";
-	else echo "OK loading BelongTo<br>";
-
-	$p->hasMany('children','person_id');
-	$p->LoadRelations('children', "	Name_first like 'J%' order by id",1,2);
-	if (sizeof($p->children) == 2 && $p->children[1]->name_first == 'JAMIE') echo "OK LoadRelations<br>";
-	else echo "error LoadRelations<br>";
-
-		$db->Execute("CREATE TEMPORARY TABLE `persons2` (
-	                `id` int(10) unsigned NOT NULL auto_increment,
-	                `name_first` varchar(100) NOT NULL default '',
-	                `name_last` varchar(100) NOT NULL default '',
-	                `favorite_color` varchar(100) default '',
-	                PRIMARY KEY  (`id`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-	$p = new adodb_active_record('persons2');
-	$p->name_first = 'James';
-
-	$p->name_last = 'James';
-
-	$p->HasMany('children','person_id');
-	$p->children;
-	var_dump($p);
-	$p->Save();
diff --git tests/test-active-recs2.php tests/test-active-recs2.php
deleted file mode 100644
index f5898fcd..00000000
--- tests/test-active-recs2.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-error_reporting(E_ALL);
-include('../adodb.inc.php');
-
-include('../adodb-active-record.inc.php');
-
-###########################
-
-$ADODB_ACTIVE_CACHESECS = 36;
-
-$DBMS = @$_GET['db'];
-
-$DBMS = 'mysql';
-if ($DBMS == 'mysql') {
-	$db = NewADOConnection('mysql://root@localhost/northwind');
-} else if ($DBMS == 'postgres') {
-	$db = NewADOConnection('postgres');
-	$db->Connect("localhost","tester","test","test");
-} else
-	$db = NewADOConnection('oci8://scott:natsoft@/');
-
-
-$arr = $db->ServerInfo();
-echo "<h3>$db->dataProvider: {$arr['description']}</h3>";
-
-$arr = $db->GetActiveRecords('products',' productid<10');
-adodb_pr($arr);
-
-ADOdb_Active_Record::SetDatabaseAdapter($db);
-if  (!$db)  die('failed');
-
-
-
-
-$rec = new ADODB_Active_Record('photos');
-
-$rec = new ADODB_Active_Record('products');
-
-
-adodb_pr($rec->getAttributeNames());
-
-echo "<hr>";
-
-
-$rec->load('productid=2');
-adodb_pr($rec);
-
-$db->debug=1;
-
-
-$rec->productname = 'Changie Chan'.rand();
-
-$rec->insert();
-$rec->update();
-
-$rec->productname = 'Changie Chan 99';
-$rec->replace();
-
-
-$rec2 = new ADODB_Active_Record('products');
-$rec->load('productid=3');
-$rec->save();
-
-$rec = new ADODB_Active_record('products');
-$rec->productname = 'John ActiveRec';
-$rec->notes = 22;
-#$rec->productid=0;
-$rec->discontinued=1;
-$rec->Save();
-$rec->supplierid=33;
-$rec->Save();
-$rec->discontinued=0;
-$rec->Save();
-$rec->Delete();
-
-echo "<p>Affected Rows after delete=".$db->Affected_Rows()."</p>";
diff --git tests/test-active-relations.php tests/test-active-relations.php
deleted file mode 100644
index 7a98d479..00000000
--- tests/test-active-relations.php
+++ /dev/null
@@ -1,85 +0,0 @@
-<?php
-
-	include_once('../adodb.inc.php');
-	include_once('../adodb-active-record.inc.php');
-
-
-	$db = NewADOConnection('mysql://root@localhost/northwind');
-	$db->debug=1;
-	ADOdb_Active_Record::SetDatabaseAdapter($db);
-
-	$db->Execute("CREATE TEMPORARY TABLE `persons` (
-	                `id` int(10) unsigned NOT NULL auto_increment,
-	                `name_first` varchar(100) NOT NULL default '',
-	                `name_last` varchar(100) NOT NULL default '',
-	                `favorite_color` varchar(100) NOT NULL default '',
-	                PRIMARY KEY  (`id`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-	$db->Execute("CREATE TEMPORARY TABLE `children` (
-	                `id` int(10) unsigned NOT NULL auto_increment,
-					`person_id` int(10) unsigned NOT NULL,
-	                `name_first` varchar(100) NOT NULL default '',
-	                `name_last` varchar(100) NOT NULL default '',
-	                `favorite_pet` varchar(100) NOT NULL default '',
-	                PRIMARY KEY  (`id`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-
-	$db->Execute("insert into children (person_id,name_first,name_last) values (1,'Jill','Lim')");
-	$db->Execute("insert into children (person_id,name_first,name_last) values (1,'Joan','Lim')");
-	$db->Execute("insert into children (person_id,name_first,name_last) values (1,'JAMIE','Lim')");
-
-	ADODB_Active_Record::TableHasMany('persons', 'children','person_id');
-	class person extends ADOdb_Active_Record{}
-
-	$person = new person();
-#	$person->HasMany('children','person_id');  ## this is affects all other instances of Person
-
-	$person->name_first     = 'John';
-	$person->name_last      = 'Lim';
-	$person->favorite_color = 'lavender';
-	$person->save(); // this save will perform an INSERT successfully
-
-	$person2 = new person();
-	$person2->Load('id=1');
-
-	$c = $person2->children;
-	if (is_array($c) && sizeof($c) == 3 && $c[0]->name_first=='Jill' && $c[1]->name_first=='Joan'
-		&& $c[2]->name_first == 'JAMIE') echo "OK Loaded HasMany</br>";
-	else {
-		var_dump($c);
-		echo "error loading hasMany should have 3 array elements Jill Joan Jamie<br>";
-	}
-
-	class child extends ADOdb_Active_Record{};
-	ADODB_Active_Record::TableBelongsTo('children','person','person_id','id');
-	$ch = new Child('children',array('id'));
-
-	$ch->Load('id=1');
-	if ($ch->name_first !== 'Jill') echo "error in Loading Child<br>";
-
-	$p = $ch->person;
-	if (!$p || $p->name_first != 'John') echo "Error loading belongsTo<br>";
-	else echo "OK loading BelongTo<br>";
-
-	if ($p) {
-		#$p->HasMany('children','person_id');  ## this is affects all other instances of Person
-		$p->LoadRelations('children', 'order by id',1,2);
-		if (sizeof($p->children) == 2 && $p->children[1]->name_first == 'JAMIE') echo "OK LoadRelations<br>";
-		else {
-		 	var_dump($p->children);
-			echo "error LoadRelations<br>";
-		}
-
-		unset($p->children);
-		$p->LoadRelations('children', " name_first like 'J%' order by id",1,2);
-	}
-	if ($p)
-	foreach($p->children as $c) {
-		echo " Saving $c->name_first <br>";
-		$c->name_first .= ' K.';
-		$c->Save();
-	}
diff --git tests/test-active-relationsx.php tests/test-active-relationsx.php
deleted file mode 100644
index 0f28f728..00000000
--- tests/test-active-relationsx.php
+++ /dev/null
@@ -1,418 +0,0 @@
-<?php
-global $err_count;
-$err_count = 0;
-
-	function found($obj, $cond)
-	{
-		$res = var_export($obj, true);
-		return (strpos($res, $cond));
-	}
-
-	function notfound($obj, $cond)
-	{
-		return !found($obj, $cond);
-	}
-
-	function ar_assert($bool)
-	{
-		global $err_count;
-		if(!$bool)
-			$err_count ++;
-		return $bool;
-	}
-
-		define('WEB', true);
-	function ar_echo($txt)
-	{
-		if(WEB)
-			$txt = str_replace("\n", "<br />\n", $txt);
-		echo $txt;
-	}
-
-	include_once('../adodb.inc.php');
-	include_once('../adodb-active-recordx.inc.php');
-
-
-	$db = NewADOConnection('mysql://root@localhost/test');
-	$db->debug=0;
-	ADOdb_Active_Record::SetDatabaseAdapter($db);
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("Preparing database using SQL queries (creating 'people', 'children')\n");
-
-	$db->Execute("DROP TABLE `people`");
-	$db->Execute("DROP TABLE `children`");
-	$db->Execute("DROP TABLE `artists`");
-	$db->Execute("DROP TABLE `songs`");
-
-	$db->Execute("CREATE TABLE `people` (
-	                `id` int(10) unsigned NOT NULL auto_increment,
-	                `name_first` varchar(100) NOT NULL default '',
-	                `name_last` varchar(100) NOT NULL default '',
-	                `favorite_color` varchar(100) NOT NULL default '',
-	                PRIMARY KEY  (`id`)
-	            ) ENGINE=MyISAM;
-	           ");
-	$db->Execute("CREATE TABLE `children` (
-					`person_id` int(10) unsigned NOT NULL,
-	                `name_first` varchar(100) NOT NULL default '',
-	                `name_last` varchar(100) NOT NULL default '',
-	                `favorite_pet` varchar(100) NOT NULL default '',
-	                `id` int(10) unsigned NOT NULL auto_increment,
-	                PRIMARY KEY  (`id`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-	$db->Execute("CREATE TABLE `artists` (
-	                `name` varchar(100) NOT NULL default '',
-	                `artistuniqueid` int(10) unsigned NOT NULL auto_increment,
-	                PRIMARY KEY  (`artistuniqueid`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-	$db->Execute("CREATE TABLE `songs` (
-	                `name` varchar(100) NOT NULL default '',
-	                `artistid` int(10) NOT NULL,
-	                `recordid` int(10) unsigned NOT NULL auto_increment,
-	                PRIMARY KEY  (`recordid`)
-	            ) ENGINE=MyISAM;
-	           ");
-
-	$db->Execute("insert into children (person_id,name_first,name_last,favorite_pet) values (1,'Jill','Lim','tortoise')");
-	$db->Execute("insert into children (person_id,name_first,name_last) values (1,'Joan','Lim')");
-	$db->Execute("insert into children (person_id,name_first,name_last) values (1,'JAMIE','Lim')");
-
-	$db->Execute("insert into artists (artistuniqueid, name) values(1,'Elvis Costello')");
-	$db->Execute("insert into songs (recordid, name, artistid) values(1,'No Hiding Place', 1)");
-	$db->Execute("insert into songs (recordid, name, artistid) values(2,'American Gangster Time', 1)");
-
-	// This class _implicitely_ relies on the 'people' table (pluralized form of 'person')
-	class Person extends ADOdb_Active_Record
-	{
-		function __construct()
-		{
-			parent::__construct();
-			$this->hasMany('children');
-		}
-	}
-	// This class _implicitely_ relies on the 'children' table
-	class Child extends ADOdb_Active_Record
-	{
-		function __construct()
-		{
-			parent::__construct();
-			$this->belongsTo('person');
-		}
-	}
-	// This class _explicitely_ relies on the 'children' table and shares its metadata with Child
-	class Kid extends ADOdb_Active_Record
-	{
-		function __construct()
-		{
-			parent::__construct('children');
-			$this->belongsTo('person');
-		}
-	}
-	// This class _explicitely_ relies on the 'children' table but does not share its metadata
-	class Rugrat extends ADOdb_Active_Record
-	{
-		function __construct()
-		{
-			parent::__construct('children', false, false, array('new' => true));
-		}
-	}
-
-	class Artist extends ADOdb_Active_Record
-	{
-		function __construct()
-		{
-			parent::__construct('artists', array('artistuniqueid'));
-			$this->hasMany('songs', 'artistid');
-		}
-	}
-	class Song extends ADOdb_Active_Record
-	{
-		function __construct()
-		{
-			parent::__construct('songs', array('recordid'));
-			$this->belongsTo('artist', 'artistid');
-		}
-	}
-
-	ar_echo("Inserting person in 'people' table ('John Lim, he likes lavender')\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$person = new Person();
-	$person->name_first     = 'John';
-	$person->name_last      = 'Lim';
-	$person->favorite_color = 'lavender';
-	$person->save(); // this save will perform an INSERT successfully
-
-	$person = new Person();
-	$person->name_first		= 'Lady';
-	$person->name_last		= 'Cat';
-	$person->favorite_color	= 'green';
-	$person->save();
-
-	$child = new Child();
-	$child->name_first		= 'Fluffy';
-	$child->name_last		= 'Cat';
-	$child->favorite_pet	= 'Cat Lady';
-	$child->person_id		= $person->id;
-	$child->save();
-
-	$child = new Child();
-	$child->name_first		= 'Sun';
-	$child->name_last		= 'Cat';
-	$child->favorite_pet	= 'Cat Lady';
-	$child->person_id		= $person->id;
-	$child->save();
-
-	$err_count = 0;
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("person->Find('id=1') [Lazy Method]\n");
-	ar_echo("person is loaded but its children will be loaded on-demand later on\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$person = new Person();
-	$people = $person->Find('id=1');
-	ar_echo((ar_assert(found($people, "'name_first' => 'John'"))) ? "[OK] Found John\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($people, "'favorite_pet' => 'tortoise'"))) ? "[OK] No relation yet\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo("\n-- Lazily Loading Children:\n\n");
-	foreach($people as $aperson)
-	{
-		foreach($aperson->children as $achild)
-		{
-			if($achild->name_first);
-		}
-	}
-	ar_echo((ar_assert(found($people, "'favorite_pet' => 'tortoise'"))) ? "[OK] Found relation: child\n" : "[!!] Missing relation: child\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'Joan'"))) ? "[OK] Found Joan\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'JAMIE'"))) ? "[OK] Found JAMIE\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("person->Find('id=1' ... ADODB_WORK_AR) [Worker Method]\n");
-	ar_echo("person is loaded, and so are its children\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$person = new Person();
-	$people = $person->Find('id=1', false, false, array('loading' => ADODB_WORK_AR));
-	ar_echo((ar_assert(found($people, "'name_first' => 'John'"))) ? "[OK] Found John\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'favorite_pet' => 'tortoise'"))) ? "[OK] Found relation: child\n" : "[!!] Missing relation: child\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'Joan'"))) ? "[OK] Found Joan\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'JAMIE'"))) ? "[OK] Found JAMIE\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("person->Find('id=1' ... ADODB_JOIN_AR) [Join Method]\n");
-	ar_echo("person and its children are loaded using a single query\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$person = new Person();
-	// When I specifically ask for a join, I have to specify which table id I am looking up
-	// otherwise the SQL parser will wonder which table's id that would be.
-	$people = $person->Find('people.id=1', false, false, array('loading' => ADODB_JOIN_AR));
-	ar_echo((ar_assert(found($people, "'name_first' => 'John'"))) ? "[OK] Found John\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'favorite_pet' => 'tortoise'"))) ? "[OK] Found relation: child\n" : "[!!] Missing relation: child\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'Joan'"))) ? "[OK] Found Joan\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'JAMIE'"))) ? "[OK] Found JAMIE\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("person->Load('people.id=1') [Join Method]\n");
-	ar_echo("Load() always uses the join method since it returns only one row\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$person = new Person();
-	// Under the hood, Load(), since it returns only one row, always perform a join
-	// Therefore we need to clarify which id we are talking about.
-	$person->Load('people.id=1');
-	ar_echo((ar_assert(found($person, "'name_first' => 'John'"))) ? "[OK] Found John\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($person, "'favorite_pet' => 'tortoise'"))) ? "[OK] Found relation: child\n" : "[!!] Missing relation: child\n");
-	ar_echo((ar_assert(found($person, "'name_first' => 'Joan'"))) ? "[OK] Found Joan\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($person, "'name_first' => 'JAMIE'"))) ? "[OK] Found JAMIE\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("child->Load('children.id=1') [Join Method]\n");
-	ar_echo("We are now loading from the 'children' table, not from 'people'\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$child = new Child();
-	$child->Load('children.id=1');
-	ar_echo((ar_assert(found($child, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($child, "'favorite_color' => 'lavender'"))) ? "[OK] Found relation: person\n" : "[!!] Missing relation: person\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("child->Find('children.id=1' ... ADODB_WORK_AR) [Worker Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$child = new Child();
-	$children = $child->Find('id=1', false, false, array('loading' => ADODB_WORK_AR));
-	ar_echo((ar_assert(found($children, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($children, "'favorite_color' => 'lavender'"))) ? "[OK] Found relation: person\n" : "[!!] Missing relation: person\n");
-	ar_echo((ar_assert(notfound($children, "'name_first' => 'Joan'"))) ? "[OK] No Joan relation\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($children, "'name_first' => 'JAMIE'"))) ? "[OK] No JAMIE relation\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("kid->Find('children.id=1' ... ADODB_WORK_AR) [Worker Method]\n");
-	ar_echo("Where we see that kid shares relationships with child because they are stored\n");
-	ar_echo("in the common table's metadata structure.\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$kid = new Kid('children');
-	$kids = $kid->Find('children.id=1', false, false, array('loading' => ADODB_WORK_AR));
-	ar_echo((ar_assert(found($kids, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($kids, "'favorite_color' => 'lavender'"))) ? "[OK] Found relation: person\n" : "[!!] Missing relation: person\n");
-	ar_echo((ar_assert(notfound($kids, "'name_first' => 'Joan'"))) ? "[OK] No Joan relation\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($kids, "'name_first' => 'JAMIE'"))) ? "[OK] No JAMIE relation\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("kid->Find('children.id=1' ... ADODB_LAZY_AR) [Lazy Method]\n");
-	ar_echo("Of course, lazy loading also retrieve medata information...\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$kid = new Kid('children');
-	$kids = $kid->Find('children.id=1', false, false, array('loading' => ADODB_LAZY_AR));
-	ar_echo((ar_assert(found($kids, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($kids, "'favorite_color' => 'lavender'"))) ? "[OK] No relation yet\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo("\n-- Lazily Loading People:\n\n");
-	foreach($kids as $akid)
-	{
-		if($akid->person);
-	}
-	ar_echo((ar_assert(found($kids, "'favorite_color' => 'lavender'"))) ? "[OK] Found relation: person\n" : "[!!] Missing relation: person\n");
-	ar_echo((ar_assert(notfound($kids, "'name_first' => 'Joan'"))) ? "[OK] No Joan relation\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo((ar_assert(notfound($kids, "'name_first' => 'JAMIE'"))) ? "[OK] No JAMIE relation\n" : "[!!] Found relation when I shouldn't\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("rugrat->Find('children.id=1' ... ADODB_WORK_AR) [Worker Method]\n");
-	ar_echo("In rugrat's constructor it is specified that\nit must forget any existing relation\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$rugrat = new Rugrat('children');
-	$rugrats = $rugrat->Find('children.id=1', false, false, array('loading' => ADODB_WORK_AR));
-	ar_echo((ar_assert(found($rugrats, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($rugrats, "'favorite_color' => 'lavender'"))) ? "[OK] No relation found\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo((ar_assert(notfound($rugrats, "'name_first' => 'Joan'"))) ? "[OK] No Joan relation\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo((ar_assert(notfound($rugrats, "'name_first' => 'JAMIE'"))) ? "[OK] No JAMIE relation\n" : "[!!] Found relation when I shouldn't\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("kid->Find('children.id=1' ... ADODB_WORK_AR) [Worker Method]\n");
-	ar_echo("Note how only rugrat forgot its relations - kid is fine.\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$kid = new Kid('children');
-	$kids = $kid->Find('children.id=1', false, false, array('loading' => ADODB_WORK_AR));
-	ar_echo((ar_assert(found($kids, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($kids, "'favorite_color' => 'lavender'"))) ? "[OK] I did not forget relation: person\n" : "[!!] I should not have forgotten relation: person\n");
-	ar_echo((ar_assert(notfound($kids, "'name_first' => 'Joan'"))) ? "[OK] No Joan relation\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo((ar_assert(notfound($kids, "'name_first' => 'JAMIE'"))) ? "[OK] No JAMIE relation\n" : "[!!] Found relation when I shouldn't\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("rugrat->Find('children.id=1' ... ADODB_WORK_AR) [Worker Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$rugrat = new Rugrat('children');
-	$rugrats = $rugrat->Find('children.id=1', false, false, array('loading' => ADODB_WORK_AR));
-	$arugrat = $rugrats[0];
-	ar_echo((ar_assert(found($arugrat, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($arugrat, "'favorite_color' => 'lavender'"))) ? "[OK] No relation yet\n" : "[!!] Found relation when I shouldn't\n");
-
-	ar_echo("\n-- Loading relations:\n\n");
-	$arugrat->belongsTo('person');
-	$arugrat->LoadRelations('person', 'order by id', 0, 2);
-	ar_echo((ar_assert(found($arugrat, "'favorite_color' => 'lavender'"))) ? "[OK] Found relation: person\n" : "[!!] Missing relation: person\n");
-	ar_echo((ar_assert(found($arugrat, "'name_first' => 'Jill'"))) ? "[OK] Found Jill\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($arugrat, "'name_first' => 'Joan'"))) ? "[OK] No Joan relation\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo((ar_assert(notfound($arugrat, "'name_first' => 'JAMIE'"))) ? "[OK] No Joan relation\n" : "[!!] Found relation when I shouldn't\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("person->Find('1=1') [Lazy Method]\n");
-	ar_echo("And now for our finale...\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$person = new Person();
-	$people = $person->Find('1=1', false, false, array('loading' => ADODB_LAZY_AR));
-	ar_echo((ar_assert(found($people, "'name_first' => 'John'"))) ? "[OK] Found John\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($people, "'favorite_pet' => 'tortoise'"))) ? "[OK] No relation yet\n" : "[!!] Found relation when I shouldn't\n");
-	ar_echo((ar_assert(notfound($people, "'name_first' => 'Fluffy'"))) ? "[OK] No Fluffy yet\n" : "[!!] Found Fluffy relation when I shouldn't\n");
-	ar_echo("\n-- Lazily Loading Everybody:\n\n");
-	foreach($people as $aperson)
-	{
-		foreach($aperson->children as $achild)
-		{
-			if($achild->name_first);
-		}
-	}
-	ar_echo((ar_assert(found($people, "'favorite_pet' => 'tortoise'"))) ? "[OK] Found relation: child\n" : "[!!] Missing relation: child\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'Joan'"))) ? "[OK] Found Joan\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'JAMIE'"))) ? "[OK] Found JAMIE\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'Lady'"))) ? "[OK] Found Cat Lady\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'Fluffy'"))) ? "[OK] Found Fluffy\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($people, "'name_first' => 'Sun'"))) ? "[OK] Found Sun\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("artist->Load('artistuniqueid=1') [Join Method]\n");
-	ar_echo("Yes, we are dabbling in the musical field now..\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$artist = new Artist();
-	$artist->Load('artistuniqueid=1');
-	ar_echo((ar_assert(found($artist, "'name' => 'Elvis Costello'"))) ? "[OK] Found Elvis Costello\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($artist, "'name' => 'No Hiding Place'"))) ? "[OK] Found relation: song\n" : "[!!] Missing relation: song\n");
-
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("song->Load('recordid=1') [Join Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$song = new Song();
-	$song->Load('recordid=1');
-	ar_echo((ar_assert(found($song, "'name' => 'No Hiding Place'"))) ? "[OK] Found song\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("artist->Find('artistuniqueid=1' ... ADODB_JOIN_AR) [Join Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$artist = new Artist();
-	$artists = $artist->Find('artistuniqueid=1', false, false, array('loading' => ADODB_JOIN_AR));
-	ar_echo((ar_assert(found($artists, "'name' => 'Elvis Costello'"))) ? "[OK] Found Elvis Costello\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($artists, "'name' => 'No Hiding Place'"))) ? "[OK] Found relation: song\n" : "[!!] Missing relation: song\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("song->Find('recordid=1' ... ADODB_JOIN_AR) [Join Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$song = new Song();
-	$songs = $song->Find('recordid=1', false, false, array('loading' => ADODB_JOIN_AR));
-	ar_echo((ar_assert(found($songs, "'name' => 'No Hiding Place'"))) ? "[OK] Found song\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("artist->Find('artistuniqueid=1' ... ADODB_WORK_AR) [Work Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$artist = new Artist();
-	$artists = $artist->Find('artistuniqueid=1', false, false, array('loading' => ADODB_WORK_AR));
-	ar_echo((ar_assert(found($artists, "'name' => 'Elvis Costello'"))) ? "[OK] Found Elvis Costello\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(found($artists, "'name' => 'No Hiding Place'"))) ? "[OK] Found relation: song\n" : "[!!] Missing relation: song\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("song->Find('recordid=1' ... ADODB_JOIN_AR) [Join Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$song = new Song();
-	$songs = $song->Find('recordid=1', false, false, array('loading' => ADODB_WORK_AR));
-	ar_echo((ar_assert(found($songs, "'name' => 'No Hiding Place'"))) ? "[OK] Found song\n" : "[!!] Find failed\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("artist->Find('artistuniqueid=1' ... ADODB_LAZY_AR) [Lazy Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$artist = new Artist();
-	$artists = $artist->Find('artistuniqueid=1', false, false, array('loading' => ADODB_LAZY_AR));
-	ar_echo((ar_assert(found($artists, "'name' => 'Elvis Costello'"))) ? "[OK] Found Elvis Costello\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($artists, "'name' => 'No Hiding Place'"))) ? "[OK] No relation yet\n" : "[!!] Found relation when I shouldn't\n");
-	foreach($artists as $anartist)
-	{
-		foreach($anartist->songs as $asong)
-		{
-			if($asong->name);
-		}
-	}
-	ar_echo((ar_assert(found($artists, "'name' => 'No Hiding Place'"))) ? "[OK] Found relation: song\n" : "[!!] Missing relation: song\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("song->Find('recordid=1' ... ADODB_LAZY_AR) [Lazy Method]\n");
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
-	$song = new Song();
-	$songs = $song->Find('recordid=1', false, false, array('loading' => ADODB_LAZY_AR));
-	ar_echo((ar_assert(found($songs, "'name' => 'No Hiding Place'"))) ? "[OK] Found song\n" : "[!!] Find failed\n");
-	ar_echo((ar_assert(notfound($songs, "'name' => 'Elvis Costello'"))) ? "[OK] No relation yet\n" : "[!!] Found relation when I shouldn't\n");
-	foreach($songs as $asong)
-	{
-		if($asong->artist);
-	}
-	ar_echo((ar_assert(found($songs, "'name' => 'Elvis Costello'"))) ? "[OK] Found relation: artist\n" : "[!!] Missing relation: artist\n");
-
-	ar_echo("\n\n-------------------------------------------------------------------------------------------------------------------\n");
-	ar_echo("Test suite complete. " . (($err_count > 0) ? "$err_count errors found.\n" : "Success.\n"));
-	ar_echo("-------------------------------------------------------------------------------------------------------------------\n");
diff --git tests/test-datadict.php tests/test-datadict.php
deleted file mode 100644
index 90b5aa9d..00000000
--- tests/test-datadict.php
+++ /dev/null
@@ -1,251 +0,0 @@
-<?php
-/*
-
-  @version   v5.20.18  28-Jun-2020
-  @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-  @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-*/
-
-error_reporting(E_ALL);
-include_once('../adodb.inc.php');
-
-foreach(array('sapdb','sybase','mysql','access','oci8po','odbc_mssql','odbc','db2','firebird','postgres','informix') as $dbType) {
-	echo "<h3>$dbType</h3><p>";
-	$db = NewADOConnection($dbType);
-	$dict = NewDataDictionary($db);
-
-	if (!$dict) continue;
-	$dict->debug = 1;
-
-	$opts = array('REPLACE','mysql' => 'ENGINE=INNODB', 'oci8' => 'TABLESPACE USERS');
-
-/*	$flds = array(
-		array('id',	'I',
-							'AUTO','KEY'),
-
-		array('name' => 'firstname', 'type' => 'varchar','size' => 30,
-							'DEFAULT'=>'Joan'),
-
-		array('lastname','varchar',28,
-							'DEFAULT'=>'Chen','key'),
-
-		array('averylonglongfieldname','X',1024,
-							'NOTNULL','default' => 'test'),
-
-		array('price','N','7.2',
-							'NOTNULL','default' => '0.00'),
-
-		array('MYDATE', 'D',
-							'DEFDATE'),
-		array('TS','T',
-							'DEFTIMESTAMP')
-	);*/
-
-	$flds = "
-ID            I           AUTO KEY,
-FIRSTNAME     VARCHAR(30) DEFAULT 'Joan' INDEX idx_name,
-LASTNAME      VARCHAR(28) DEFAULT 'Chen' key INDEX idx_name INDEX idx_lastname,
-averylonglongfieldname X(1024) DEFAULT 'test',
-price         N(7.2)  DEFAULT '0.00',
-MYDATE        D      DEFDATE INDEX idx_date,
-BIGFELLOW     X      NOTNULL,
-TS_SECS            T      DEFTIMESTAMP,
-TS_SUBSEC   TS DEFTIMESTAMP
-";
-
-
-	$sqla = $dict->CreateDatabase('KUTU',array('postgres'=>"LOCATION='/u01/postdata'"));
-	$dict->SetSchema('KUTU');
-
-	$sqli = ($dict->CreateTableSQL('testtable',$flds, $opts));
-	$sqla = array_merge($sqla,$sqli);
-
-	$sqli = $dict->CreateIndexSQL('idx','testtable','price,firstname,lastname',array('BITMAP','FULLTEXT','CLUSTERED','HASH'));
-	$sqla = array_merge($sqla,$sqli);
-	$sqli = $dict->CreateIndexSQL('idx2','testtable','price,lastname');//,array('BITMAP','FULLTEXT','CLUSTERED'));
-	$sqla = array_merge($sqla,$sqli);
-
-	$addflds = array(array('height', 'F'),array('weight','F'));
-	$sqli = $dict->AddColumnSQL('testtable',$addflds);
-	$sqla = array_merge($sqla,$sqli);
-	$addflds = array(array('height', 'F','NOTNULL'),array('weight','F','NOTNULL'));
-	$sqli = $dict->AlterColumnSQL('testtable',$addflds);
-	$sqla = array_merge($sqla,$sqli);
-
-
-	printsqla($dbType,$sqla);
-
-	if (file_exists('d:\inetpub\wwwroot\php\phplens\adodb\adodb.inc.php'))
-	if ($dbType == 'mysqlt') {
-		$db->Connect('localhost', "root", "", "test");
-		$dict->SetSchema('');
-		$sqla2 = $dict->ChangeTableSQL('adoxyz',$flds);
-		if ($sqla2) printsqla($dbType,$sqla2);
-	}
-	if ($dbType == 'postgres') {
-		if (@$db->Connect('localhost', "tester", "test", "test"));
-		$dict->SetSchema('');
-		$sqla2 = $dict->ChangeTableSQL('adoxyz',$flds);
-		if ($sqla2) printsqla($dbType,$sqla2);
-	}
-
-	if ($dbType == 'odbc_mssql') {
-		$dsn = $dsn = "PROVIDER=MSDASQL;Driver={SQL Server};Server=localhost;Database=northwind;";
-		if (@$db->Connect($dsn, "sa", "natsoft", "test"));
-		$dict->SetSchema('');
-		$sqla2 = $dict->ChangeTableSQL('adoxyz',$flds);
-		if ($sqla2) printsqla($dbType,$sqla2);
-	}
-
-
-
-	adodb_pr($dict->databaseType);
-	printsqla($dbType, $dict->DropColumnSQL('table',array('my col','`col2_with_Quotes`','A_col3','col3(10)')));
-	printsqla($dbType, $dict->ChangeTableSQL('adoxyz','LASTNAME varchar(32)'));
-
-}
-
-function printsqla($dbType,$sqla)
-{
-	print "<pre>";
-	//print_r($dict->MetaTables());
-	foreach($sqla as $s) {
-		$s = htmlspecialchars($s);
-		print "$s;\n";
-		if ($dbType == 'oci8') print "/\n";
-	}
-	print "</pre><hr />";
-}
-
-/***
-
-Generated SQL:
-
-mysql
-
-CREATE DATABASE KUTU;
-DROP TABLE KUTU.testtable;
-CREATE TABLE KUTU.testtable (
-id               INTEGER NOT NULL AUTO_INCREMENT,
-firstname        VARCHAR(30) DEFAULT 'Joan',
-lastname         VARCHAR(28) NOT NULL DEFAULT 'Chen',
-averylonglongfieldname LONGTEXT NOT NULL,
-price            NUMERIC(7,2) NOT NULL DEFAULT 0.00,
-MYDATE           DATE DEFAULT CURDATE(),
-                 PRIMARY KEY (id, lastname)
-)TYPE=ISAM;
-CREATE FULLTEXT INDEX idx ON KUTU.testtable (firstname,lastname);
-CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
-ALTER TABLE KUTU.testtable  ADD height           DOUBLE;
-ALTER TABLE KUTU.testtable  ADD weight           DOUBLE;
-ALTER TABLE KUTU.testtable  MODIFY COLUMN height           DOUBLE NOT NULL;
-ALTER TABLE KUTU.testtable  MODIFY COLUMN weight           DOUBLE NOT NULL;
-
-
---------------------------------------------------------------------------------
-
-oci8
-
-CREATE USER KUTU IDENTIFIED BY tiger;
-/
-GRANT CREATE SESSION, CREATE TABLE,UNLIMITED TABLESPACE,CREATE SEQUENCE TO KUTU;
-/
-DROP TABLE KUTU.testtable CASCADE CONSTRAINTS;
-/
-CREATE TABLE KUTU.testtable (
-id               NUMBER(16) NOT NULL,
-firstname        VARCHAR(30) DEFAULT 'Joan',
-lastname         VARCHAR(28) DEFAULT 'Chen' NOT NULL,
-averylonglongfieldname CLOB NOT NULL,
-price            NUMBER(7,2) DEFAULT 0.00 NOT NULL,
-MYDATE           DATE DEFAULT TRUNC(SYSDATE),
-                 PRIMARY KEY (id, lastname)
-)TABLESPACE USERS;
-/
-DROP SEQUENCE KUTU.SEQ_testtable;
-/
-CREATE SEQUENCE KUTU.SEQ_testtable;
-/
-CREATE OR REPLACE TRIGGER KUTU.TRIG_SEQ_testtable BEFORE insert ON KUTU.testtable
-		FOR EACH ROW
-		BEGIN
-		  select KUTU.SEQ_testtable.nextval into :new.id from dual;
-		END;
-/
-CREATE BITMAP INDEX idx ON KUTU.testtable (firstname,lastname);
-/
-CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
-/
-ALTER TABLE testtable ADD (
- height           NUMBER,
- weight           NUMBER);
-/
-ALTER TABLE testtable MODIFY(
- height           NUMBER NOT NULL,
- weight           NUMBER NOT NULL);
-/
-
-
---------------------------------------------------------------------------------
-
-postgres
-AlterColumnSQL not supported for PostgreSQL
-
-
-CREATE DATABASE KUTU LOCATION='/u01/postdata';
-DROP TABLE KUTU.testtable;
-CREATE TABLE KUTU.testtable (
-id               SERIAL,
-firstname        VARCHAR(30) DEFAULT 'Joan',
-lastname         VARCHAR(28) DEFAULT 'Chen' NOT NULL,
-averylonglongfieldname TEXT NOT NULL,
-price            NUMERIC(7,2) DEFAULT 0.00 NOT NULL,
-MYDATE           DATE DEFAULT CURRENT_DATE,
-                 PRIMARY KEY (id, lastname)
-);
-CREATE INDEX idx ON KUTU.testtable USING HASH (firstname,lastname);
-CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
-ALTER TABLE KUTU.testtable  ADD height           FLOAT8;
-ALTER TABLE KUTU.testtable  ADD weight           FLOAT8;
-
-
---------------------------------------------------------------------------------
-
-odbc_mssql
-
-CREATE DATABASE KUTU;
-DROP TABLE KUTU.testtable;
-CREATE TABLE KUTU.testtable (
-id               INT IDENTITY(1,1) NOT NULL,
-firstname        VARCHAR(30) DEFAULT 'Joan',
-lastname         VARCHAR(28) DEFAULT 'Chen' NOT NULL,
-averylonglongfieldname TEXT NOT NULL,
-price            NUMERIC(7,2) DEFAULT 0.00 NOT NULL,
-MYDATE           DATETIME DEFAULT GetDate(),
-                 PRIMARY KEY (id, lastname)
-);
-CREATE CLUSTERED INDEX idx ON KUTU.testtable (firstname,lastname);
-CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
-ALTER TABLE KUTU.testtable  ADD
- height           REAL,
- weight           REAL;
-ALTER TABLE KUTU.testtable  ALTER COLUMN height           REAL NOT NULL;
-ALTER TABLE KUTU.testtable  ALTER COLUMN weight           REAL NOT NULL;
-
-
---------------------------------------------------------------------------------
-*/
-
-
-echo "<h1>Test XML Schema</h1>";
-$ff = file('xmlschema.xml');
-echo "<pre>";
-foreach($ff as $xml) echo htmlspecialchars($xml);
-echo "</pre>";
-include_once('test-xmlschema.php');
diff --git tests/test-perf.php tests/test-perf.php
deleted file mode 100644
index 62465bef..00000000
--- tests/test-perf.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-include_once('../adodb-perf.inc.php');
-
-error_reporting(E_ALL);
-session_start();
-
-if (isset($_GET)) {
-	foreach($_GET as $k => $v) {
-		if (strncmp($k,'test',4) == 0) $_SESSION['_db'] = $k;
-	}
-}
-
-if (isset($_SESSION['_db'])) {
-	$_db = $_SESSION['_db'];
-	$_GET[$_db] = 1;
-	$$_db = 1;
-}
-
-echo "<h1>Performance Monitoring</h1>";
-include_once('testdatabases.inc.php');
-
-
-function testdb($db)
-{
-	if (!$db) return;
-	echo "<font size=1>";print_r($db->ServerInfo()); echo " user=".$db->user."</font>";
-
-	$perf = NewPerfMonitor($db);
-
-	# unit tests
-	if (0) {
-		//$DB->debug=1;
-		echo "Data Cache Size=".$perf->DBParameter('data cache size').'<p>';
-		echo $perf->HealthCheck();
-		echo($perf->SuspiciousSQL());
-		echo($perf->ExpensiveSQL());
-		echo($perf->InvalidSQL());
-		echo $perf->Tables();
-
-		echo "<pre>";
-		echo $perf->HealthCheckCLI();
-		$perf->Poll(3);
-		die();
-	}
-
-	if ($perf) $perf->UI(3);
-}
diff --git tests/test-pgblob.php tests/test-pgblob.php
deleted file mode 100644
index 3add99e6..00000000
--- tests/test-pgblob.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-function getmicrotime()
-{
-	$t = microtime();
-	$t = explode(' ',$t);
-	return (float)$t[1]+ (float)$t[0];
-}
-
-function doloop()
-{
-global $db,$MAX;
-
-	$sql = "select id,firstname,lastname from adoxyz where
-		firstname not like ? and lastname not like ? and id=?";
-	$offset = 0;
-	/*$sql = "select * from juris9.employee join juris9.emp_perf_plan on epp_empkey = emp_id
-		where emp_name not like ? and emp_name not like ? and emp_id=28000+?";
-	$offset = 28000;*/
-	for ($i=1; $i <= $MAX; $i++) {
-		$db->Param(false);
-		$x = (rand() % 10) + 1;
-		$db->debug= ($i==1);
-		$id = $db->GetOne($sql,
-			array('Z%','Z%',$x));
-		if($id != $offset+$x) {
-			print "<p>Error at $x";
-			break;
-		}
-	}
-}
-
-include_once('../adodb.inc.php');
-$db = NewADOConnection('postgres7');
-$db->PConnect('localhost','tester','test','test') || die("failed connection");
-
-$enc = "GIF89a%01%00%01%00%80%FF%00%C0%C0%C0%00%00%00%21%F9%04%01%00%00%00%00%2C%00%00%00%00%01%00%01%00%00%01%012%00%3Bt_clear.gif%0D";
-$val = rawurldecode($enc);
-
-$MAX = 1000;
-
-adodb_pr($db->ServerInfo());
-
-echo "<h4>Testing PREPARE/EXECUTE PLAN</h4>";
-
-
-$db->_bindInputArray = true; // requires postgresql 7.3+ and ability to modify database
-$t = getmicrotime();
-doloop();
-echo '<p>',$MAX,' times, with plan=',getmicrotime() - $t,'</p>';
-
-
-$db->_bindInputArray = false;
-$t = getmicrotime();
-doloop();
-echo '<p>',$MAX,' times, no plan=',getmicrotime() - $t,'</p>';
-
-
-
-echo "<h4>Testing UPDATEBLOB</h4>";
-$db->debug=1;
-
-### TEST BEGINS
-
-$db->Execute("insert into photos (id,name) values(9999,'dot.gif')");
-$db->UpdateBlob('photos','photo',$val,'id=9999');
-$v = $db->GetOne('select photo from photos where id=9999');
-
-
-### CLEANUP
-
-$db->Execute("delete from photos where id=9999");
-
-### VALIDATION
-
-if ($v !== $val) echo "<b>*** ERROR: Inserted value does not match downloaded val<b>";
-else echo "<b>*** OK: Passed</b>";
-
-echo "<pre>";
-echo "INSERTED: ", $enc;
-echo "<hr />";
-echo"RETURNED: ", rawurlencode($v);
-echo "<hr /><p>";
-echo "INSERTED: ", $val;
-echo "<hr />";
-echo "RETURNED: ", $v;
diff --git tests/test-php5.php tests/test-php5.php
deleted file mode 100644
index 1c63f12d..00000000
--- tests/test-php5.php
+++ /dev/null
@@ -1,116 +0,0 @@
-<?php
-/*
-  @version   v5.20.18  28-Jun-2020
-  @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-  @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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.
- */
-
-
-error_reporting(E_ALL);
-
-$path = dirname(__FILE__);
-
-include("$path/../adodb-exceptions.inc.php");
-include("$path/../adodb.inc.php");
-
-echo "<h3>PHP ".PHP_VERSION."</h3>\n";
-try {
-
-$dbt = 'oci8po';
-
-try {
-switch($dbt) {
-case 'oci8po':
-	$db = NewADOConnection("oci8po");
-
-	$db->Connect('localhost','scott','natsoft','sherkhan');
-	break;
-default:
-case 'mysql':
-	$db = NewADOConnection("mysql");
-	$db->Connect('localhost','root','','northwind');
-	break;
-
-case 'mysqli':
-	$db = NewADOConnection("mysqli://root:@localhost/northwind");
-	//$db->Connect('localhost','root','','test');
-	break;
-}
-} catch (exception $e){
-	echo "Connect Failed";
-	adodb_pr($e);
-	die();
-}
-
-$db->debug=1;
-
-$cnt = $db->GetOne("select count(*) from adoxyz where ?<id and id<?",array(10,20));
-$stmt = $db->Prepare("select * from adoxyz where ?<id and id<?");
-if (!$stmt) echo $db->ErrorMsg(),"\n";
-$rs = $db->Execute($stmt,array(10,20));
-
-echo  "<hr /> Foreach Iterator Test (rand=".rand().")<hr />";
-$i = 0;
-foreach($rs as $v) {
-	$i += 1;
-	echo "rec $i: "; $s1 = adodb_pr($v,true); $s2 = adodb_pr($rs->fields,true);
-	if ($s1 != $s2 && !empty($v)) {adodb_pr($s1); adodb_pr($s2);}
-	else echo "passed<br>";
-	flush();
-}
-
-$rs = new ADORecordSet_empty();
-foreach($rs as $v) {
-	echo "<p>empty ";var_dump($v);
-}
-
-
-if ($i != $cnt) die("actual cnt is $i, cnt should be $cnt\n");
-else echo "Count $i is correct<br>";
-
-$rs = $db->Execute("select bad from badder");
-
-} catch (exception $e) {
-	adodb_pr($e);
-	echo "<h3>adodb_backtrace:</h3>\n";
-	$e = adodb_backtrace($e->gettrace());
-}
-
-$rs = $db->Execute("select distinct id, firstname,lastname from adoxyz order by id");
-echo "Result=\n",$rs,"</p>";
-
-echo "<h3>Active Record</h3>";
-
-	include_once("../adodb-active-record.inc.php");
-	ADOdb_Active_Record::SetDatabaseAdapter($db);
-
-try {
-	class City extends ADOdb_Active_Record{};
-	$a = new City();
-
-} catch(exception $e){
-	echo $e->getMessage();
-}
-
-try {
-
-	$a = new City();
-
-	echo "<p>Successfully created City()<br>";
-	#var_dump($a->GetPrimaryKeys());
-	$a->city = 'Kuala Lumpur';
-	$a->Save();
-	$a->Update();
-	#$a->SetPrimaryKeys(array('city'));
-	$a->country = "M'sia";
-	$a->save();
-	$a->Delete();
-} catch(exception $e){
-	echo $e->getMessage();
-}
-
-//include_once("test-active-record.php");
diff --git tests/test-xmlschema.php tests/test-xmlschema.php
deleted file mode 100644
index c56cfec8..00000000
--- tests/test-xmlschema.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?PHP
-
-// V4.50 6 July 2004
-
-error_reporting(E_ALL);
-include_once( "../adodb.inc.php" );
-include_once( "../adodb-xmlschema03.inc.php" );
-
-// To build the schema, start by creating a normal ADOdb connection:
-$db = ADONewConnection( 'mysql' );
-$db->Connect( 'localhost', 'root', '', 'test' ) || die('fail connect1');
-
-// To create a schema object and build the query array.
-$schema = new adoSchema( $db );
-
-// To upgrade an existing schema object, use the following
-// To upgrade an existing database to the provided schema,
-// uncomment the following line:
-#$schema->upgradeSchema();
-
-print "<b>SQL to build xmlschema.xml</b>:\n<pre>";
-// Build the SQL array
-$sql = $schema->ParseSchema( "xmlschema.xml" );
-
-var_dump( $sql );
-print "</pre>\n";
-
-// Execute the SQL on the database
-//$result = $schema->ExecuteSchema( $sql );
-
-// Finally, clean up after the XML parser
-// (PHP won't do this for you!)
-//$schema->Destroy();
-
-
-
-print "<b>SQL to build xmlschema-mssql.xml</b>:\n<pre>";
-
-$db2 = ADONewConnection('mssql');
-$db2->Connect('','adodb','natsoft','northwind') || die("Fail 2");
-
-$db2->Execute("drop table simple_table");
-
-$schema = new adoSchema( $db2 );
-$sql = $schema->ParseSchema( "xmlschema-mssql.xml" );
-
-print_r( $sql );
-print "</pre>\n";
-
-$db2->debug=1;
-
-foreach ($sql as $s)
-$db2->Execute($s);
diff --git tests/test.php tests/test.php
deleted file mode 100644
index 82178864..00000000
--- tests/test.php
+++ /dev/null
@@ -1,1781 +0,0 @@
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-
-
-//if (!defined('E_STRICT')) define('E_STRICT',0);
-error_reporting(E_ALL|E_STRICT);
-
-$ADODB_FLUSH = true;
-
-define('ADODB_ASSOC_CASE',0);
-
-
-function getmicrotime()
-{
-	$t = microtime();
-	$t = explode(' ',$t);
-	return (float)$t[1]+ (float)$t[0];
-}
-
-
-if (PHP_VERSION < 5) include_once('../adodb-pear.inc.php');
-//--------------------------------------------------------------------------------------
-//define('ADODB_ASSOC_CASE',1);
-//
-function Err($msg)
-{
-	print "<b>$msg</b><br>";
-	flush();
-}
-
-function CheckWS($conn)
-{
-global $ADODB_EXTENSION;
-
-	include_once('../session/adodb-session.php');
-	if (defined('CHECKWSFAIL')){ echo " TESTING $conn ";flush();}
-	$saved = $ADODB_EXTENSION;
-	$db = ADONewConnection($conn);
-	$ADODB_EXTENSION = $saved;
-	if (headers_sent()) {
-		print "<p><b>White space detected in adodb-$conn.inc.php or include file...</b></p>";
-		//die();
-	}
-}
-
-function do_strtolower(&$arr)
-{
-	foreach($arr as $k => $v) {
-		if (is_object($v)) $arr[$k] = adodb_pr($v,true);
-		else $arr[$k] = strtolower($v);
-	}
-}
-
-
-function CountExecs($db, $sql, $inputarray)
-{
-global $EXECS;  $EXECS++;
-}
-
-function CountCachedExecs($db, $secs2cache, $sql, $inputarray)
-{
-global $CACHED; $CACHED++;
-}
-
-// the table creation code is specific to the database, so we allow the user
-// to define their own table creation stuff
-
-function testdb(&$db,$createtab="create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)")
-{
-GLOBAL $ADODB_vers,$ADODB_CACHE_DIR,$ADODB_FETCH_MODE,$ADODB_COUNTRECS;
-
-	//adodb_pr($db);
-
-?>	<form method=GET>
-	</p>
-	<table width=100% ><tr><td bgcolor=beige>&nbsp;</td></tr></table>
-	</p>
-<?php
-	$create =false;
-	/*$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-
-	$rs = $db->Execute('select lastname,firstname,lastname,id from ADOXYZ');
-	$arr = $rs->GetAssoc();
-	echo "<pre>";print_r($arr);
-	die();*/
-
-	if (!$db) die("testdb: database not inited");
-	GLOBAL $EXECS, $CACHED;
-
-	$EXECS = 0;
-	$CACHED = 0;
-	//$db->Execute("drop table adodb_logsql");
-	if ((rand()%3) == 0) @$db->Execute("delete from adodb_logsql");
-	$db->debug=1;
-
-	$db->fnExecute = 'CountExecs';
-	$db->fnCacheExecute = 'CountCachedExecs';
-
-	if (empty($_GET['nolog'])) {
-		echo "<h3>SQL Logging enabled</h3>";
-		$db->LogSQL();/*
-		$sql =
-"SELECT t1.sid, t1.sid, t1.title, t1.hometext, t1.notes, t1.aid, t1.informant,
-t2.url, t2.email, t1.catid, t3.title, t1.topic, t4.topicname, t4.topicimage,
-t4.topictext, t1.score, t1.ratings, t1.counter, t1.comments, t1.acomm
-FROM `nuke_stories` `t1`, `nuke_authors` `t2`, `nuke_stories_cat` `t3`, `nuke_topics` `t4`
-	WHERE ((t2.aid=t1.aid) AND (t3.catid=t1.catid) AND (t4.topicid=t1.topic)
-	AND ((t1.alanguage='german') OR (t1.alanguage='')) AND (t1.ihome='0'))
-	ORDER BY t1.time DESC";
-		$db->SelectLimit($sql);
-		echo $db->ErrorMsg();*/
-	}
-	$ADODB_CACHE_DIR = dirname(TempNam('/tmp','testadodb'));
-	$db->debug = false;
-	//print $db->UnixTimeStamp('2003-7-22 23:00:00');
-
-	$phpv = phpversion();
-	if (defined('ADODB_EXTENSION')) $ext = ' &nbsp; Extension '.ADODB_EXTENSION.' installed';
-	else $ext = '';
-	print "<h3>ADODB Version: $ADODB_vers";
-	print "<p>Host: <i>$db->host</i>";
-	print "<br>Database: <i>$db->database</i>";
-	print "<br>PHP: <i>$phpv $ext</i></h3>";
-
-	flush();
-
-	print "Current timezone: " . date_default_timezone_get() . "<p>";
-
-	$arr = $db->ServerInfo();
-	print_r($arr);
-	echo E_ALL,' ',E_STRICT, "<br>";
-	$e = error_reporting(E_ALL | E_STRICT);
-	echo error_reporting(),'<p>';
-	flush();
-	#$db->debug=1;
-	$tt  = $db->Time();
-	if ($tt == 0) echo '<br><b>$db->Time failed</b>';
-	else echo "<br>db->Time: ".date('d-m-Y H:i:s',$tt);
-	echo '<br>';
-
-	echo "Date=",$db->UserDate('2002-04-07'),'<br>';
-	print "<i>date1</i> (1969-02-20) = ".$db->DBDate('1969-2-20');
-	print "<br><i>date1</i> (1999-02-20) = ".$db->DBDate('1999-2-20');
-	print "<br><i>date1.1</i> 1999 injection attack= ".$db->DBDate("'1999', ' injection attack '");
-	print "<br><i>date2</i> (1970-1-2) = ".$db->DBDate(24*3600)."<p>";
-	print "<i>ts1</i> (1999-02-20 13:40:50) = ".$db->DBTimeStamp('1999-2-20 1:40:50 pm');
-	print "<br><i>ts1.1</i> (1999-02-20 13:40:00) = ".$db->DBTimeStamp('1999-2-20 13:40');
-	print "<br><i>ts2</i> (1999-02-20) = ".$db->DBTimeStamp('1999-2-20');
-	print "<br><i>ts2</i> (1999-02-20) = ".$db->DBTimeStamp("'1999-2-20', 'injection attack'");
-	print "<br><i>ts3</i> (1970-1-2 +/- timezone) = ".$db->DBTimeStamp(24*3600);
-	print "<br> Fractional TS (1999-2-20 13:40:50.91): ".$db->DBTimeStamp($db->UnixTimeStamp('1999-2-20 13:40:50.91+1'));
-	 $dd = $db->UnixDate('1999-02-20');
-	print "<br>unixdate</i> 1999-02-20 = ".date('Y-m-d',$dd)."<p>";
-	print "<br><i>ts4</i> =".($db->UnixTimeStamp("19700101000101")+8*3600);
-	print "<br><i>ts5</i> =".$db->DBTimeStamp($db->UnixTimeStamp("20040110092123"));
-	print "<br><i>ts6</i> =".$db->UserTimeStamp("20040110092123");
-	print "<br><i>ts7</i> =".$db->DBTimeStamp("20040110092123");
-	flush();
-	// mssql too slow in failing bad connection
-	if (false && $db->databaseType != 'mssql') {
-		print "<p>Testing bad connection. Ignore following error msgs:<br>";
-		$db2 = ADONewConnection();
-		$rez = $db2->Connect("bad connection");
-		$err = $db2->ErrorMsg();
-		print "<i>Error='$err'</i></p>";
-		if ($rez) print "<b>Cannot check if connection failed.</b> The Connect() function returned true.</p>";
-	}
-	#error_reporting($e);
-	flush();
-
-	//$ADODB_COUNTRECS=false;
-	$rs=$db->Execute('select * from ADOXYZ order by id');
-	if($rs === false) $create = true;
-	else $rs->Close();
-
-	//if ($db->databaseType !='vfp') $db->Execute("drop table ADOXYZ");
-
-	if ($create) {
-		if (false && $db->databaseType == 'ibase') {
-			print "<b>Please create the following table for testing:</b></p>$createtab</p>";
-			return;
-		} else {
-			$db->debug = 99;
-		#	$e = error_reporting(E_ALL-E_WARNING);
-			$db->Execute($createtab);
-		#	error_reporting($e);
-		}
-	}
-	#error_reporting(E_ALL);
-	echo "<p>Testing Metatypes</p>";
-	$t = $db->MetaType('varchar');
-	if ($t != 'C') Err("Bad Metatype for varchar");
-
-	$rs = $db->Execute("delete from ADOXYZ"); // some ODBC drivers will fail the drop so we delete
-	if ($rs) {
-		if(! $rs->EOF) print "<b>Error: </b>RecordSet returned by Execute('delete...') should show EOF</p>";
-		$rs->Close();
-	} else print "err=".$db->ErrorMsg();
-
-	print "<p>Test select on empty table, FetchField when EOF, and GetInsertSQL</p>";
-	$rs = $db->Execute("select id,firstname from ADOXYZ where id=9999");
-	if ($rs && !$rs->EOF) print "<b>Error: </b>RecordSet returned by Execute(select...') on empty table should show EOF</p>";
-	if ($rs->EOF && (($ox = $rs->FetchField(0)) && !empty($ox->name))) {
-		$record['id'] = 99;
-		$record['firstname'] = 'John';
-		$sql =  $db->GetInsertSQL($rs, $record);
-		if (strtoupper($sql) != strtoupper("INSERT INTO ADOXYZ ( id, firstname ) VALUES ( 99, 'John' )")) Err("GetInsertSQL does not work on empty table: $sql");
-	} else {
-		Err("FetchField does not work on empty recordset, meaning GetInsertSQL will fail...");
-	}
-	if ($rs) $rs->Close();
-	flush();
-	//$db->debug=true;
-	print "<p>Testing Commit: ";
-	$time = $db->DBDate(time());
-	if (!$db->BeginTrans()) {
-		print '<b>Transactions not supported</b></p>';
-		if ($db->hasTransactions) Err("hasTransactions should be false");
-	} else { /* COMMIT */
-		if (!$db->hasTransactions) Err("hasTransactions should be true");
-		if ($db->transCnt != 1) Err("Invalid transCnt = $db->transCnt (should be 1)");
-		$rs = $db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values (99,'Should Not','Exist (Commit)',$time)");
-		if ($rs && $db->CommitTrans()) {
-			$rs->Close();
-			$rs = $db->Execute("select * from ADOXYZ where id=99");
-			if ($rs === false || $rs->EOF) {
-				print '<b>Data not saved</b></p>';
-				$rs = $db->Execute("select * from ADOXYZ where id=99");
-				print_r($rs);
-				die();
-			} else print 'OK</p>';
-			if ($rs) $rs->Close();
-		} else {
-			if (!$rs) {
-				print "<b>Insert failed</b></p>";
-				$db->RollbackTrans();
-			} else print "<b>Commit failed</b></p>";
-		}
-		if ($db->transCnt != 0) Err("Invalid transCnt = $db->transCnt (should be 0)");
-
-		/* ROLLBACK */
-		if (!$db->BeginTrans()) print "<p><b>Error in BeginTrans</b>()</p>";
-		print "<p>Testing Rollback: ";
-		$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values (100,'Should Not','Exist (Rollback)',$time)");
-		if ($db->RollbackTrans()) {
-			$rs = $db->Execute("select * from ADOXYZ where id=100");
-			if ($rs && !$rs->EOF) print '<b>Fail: Data should rollback</b></p>';
-			else print 'OK</p>';
-			if ($rs) $rs->Close();
-		} else
-			print "<b>Commit failed</b></p>";
-
-		$rs = $db->Execute('delete from ADOXYZ where id>50');
-		if ($rs) $rs->Close();
-
-		if ($db->transCnt != 0) Err("Invalid transCnt = $db->transCnt (should be 0)");
-	}
-
-	if (1) {
-		print "<p>Testing MetaDatabases()</p>";
-		print_r( $db->MetaDatabases());
-
-		print "<p>Testing MetaTables() and MetaColumns()</p>";
-		$a = $db->MetaTables();
-		if ($a===false) print "<b>MetaTables not supported</b></p>";
-		else {
-			print "Array of tables and views: ";
-			foreach($a as $v) print " ($v) ";
-			print '</p>';
-		}
-
-		$a = $db->MetaTables('VIEW');
-		if ($a===false) print "<b>MetaTables not supported (views)</b></p>";
-		else {
-			print "Array of views: ";
-			foreach($a as $v) print " ($v) ";
-			print '</p>';
-		}
-
-		$a = $db->MetaTables(false,false,'aDo%');
-		if ($a===false) print "<b>MetaTables not supported (mask)</b></p>";
-		else {
-			print "Array of ado%: ";
-			foreach($a as $v) print " ($v) ";
-			print '</p>';
-		}
-
-		$a = $db->MetaTables('TABLE');
-		if ($a===false) print "<b>MetaTables not supported</b></p>";
-		else {
-			print "Array of tables: ";
-			foreach($a as $v) print " ($v) ";
-			print '</p>';
-		}
-
-		$db->debug=0;
-		$rez = $db->MetaColumns("NOSUCHTABLEHERE");
-		if ($rez !== false) {
-			Err("MetaColumns error handling failed");
-			var_dump($rez);
-		}
-		$db->debug=1;
-		$a = $db->MetaColumns('ADOXYZ');
-		if ($a===false) print "<b>MetaColumns not supported</b></p>";
-		else {
-			print "<p>Columns of ADOXYZ: <font size=1><br>";
-			foreach($a as $v) {print_r($v); echo "<br>";}
-			echo "</font>";
-		}
-
-		print "<p>Testing MetaIndexes</p>";
-
-		$a = $db->MetaIndexes(('ADOXYZ'),true);
-		if ($a===false) print "<b>MetaIndexes not supported</b></p>";
-		else {
-			print "<p>Indexes of ADOXYZ: <font size=1><br>";
-			adodb_pr($a);
-			echo "</font>";
-		}
-		print "<p>Testing MetaPrimaryKeys</p>";
-		$a = $db->MetaPrimaryKeys('ADOXYZ');
-		var_dump($a);
-	}
-	$rs = $db->Execute('delete from ADOXYZ');
-	if ($rs) $rs->Close();
-
-	$db->debug = false;
-
-
-	switch ($db->databaseType) {
-	case 'vfp':
-
-		if (0) {
-			// memo test
-			$rs = $db->Execute("select data from memo");
-			rs2html($rs);
-		}
-		break;
-
-	case 'postgres7':
-	case 'postgres64':
-	case 'postgres':
-	case 'ibase':
-		print "<p>Encode=".$db->BlobEncode("abc\0d\"'
-ef")."</p>";//'
-
-		print "<p>Testing Foreign Keys</p>";
-		$arr = $db->MetaForeignKeys('ADOXYZ',false,true);
-		print_r($arr);
-		if (!$arr) Err("No MetaForeignKeys");
-		break;
-
-	case 'odbc_mssql':
-	case 'mssqlpo':
-		print "<p>Testing Foreign Keys</p>";
-		$arr = $db->MetaForeignKeys('Orders',false,true);
-		print_r($arr);
-		if (!$arr) Err("Bad MetaForeignKeys");
-		if ($db->databaseType == 'odbc_mssql') break;
-
-	case 'mssql':
-
-
-/*
-ASSUME Northwind available...
-
-CREATE PROCEDURE SalesByCategory
-	@CategoryName nvarchar(15), @OrdYear nvarchar(4) = '1998'
-AS
-IF @OrdYear != '1996' AND @OrdYear != '1997' AND @OrdYear != '1998'
-BEGIN
-	SELECT @OrdYear = '1998'
-END
-
-SELECT ProductName,
-	TotalPurchase=ROUND(SUM(CONVERT(decimal(14,2), OD.Quantity * (1-OD.Discount) * OD.UnitPrice)), 0)
-FROM [Order Details] OD, Orders O, Products P, Categories C
-WHERE OD.OrderID = O.OrderID
-	AND OD.ProductID = P.ProductID
-	AND P.CategoryID = C.CategoryID
-	AND C.CategoryName = @CategoryName
-	AND SUBSTRING(CONVERT(nvarchar(22), O.OrderDate, 111), 1, 4) = @OrdYear
-GROUP BY ProductName
-ORDER BY ProductName
-GO
-
-
-CREATE PROCEDURE ADODBTestSP
-@a nvarchar(25)
-AS
-SELECT GETDATE() AS T, @a AS A
-GO
-*/
-		print "<h4>Testing Stored Procedures for mssql</h4>";
-		$saved = $db->debug;
-		$db->debug=true;
-		$assoc = $ADODB_FETCH_MODE;
-		$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-		$cmd = $db->PrepareSP('ADODBTestSP');
-		$ss = "You should see me in the output.";
-		$db->InParameter($cmd,$ss,'a');
-		$rs = $db->Execute($cmd);
-		#var_dump($rs->fields);
-		echo $rs->fields['T']." --- ".$rs->fields['A']."---<br>";
-
-		$cat = 'Dairy Products';
-		$yr = '1998';
-
-		$stmt = $db->PrepareSP('SalesByCategory');
-		$db->InParameter($stmt,$cat,'CategoryName');
-		$db->InParameter($stmt,$yr,'OrdYear');
-		$rs = $db->Execute($stmt);
-		rs2html($rs);
-
-		$cat = 'Grains/Cereals';
-		$yr = 1998;
-
-		$stmt = $db->PrepareSP('SalesByCategory');
-		$db->InParameter($stmt,$cat,'CategoryName');
-		$db->InParameter($stmt,$yr,'OrdYear');
-		$rs = $db->Execute($stmt);
-		rs2html($rs);
-
-		$ADODB_FETCH_MODE = $assoc;
-
-		/*
-		Test out params - works in PHP 4.2.3 and 4.3.3 and 4.3.8 but not 4.3.0:
-
-			CREATE PROCEDURE at_date_interval
-				@days INTEGER,
-				@start VARCHAR(20) OUT,
-				@end VARCHAR(20) OUT
-			AS
-			BEGIN
-				set @start = CONVERT(VARCHAR(20), getdate(), 101)
-				set @end =CONVERT(VARCHAR(20), dateadd(day, @days, getdate()), 101 )
-			END
-			GO
-		*/
-		$db->debug=1;
-		$stmt = $db->PrepareSP('at_date_interval');
-		$days = 10;
-		$begin_date = '';
-		$end_date = '';
-		$db->InParameter($stmt,$days,'days', 4, SQLINT4);
-		$db->OutParameter($stmt,$begin_date,'start', 20, SQLVARCHAR );
-		$db->OutParameter($stmt,$end_date,'end', 20, SQLVARCHAR );
-		$db->Execute($stmt);
-		if (empty($begin_date) or empty($end_date) or $begin_date == $end_date) {
-			Err("MSSQL SP Test for OUT Failed");
-			print "begin=$begin_date end=$end_date<p>";
-		} else print "(Today +10days) = (begin=$begin_date end=$end_date)<p>";
-
-		$db->debug = $saved;
-		break;
-	case 'oci8':
-	case 'oci8po':
-
-		if (0) {
-		$t = getmicrotime();
-		$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-		$arr = $db->GetArray('select * from abalone_tree');
-		$arr = $db->GetArray('select * from abalone_tree');
-		$arr = $db->GetArray('select * from abalone_tree');
-		echo "<p>t = ",getmicrotime() - $t,"</p>";
-		die();
-		}
-
-		# cleanup
-		$db->Execute("delete from photos where id=99 or id=1");
-		$db->Execute("insert into photos (id) values(1)");
-		$db->Execute("update photos set photo=null,descclob=null where id=1");
-
-		$saved = $db->debug;
-		$db->debug=true;
-
-
-
-		/*
-		CREATE TABLE PHOTOS
-		(
-		  ID           NUMBER(16) primary key,
-		  PHOTO        BLOB,
-		  DESCRIPTION  VARCHAR2(4000 BYTE),
-		  DESCCLOB     CLOB
-		);
-
-		INSERT INTO PHOTOS (ID) VALUES(1);
-		*/
-		$s = '';
-		for ($i = 0; $i <= 500; $i++) {
-			$s .= '1234567890';
-		}
-
-		$sql = "INSERT INTO photos ( ID, photo) ".
-			"VALUES ( :id, empty_blob() )".
-			" RETURNING photo INTO :xx";
-
-
-		$blob_data = $s;
-		$id = 99;
-
- 		$stmt = $db->PrepareSP($sql);
-		$db->InParameter($stmt, $id, 'id');
-		$blob = $db->InParameter($stmt, $s, 'xx',-1, OCI_B_BLOB);
-		$db->StartTrans();
-		$result = $db->Execute($stmt);
-		$db->CompleteTrans();
-
-		$s2= $db->GetOne("select photo from photos where id=99");
-		echo "<br>---$s2";
-		if ($s !== $s2) Err("insert blob does not match");
-
-		print "<h4>Testing Blob: size=".strlen($s)."</h4>";
-		$ok = $db->Updateblob('photos','photo',$s,'id=1');
-		if (!$ok) Err("Blob failed 1");
-		else {
-			$s2= $db->GetOne("select photo from photos where id=1");
-			if ($s !== $s2) Err("updateblob does not match");
-		}
-
-		print "<h4>Testing Clob: size=".strlen($s)."</h4>";
-		$ok = $db->UpdateClob('photos','descclob',$s,'id=1');
-		if (!$ok) Err("Clob failed 1");
-		else {
-			$s2= $db->GetOne("select descclob from photos where id=1");
-			if ($s !== $s2) Err("updateclob does not match");
-		}
-
-
-		$s = '';
-		$s2 = '';
-		print "<h4>Testing Foreign Keys</h4>";
-		$arr = $db->MetaForeignKeys('emp','scott');
-		print_r($arr);
-		if (!$arr) Err("Bad MetaForeignKeys");
-/*
--- TEST PACKAGE
--- "Set scan off" turns off substitution variables.
-Set scan off;
-
-CREATE OR REPLACE PACKAGE Adodb AS
-TYPE TabType IS REF CURSOR RETURN TAB%ROWTYPE;
-PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames IN VARCHAR);
-PROCEDURE open_tab2 (tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) ;
-PROCEDURE data_out(input IN VARCHAR, output OUT VARCHAR);
-PROCEDURE data_in(input IN VARCHAR);
-PROCEDURE myproc (p1 IN NUMBER, p2 OUT NUMBER);
-END Adodb;
-/
-
-
-CREATE OR REPLACE PACKAGE BODY Adodb AS
-PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames IN VARCHAR) IS
-	BEGIN
-		OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames;
-	END open_tab;
-
-	PROCEDURE open_tab2 (tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) IS
-	BEGIN
-		OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames;
-		tablenames := 'TEST';
-	END open_tab2;
-
-PROCEDURE data_out(input IN VARCHAR, output OUT VARCHAR) IS
-	BEGIN
-		output := 'Cinta Hati '||input;
-	END;
-
-PROCEDURE data_in(input IN VARCHAR) IS
-	ignore varchar(1000);
-	BEGIN
-		ignore := input;
-	END;
-
-PROCEDURE myproc (p1 IN NUMBER, p2 OUT NUMBER) AS
-BEGIN
-p2 := p1;
-END;
-END Adodb;
-/
-
-*/
-
-		print "<h4>Testing Cursor Variables</h4>";
-		$rs = $db->ExecuteCursor("BEGIN adodb.open_tab(:zz,'A%'); END;",'zz');
-
-		if ($rs && !$rs->EOF) {
-			$v = $db->GetOne("SELECT count(*) FROM tab where tname like 'A%'");
-			if ($v == $rs->RecordCount()) print "Test 1 RowCount: OK<p>";
-			else Err("Test 1 RowCount ".$rs->RecordCount().", actual = $v");
-		} else {
-			print "<b>Error in using Cursor Variables 1</b><p>";
-		}
-		if ($rs) $rs->Close();
-
-		print "<h4>Testing Stored Procedures for oci8</h4>";
-
-		$stmt = $db->PrepareSP("BEGIN adodb.data_out(:a1, :a2); END;");
-		$a1 = 'Malaysia';
-		//$a2 = ''; # a2 doesn't even need to be defined!
-		$db->InParameter($stmt,$a1,'a1');
-		$db->OutParameter($stmt,$a2,'a2');
-		$rs = $db->Execute($stmt);
-		if ($rs) {
-			if ($a2 !== 'Cinta Hati Malaysia') print "<b>Stored Procedure Error: a2 = $a2</b><p>";
-			else echo  "OK: a2=$a2<p>";
-		} else {
-			print "<b>Error in using Stored Procedure IN/Out Variables</b><p>";
-		}
-
-		$tname = 'A%';
-
-		$stmt = $db->PrepareSP('select * from tab where tname like :tablename');
-		$db->Parameter($stmt,$tname,'tablename');
-		$rs = $db->Execute($stmt);
-		rs2html($rs);
-
-		$stmt = $db->PrepareSP("begin adodb.data_in(:a1); end;");
-		$db->InParameter($stmt,$a1,'a1');
-		$db->Execute($stmt);
-
-		$db->debug = $saved;
-		break;
-
-	default:
-		break;
-	}
-	$arr = array(
-		array(1,'Caroline','Miranda'),
-		array(2,'John','Lim'),
-		array(3,'Wai Hun','See')
-	);
-	//$db->debug=1;
-	print "<p>Testing Bulk Insert of 3 rows</p>";
-
-//	$db->debug=1;
-//	$db->Execute('select * from table where val=? AND value=?', array('val'=>'http ://www.whatever.com/test?=21', 'value'=>'blabl'));
-
-
-	$sql = "insert into ADOXYZ (id,firstname,lastname) values (".$db->Param('0').",".$db->Param('1').",".$db->Param('2').")";
-	$db->bulkBind = true;
-	$db->StartTrans();
-	$db->debug=99;
-	$db->Execute($sql,$arr);
-	$db->CompleteTrans();
-	$db->bulkBind = false;
-	$rs = $db->Execute('select * from ADOXYZ order by id');
-	if (!$rs || $rs->RecordCount() != 3) Err("Bad bulk insert");
-
-	rs2html($rs);
-
-	$db->Execute('delete from ADOXYZ');
-
-	print "<p>Inserting 50 rows</p>";
-
-	for ($i = 0; $i < 5; $i++) {
-
-	$time = $db->DBDate(time());
-	if (empty($_GET['hide'])) $db->debug = true;
-	switch($db->databaseType){
-	case 'mssqlpo':
-	case 'mssql':
-		$sqlt = "CREATE TABLE mytable (
-  row1 INT  IDENTITY(1,1) NOT NULL,
-  row2 varchar(16),
-  PRIMARY KEY  (row1))";
-  		//$db->debug=1;
-  		if (!$db->Execute("delete from mytable"))
-			$db->Execute($sqlt);
-
-		$ok = $db->Execute("insert into mytable (row2) values ('test')");
-		$ins_id=$db->Insert_ID();
-		echo "Insert ID=";var_dump($ins_id);
-		if ($ins_id == 0) Err("Bad Insert_ID()");
-		$ins_id2 = $db->GetOne("select row1 from mytable");
-		if ($ins_id != $ins_id2) Err("Bad Insert_ID() 2");
-
-		$arr = array(0=>'Caroline',1=>'Miranda');
-		$sql = "insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+0,?,?,$time)";
-		break;
-	case 'mysqli':
-	case 'mysqlt':
-	case 'mysql':
-		$sqlt = "CREATE TABLE `mytable` (
-  `row1` int(11) NOT NULL auto_increment,
-  `row2` varchar(16) NOT NULL default '',
-  PRIMARY KEY  (`row1`),
-  KEY `myindex` (`row1`,`row2`)
-) ";
-		if (!$db->Execute("delete from mytable"))
-			$db->Execute($sqlt);
-
-		$ok = $db->Execute("insert into mytable (row2) values ('test')");
-		$ins_id=$db->Insert_ID();
-		echo "Insert ID=";var_dump($ins_id);
-		if ($ins_id == 0) Err("Bad Insert_ID()");
-		$ins_id2 = $db->GetOne("select row1 from mytable");
-		if ($ins_id != $ins_id2) Err("Bad Insert_ID() 2");
-
-	default:
-		$arr = array(0=>'Caroline',1=>'Miranda');
-		$sql = "insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+0,?,?,$time)";
-		break;
-
-	case 'oci8':
-	case 'oci805':
-		$arr = array('first'=>'Caroline','last'=>'Miranda');
-		$amt = rand() % 100;
-		$sql = "insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+0,:first,:last,$time)";
-		break;
-	}
-	if ($i & 1) {
-		$sql = $db->Prepare($sql);
-	}
-	$rs = $db->Execute($sql,$arr);
-
-	if ($rs === false) Err( 'Error inserting with parameters');
-	else $rs->Close();
-	$db->debug = false;
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+1,'John','Lim',$time)");
-	/*$ins_id=$db->Insert_ID();
-	echo "Insert ID=";var_dump($ins_id);*/
-	if ($db->databaseType == 'mysql') if ($ins_id == 0) Err('Bad Insert_ID');
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+2,'Mary','Lamb',$time )");
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+3,'George','Washington',$time )");
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+4,'Mr. Alan','Tam',$time )");
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+5,'Alan',".$db->quote("Turing'ton").",$time )");
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created)values ($i*10+6,'Serena','Williams',$time )");
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+7,'Yat Sun','Sun',$time )");
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+8,'Wai Hun','See',$time )");
-	$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+9,'Steven','Oey',$time )");
-	} // for
-	if (1) {
-	$db->debug=1;
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$cnt = $db->GetOne("select count(*) from ADOXYZ");
-	$rs = $db->Execute('update ADOXYZ set id=id+1');
-	if (!is_object($rs)) {
-		print_r($rs);
-		err("Update should return object");
-	}
-	if (!$rs) err("Update generated error");
-
-	$nrows = $db->Affected_Rows();
-	if ($nrows === false) print "<p><b>Affected_Rows() not supported</b></p>";
-	else if ($nrows != $cnt)  print "<p><b>Affected_Rows() Error: $nrows returned (should be 50) </b></p>";
-	else print "<p>Affected_Rows() passed</p>";
-	}
-
-	if ($db->dataProvider == 'oci8')  $array = array('zid'=>1,'zdate'=>date('Y-m-d',time()));
-	else $array=array(1,date('Y-m-d',time()));
-
-
-	#$array = array(1,date('Y-m-d',time()));
-	$id = $db->GetOne("select id from ADOXYZ
-		where id=".$db->Param('zid')." and created>=".$db->Param('ZDATE')."",
-		$array);
-	if ($id != 1) Err("Bad bind; id=$id");
-	else echo "<br>Bind date/integer 1 passed";
-
-	$array =array(1,$db->BindDate(time()));
-	$id = $db->GetOne("select id from ADOXYZ
-		where id=".$db->Param('0')." and created>=".$db->Param('1')."",
-		$array);
-	if ($id != 1) Err("Bad bind; id=$id");
-	else echo "<br>Bind date/integer 2 passed";
-
-	$db->debug = false;
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
- //////////////////////////////////////////////////////////////////////////////////////////
-
-	$rs = $db->Execute("select * from ADOXYZ where firstname = 'not known'");
-	if (!$rs ||  !$rs->EOF) print "<p><b>Error on empty recordset</b></p>";
-	else if ($rs->RecordCount() != 0) {
-		print "<p><b>Error on RecordCount. Should be 0. Was ".$rs->RecordCount()."</b></p>";
-		print_r($rs->fields);
-	}
-	if ($db->databaseType !== 'odbc') {
-		$rs = $db->Execute("select id,firstname,lastname,created,".$db->random." from ADOXYZ order by id");
-		if ($rs) {
-			if ($rs->RecordCount() != 50) {
-				print "<p><b>RecordCount returns ".$rs->RecordCount().", should be 50</b></p>";
-				adodb_pr($rs->GetArray());
-				$poc = $rs->PO_RecordCount('ADOXYZ');
-				if ($poc == 50) print "<p> &nbsp; &nbsp; PO_RecordCount passed</p>";
-				else print "<p><b>PO_RecordCount returns wrong value: $poc</b></p>";
-			} else print "<p>RecordCount() passed</p>";
-			if (isset($rs->fields['firstname'])) print '<p>The fields columns can be indexed by column name.</p>';
-			else {
-				Err( '<p>The fields columns <i>cannot</i> be indexed by column name.</p>');
-				print_r($rs->fields);
-			}
-			if (empty($_GET['hide'])) rs2html($rs);
-		}
-		else print "<p><b>Error in Execute of SELECT with random</b></p>";
-	}
-	$val = $db->GetOne("select count(*) from ADOXYZ");
-	 if ($val == 50) print "<p>GetOne returns ok</p>";
-	 else print "<p><b>Fail: GetOne returns $val</b></p>";
-
-	 echo "<b>GetRow Test</b>";
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-	$val1 = $db->GetRow("select count(*) from ADOXYZ");
-	$val2 = $db->GetRow("select count(*) from ADOXYZ");
-	 if ($val1[0] == 50 and sizeof($val1) == 1 and $val2[0] == 50 and sizeof($val2) == 1) print "<p>GetRow returns ok</p>";
-	 else {
-	 	print_r($val);
-	 	print "<p><b>Fail: GetRow returns {$val2[0]}</b></p>";
-	}
-
-	print "<p>FetchObject/FetchNextObject Test</p>";
-	$rs = $db->Execute('select * from ADOXYZ');
-	if ($rs) {
-		if (empty($rs->connection)) print "<b>Connection object missing from recordset</b></br>";
-
-		while ($o = $rs->FetchNextObject()) { // calls FetchObject internally
-			if (!is_string($o->FIRSTNAME) || !is_string($o->LASTNAME)) {
-				print_r($o);
-				print "<p><b>Firstname is not string</b></p>";
-				break;
-			}
-		}
-	} else {
-		print "<p><b>Failed rs</b></p>";
-		die("<p>ADOXYZ table cannot be read - die()");
-	}
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	print "<p>FetchObject/FetchNextObject Test 2</p>";
-	#$db->debug=99;
-	$rs = $db->Execute('select * from ADOXYZ');
-	if (empty($rs->connection)) print "<b>Connection object missing from recordset</b></br>";
-	print_r($rs->fields);
-	while ($o = $rs->FetchNextObject()) { // calls FetchObject internally
-		if (!is_string($o->FIRSTNAME) || !is_string($o->LASTNAME)) {
-			print_r($o);
-			print "<p><b>Firstname is not string</b></p>";
-			break;
-		}
-	}
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-
-	$savefetch = $ADODB_FETCH_MODE;
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-
-	print "<p>CacheSelectLimit  Test...</p>";
-	$rs = $db->CacheSelectLimit('select  id, firstname from  ADOXYZ order by id',2);
-
-	if (ADODB_ASSOC_CASE == 2 || $db->dataProvider == 'oci8') {
-		$id = 'ID';
-		$fname = 'FIRSTNAME';
-	}else {
-		$id = 'id';
-		$fname = 'firstname';
-	}
-
-
-	if ($rs && !$rs->EOF) {
-		if (isset($rs->fields[0])) {
-			Err("ASSOC has numeric fields");
-			print_r($rs->fields);
-		}
-		if ($rs->fields[$id] != 1)  {Err("Error"); print_r($rs->fields);};
-		if (trim($rs->fields[$fname]) != 'Caroline')  {print Err("Error 2"); print_r($rs->fields);};
-
-		$rs->MoveNext();
-		if ($rs->fields[$id] != 2)  {Err("Error 3"); print_r($rs->fields);};
-		$rs->MoveNext();
-		if (!$rs->EOF) {
-			Err("Error EOF");
-			print_r($rs);
-		}
-	}
-
-	print "<p>FETCH_MODE = ASSOC: Should get 1, Caroline ASSOC_CASE=".ADODB_ASSOC_CASE."</p>";
-	$rs = $db->SelectLimit('select id,firstname from ADOXYZ order by id',2);
-	if ($rs && !$rs->EOF) {
-
-		if ($rs->fields[$id] != 1)  {Err("Error 1"); print_r($rs->fields);};
-		if (trim($rs->fields[$fname]) != 'Caroline')  {Err("Error 2"); print_r($rs->fields);};
-		$rs->MoveNext();
-		if ($rs->fields[$id] != 2)  {Err("Error 3"); print_r($rs->fields);};
-		$rs->MoveNext();
-		if (!$rs->EOF) Err("Error EOF");
-		else if (is_array($rs->fields) || $rs->fields) {
-			Err("Error: ## fields should be set to false on EOF");
-			print_r($rs->fields);
-		}
-	}
-
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-	print "<p>FETCH_MODE = NUM: Should get 1, Caroline</p>";
-	$rs = $db->SelectLimit('select id,firstname from ADOXYZ order by id',1);
-	if ($rs && !$rs->EOF) {
-		if (isset($rs->fields[$id])) Err("FETCH_NUM has ASSOC fields");
-		if ($rs->fields[0] != 1)  {Err("Error 1"); print_r($rs->fields);};
-		if (trim($rs->fields[1]) != 'Caroline')  {Err("Error 2");print_r($rs->fields);};
-		$rs->MoveNext();
-		if (!$rs->EOF) Err("Error EOF");
-
-	}
-	$ADODB_FETCH_MODE = $savefetch;
-
-	$db->debug = false;
-	print "<p>GetRowAssoc Upper: Should get 1, Caroline</p>";
-	$rs = $db->SelectLimit('select id,firstname from ADOXYZ order by id',1);
-	if ($rs && !$rs->EOF) {
-		$arr = $rs->GetRowAssoc(ADODB_ASSOC_CASE_UPPER);
-
-		if ($arr[strtoupper($id)] != 1) {Err("Error 1");print_r($arr);};
-		if (trim($arr[strtoupper($fname)]) != 'Caroline') {Err("Error 2"); print_r($arr);};
-		$rs->MoveNext();
-		if (!$rs->EOF) Err("Error EOF");
-
-	}
-	print "<p>GetRowAssoc Lower: Should get 1, Caroline</p>";
-	$rs = $db->SelectLimit('select id,firstname from ADOXYZ order by id',1);
-	if ($rs && !$rs->EOF) {
-		$arr = $rs->GetRowAssoc(ADODB_ASSOC_CASE_LOWER);
-		if ($arr['id'] != 1) {Err("Error 1"); print_r($arr);};
-		if (trim($arr['firstname']) != 'Caroline') {Err("Error 2"); print_r($arr);};
-
-	}
-
-	print "<p>GetCol Test</p>";
-	$col = $db->GetCol('select distinct firstname from ADOXYZ order by 1');
-	if (!is_array($col)) Err("Col size is wrong");
-	if (trim($col[0]) != 'Alan' or trim($col[9]) != 'Yat Sun') Err("Col elements wrong");
-
-
-	$col = $db->CacheGetCol('select distinct firstname from ADOXYZ order by 1');
-	if (!is_array($col)) Err("Col size is wrong");
-	if (trim($col[0]) != 'Alan' or trim($col[9]) != 'Yat Sun') Err("Col elements wrong");
-
-	$db->debug = true;
-
-
-	echo "<p>Date Update Test</p>";
-	$zdate = date('Y-m-d',time()+3600*24);
-	$zdate = $db->DBDate($zdate);
-	$db->Execute("update ADOXYZ set created=$zdate where id=1");
-	$row = $db->GetRow("select created,firstname from ADOXYZ where id=1");
-	print_r($row); echo "<br>";
-
-
-
-	print "<p>SelectLimit Distinct Test 1: Should see Caroline, John and Mary</p>";
-	$rs = $db->SelectLimit('select distinct * from ADOXYZ order by id',3);
-
-
-	if ($rs && !$rs->EOF) {
-		if (trim($rs->fields[1]) != 'Caroline') Err("Error 1 (exp Caroline), ".$rs->fields[1]);
-		$rs->MoveNext();
-
-		if (trim($rs->fields[1]) != 'John') Err("Error 2 (exp John), ".$rs->fields[1]);
-		$rs->MoveNext();
-		if (trim($rs->fields[1]) != 'Mary') Err("Error 3 (exp Mary),".$rs->fields[1]);
-		$rs->MoveNext();
-		if (! $rs->EOF) Err("Error EOF");
-		//rs2html($rs);
-	} else Err("Failed SelectLimit Test 1");
-
-	print "<p>SelectLimit Test 2: Should see Mary, George and Mr. Alan</p>";
-	$rs = $db->SelectLimit('select * from ADOXYZ order by id',3,2);
-	if ($rs && !$rs->EOF) {
-		if (trim($rs->fields[1]) != 'Mary') Err("Error 1 - No Mary, instead: ".$rs->fields[1]);
-		$rs->MoveNext();
-		if (trim($rs->fields[1]) != 'George')Err("Error 2 - No George, instead: ".$rs->fields[1]);
-		$rs->MoveNext();
-		if (trim($rs->fields[1]) != 'Mr. Alan') Err("Error 3 - No Mr. Alan, instead: ".$rs->fields[1]);
-		$rs->MoveNext();
-		if (! $rs->EOF) Err("Error EOF");
-	//	rs2html($rs);
-	}
-	 else Err("Failed SelectLimit Test 2 ". ($rs ? 'EOF':'no RS'));
-
-	print "<p>SelectLimit Test 3: Should see Wai Hun and Steven</p>";
-	$db->debug=1;
-	global $A; $A=1;
-	$rs = $db->SelectLimit('select * from ADOXYZ order by id',-1,48);
-	$A=0;
-	if ($rs && !$rs->EOF) {
-		if (empty($rs->connection)) print "<b>Connection object missing from recordset</b></br>";
-		if (trim($rs->fields[1]) != 'Wai Hun') Err("Error 1 ".$rs->fields[1]);
-		$rs->MoveNext();
-		if (trim($rs->fields[1]) != 'Steven') Err("Error 2 ".$rs->fields[1]);
-		$rs->MoveNext();
-		if (! $rs->EOF) {
-			Err("Error EOF");
-		}
-		//rs2html($rs);
-	}
-	 else Err("Failed SelectLimit Test 3");
-		$db->debug = false;
-
-
-	$rs = $db->Execute("select * from ADOXYZ order by id");
-	print "<p>Testing Move()</p>";
-	if (!$rs)Err( "Failed Move SELECT");
-	else {
-		if (!$rs->Move(2)) {
-			if (!$rs->canSeek) print "<p>$db->databaseType: <b>Move(), MoveFirst() nor MoveLast() not supported.</b></p>";
-			else print '<p><b>RecordSet->canSeek property should be set to false</b></p>';
-		} else {
-			$rs->MoveFirst();
-			if (trim($rs->Fields("firstname")) != 'Caroline') {
-				print "<p><b>$db->databaseType: MoveFirst failed -- probably cannot scroll backwards</b></p>";
-			}
-			else print "MoveFirst() OK<BR>";
-
-						// Move(3) tests error handling -- MoveFirst should not move cursor
-			$rs->Move(3);
-			if (trim($rs->Fields("firstname")) != 'George') {
-				print '<p>'.$rs->Fields("id")."<b>$db->databaseType: Move(3) failed</b></p>";
-			} else print "Move(3) OK<BR>";
-
-			$rs->Move(7);
-			if (trim($rs->Fields("firstname")) != 'Yat Sun') {
-				print '<p>'.$rs->Fields("id")."<b>$db->databaseType: Move(7) failed</b></p>";
-				print_r($rs);
-			} else print "Move(7) OK<BR>";
-			if ($rs->EOF) Err("Move(7) is EOF already");
-			$rs->MoveLast();
-			if (trim($rs->Fields("firstname")) != 'Steven'){
-				 print '<p>'.$rs->Fields("id")."<b>$db->databaseType: MoveLast() failed</b></p>";
-				 print_r($rs);
-			}else print "MoveLast() OK<BR>";
-			$rs->MoveNext();
-			if (!$rs->EOF) err("Bad MoveNext");
-			if ($rs->canSeek) {
-				$rs->Move(3);
-				if (trim($rs->Fields("firstname")) != 'George') {
-					print '<p>'.$rs->Fields("id")."<b>$db->databaseType: Move(3) after MoveLast failed</b></p>";
-
-				} else print "Move(3) after MoveLast() OK<BR>";
-			}
-
-			print "<p>Empty Move Test";
-			$rs = $db->Execute("select * from ADOXYZ where id > 0 and id < 0");
-			$rs->MoveFirst();
-			if (!$rs->EOF || $rs->fields) Err("Error in empty move first");
-		}
-	}
-
-	$rs = $db->Execute('select * from ADOXYZ where id = 2');
-	if ($rs->EOF || !is_array($rs->fields)) Err("Error in select");
-	$rs->MoveNext();
-	if (!$rs->EOF) Err("Error in EOF (xx) ");
- //	$db->debug=true;
-	print "<p>Testing ADODB_FETCH_ASSOC and concat: concat firstname and lastname</p>";
-
-	$save = $ADODB_FETCH_MODE;
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	if ($db->dataProvider == 'postgres') {
-		$sql = "select ".$db->Concat('cast(firstname as varchar)',$db->qstr(' '),'lastname')." as fullname,id,".$db->sysTimeStamp." as d from ADOXYZ";
-		$rs = $db->Execute($sql);
-	} else {
-		$sql = "select distinct ".$db->Concat('firstname',$db->qstr(' '),'lastname')." as fullname,id,".$db->sysTimeStamp." as d from ADOXYZ";
-		$rs = $db->Execute($sql);
-	}
-	if ($rs) {
-		if (empty($_GET['hide'])) rs2html($rs);
-	} else {
-		Err( "Failed Concat:".$sql);
-	}
-	$ADODB_FETCH_MODE = $save;
-	print "<hr />Testing GetArray() ";
-	//$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-
-	$rs = $db->Execute("select * from ADOXYZ order by id");
-	if ($rs) {
-		$arr = $rs->GetArray(10);
-		if (sizeof($arr) != 10 || trim($arr[1][1]) != 'John' || trim($arr[1][2]) != 'Lim') print $arr[1][1].' '.$arr[1][2]."<b> &nbsp; ERROR</b><br>";
-		else print " OK<BR>";
-	}
-
-	$arr = $db->GetArray("select x from ADOXYZ");
-	$e = $db->ErrorMsg(); $e2 = $db->ErrorNo();
-	echo "Testing error handling, should see illegal column 'x' error=<i>$e ($e2) </i><br>";
-	if (!$e || !$e2) Err("Error handling did not work");
-	print "Testing FetchNextObject for 1 object ";
-	$rs = $db->Execute("select distinct lastname,firstname from ADOXYZ where firstname='Caroline'");
-	$fcnt = 0;
-	if ($rs)
-	while ($o = $rs->FetchNextObject()) {
-		$fcnt += 1;
-	}
-	if ($fcnt == 1) print " OK<BR>";
-	else print "<b>FAILED</b><BR>";
-
-	$stmt = $db->Prepare("select * from ADOXYZ where id < 3");
-	$rs = $db->Execute($stmt);
-	if (!$rs) Err("Prepare failed");
-	else {
-		$arr = $rs->GetArray();
-		if (!$arr) Err("Prepare failed 2");
-		if (sizeof($arr) != 2) Err("Prepare failed 3");
-	}
-	print "Testing GetAssoc() ";
-
-
-	if ($db->dataProvider == 'mysql') {
-		$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-		$arr = $db->GetAssoc("SELECT 'adodb', '0'");
-		var_dump($arr);
-		die();
-	}
-
-	$savecrecs = $ADODB_COUNTRECS;
-	$ADODB_COUNTRECS = false;
-	//$arr = $db->GetArray("select  lastname,firstname from ADOXYZ");
-	//print_r($arr);
-	print "<hr />";
-	$rs = $db->Execute("select distinct lastname,firstname,created from ADOXYZ");
-
-	if ($rs) {
-		$arr = $rs->GetAssoc();
-		//print_r($arr);
-		if (empty($arr['See']) || trim(reset($arr['See'])) != 'Wai Hun') print $arr['See']." &nbsp; <b>ERROR</b><br>";
-		else print " OK 1";
-	}
-
-	$arr = $db->GetAssoc("select distinct lastname,firstname from ADOXYZ");
-	if ($arr) {
-		//print_r($arr);
-		if (empty($arr['See']) || trim($arr['See']) != 'Wai Hun') print $arr['See']." &nbsp; <b>ERROR</b><br>";
-		else print " OK 2<BR>";
-	}
-	// Comment this out to test countrecs = false
-	$ADODB_COUNTRECS = $savecrecs;
-	$db->debug=1;
-	$query = $db->Prepare("select count(*) from ADOXYZ");
-	$rs = $db->CacheExecute(10,$query);
-	if (reset($rs->fields) != 50) echo Err("$cnt wrong for Prepare/CacheGetOne");
-
-	for ($loop=0; $loop < 1; $loop++) {
-	print "Testing GetMenu() and CacheExecute<BR>";
-	$db->debug = true;
-	$rs = $db->CacheExecute(4,"select distinct firstname,lastname from ADOXYZ");
-
-
-
-
-	if ($rs) print 'With blanks, Steven selected:'. $rs->GetMenu('menu','Steven').'<BR>';
-	else print " Fail<BR>";
-	$rs = $db->CacheExecute(4,"select distinct firstname,lastname from ADOXYZ");
-
-	if ($rs) print ' No blanks, Steven selected: '. $rs->GetMenu('menu','Steven',false).'<BR>';
-	else print " Fail<BR>";
-
-	$rs = $db->CacheExecute(4,"select distinct firstname,lastname from ADOXYZ");
-
-	if ($rs) print ' 1st line set to **** , Steven selected: '. $rs->GetMenu('menu','Steven','1st:****').'<BR>';
-	else print " Fail<BR>";
-
-
-
-	$rs = $db->CacheExecute(4,"select distinct firstname,lastname from ADOXYZ");
-	if ($rs) print ' Multiple, Alan selected: '. $rs->GetMenu('menu','Alan',false,true).'<BR>';
-	else print " Fail<BR>";
-	print '</p><hr />';
-
-	$rs = $db->CacheExecute(4,"select distinct firstname,lastname from ADOXYZ");
-	if ($rs) {
-		print ' Multiple, Alan and George selected: '. $rs->GetMenu('menu',array('Alan','George'),false,true);
-		if (empty($rs->connection)) print "<b>Connection object missing from recordset</b></br>";
-	} else print " Fail<BR>";
-	print '</p><hr />';
-
-	print "Testing GetMenu3()<br>";
-	$rs = $db->Execute("select ".$db->Concat('firstname',"'-'",'id').",id, lastname from ADOXYZ order by lastname,id");
-	if ($rs) print "Grouped Menu: ".$rs->GetMenu3('name');
-	else Err('Grouped Menu GetMenu3()');
-	print "<hr />";
-
-	print "Testing GetMenu2() <BR>";
-	$rs = $db->CacheExecute(4,"select distinct firstname,lastname from ADOXYZ");
-	if ($rs) print 'With blanks, Steven selected:'. $rs->GetMenu2('menu',('Oey')).'<BR>';
-	else print " Fail<BR>";
-	$rs = $db->CacheExecute(6,"select distinct firstname,lastname from ADOXYZ");
-	if ($rs) print ' No blanks, Steven selected: '. $rs->GetMenu2('menu',('Oey'),false).'<BR>';
-	else print " Fail<BR>";
-	}
-	echo "<h3>CacheExecute</h3>";
-
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-	$rs = $db->CacheExecute(6,"select distinct firstname,lastname from ADOXYZ");
-	print_r($rs->fields); echo $rs->fetchMode;echo "<br>";
-	echo $rs->Fields($fname);
-
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$rs = $db->CacheExecute(6,"select distinct firstname,lastname from ADOXYZ");
-	print_r($rs->fields);echo "<br>";
-	echo $rs->Fields($fname);
-	$db->debug = false;
-
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-	// phplens
-
-	$sql = 'select * from ADOXYZ where 0=1';
-	echo "<p>**Testing '$sql' (phplens compat 1)</p>";
-	$rs = $db->Execute($sql);
-	if (!$rs) err( "<b>No recordset returned for '$sql'</b>");
-	if (!$rs->FieldCount()) err( "<b>No fields returned for $sql</b>");
-	if (!$rs->FetchField(1)) err( "<b>FetchField failed for $sql</b>");
-
-	$sql = 'select * from ADOXYZ order by 1';
-	echo "<p>**Testing '$sql' (phplens compat 2)</p>";
-	$rs = $db->Execute($sql);
-	if (!$rs) err( "<b>No recordset returned for '$sql'<br>".$db->ErrorMsg()."</b>");
-
-
-	$sql = 'select * from ADOXYZ order by 1,1';
-	echo "<p>**Testing '$sql' (phplens compat 3)</p>";
-	$rs = $db->Execute($sql);
-	if (!$rs) err( "<b>No recordset returned for '$sql'<br>".$db->ErrorMsg()."</b>");
-
-
-	// Move
-	$rs1 = $db->Execute("select id from ADOXYZ where id <= 2 order by 1");
-	$rs2 = $db->Execute("select id from ADOXYZ where id = 3 or id = 4 order by 1");
-
-	if ($rs1) $rs1->MoveLast();
-	if ($rs2) $rs2->MoveLast();
-
-	if (empty($rs1) || empty($rs2) || $rs1->fields[0] != 2 || $rs2->fields[0] != 4) {
-		$a = $rs1->fields[0];
-		$b = $rs2->fields[0];
-		print "<p><b>Error in multiple recordset test rs1=$a rs2=$b (should be rs1=2 rs2=4)</b></p>";
-	} else
-		print "<p>Testing multiple recordsets OK</p>";
-
-
-	echo "<p> GenID test: ";
-	for ($i=1; $i <= 10; $i++)
-		echo  "($i: ",$val = $db->GenID($db->databaseType.'abcseq7' ,5), ") ";
-	if ($val == 0) Err("GenID not supported");
-
-	if ($val) {
-		$db->DropSequence('abc_seq2');
-		$db->CreateSequence('abc_seq2');
-		$val = $db->GenID('abc_seq2');
-		$db->DropSequence('abc_seq2');
-		$db->CreateSequence('abc_seq2');
-		$val = $db->GenID('abc_seq2');
-		if ($val != 1) Err("Drop and Create Sequence not supported ($val)");
-	}
-	echo "<p>";
-
-	if (substr($db->dataProvider,0,3) != 'notused') { // used to crash ado
-		$sql = "select firstnames from ADOXYZ";
-		print "<p>Testing execution of illegal statement: <i>$sql</i></p>";
-		if ($db->Execute($sql) === false) {
-			print "<p>This returns the following ErrorMsg(): <i>".$db->ErrorMsg()."</i> and ErrorNo(): ".$db->ErrorNo().'</p>';
-		} else
-			print "<p><b>Error in error handling -- Execute() should return false</b></p>";
-	} else
-		print "<p><b>ADO skipped error handling of bad select statement</b></p>";
-
-	print "<p>ASSOC TEST 2<br>";
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$rs = $db->query('select * from ADOXYZ order by id');
-	if ($ee = $db->ErrorMsg()) {
-		Err("Error message=$ee");
-	}
-	if ($ee = $db->ErrorNo()) {
-		Err("Error No = $ee");
-	}
-	print_r($rs->fields);
-	for($i=0;$i<$rs->FieldCount();$i++)
-	{
-		$fld=$rs->FetchField($i);
-		print "<br> Field name is ".$fld->name;
-		print " ".$rs->Fields($fld->name);
-	}
-
-
-	print "<p>BOTH TEST 2<br>";
-	if ($db->dataProvider == 'ado') {
-		print "<b>ADODB_FETCH_BOTH not supported</b> for dataProvider=".$db->dataProvider."<br>";
-	} else {
-		$ADODB_FETCH_MODE = ADODB_FETCH_BOTH;
-		$rs = $db->query('select * from ADOXYZ order by id');
-		for($i=0;$i<$rs->FieldCount();$i++)
-		{
-			$fld=$rs->FetchField($i);
-			print "<br> Field name is ".$fld->name;
-			print " ".$rs->Fields($fld->name);
-		}
-	}
-
-	print "<p>NUM TEST 2<br>";
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-	$rs = $db->query('select * from ADOXYZ order by id');
-	for($i=0;$i<$rs->FieldCount();$i++)
-	{
-		$fld=$rs->FetchField($i);
-		print "<br> Field name is ".$fld->name;
-		print " ".$rs->Fields($fld->name);
-	}
-
-	print "<p>ASSOC Test of SelectLimit<br>";
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$rs = $db->selectlimit('select * from ADOXYZ order by id',3,4);
-	$cnt = 0;
-	while ($rs && !$rs->EOF) {
-		$cnt += 1;
-		if (!isset($rs->fields['firstname'])) {
-			print "<br><b>ASSOC returned numeric field</b></p>";
-			break;
-		}
-		$rs->MoveNext();
-	}
-	if ($cnt != 3) print "<br><b>Count should be 3, instead it was $cnt</b></p>";
-
-
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-	if ($db->sysDate) {
-		$saved = $db->debug;
-		$db->debug = 1;
-		$rs = $db->Execute("select {$db->sysDate} from ADOXYZ where id=1");
-		if (ADORecordSet::UnixDate(date('Y-m-d')) != $rs->UnixDate($rs->fields[0])) {
-			print "<p><b>Invalid date {$rs->fields[0]}</b></p>";
-		} else
-			print "<p>Passed \$sysDate test ({$rs->fields[0]})</p>";
-
-		print_r($rs->FetchField(0));
-		print time();
-		$db->debug=$saved;
-	} else {
-		print "<p><b>\$db->sysDate not defined</b></p>";
-	}
-
-	print "<p>Test CSV</p>";
-	include_once('../toexport.inc.php');
-	//$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$rs = $db->SelectLimit('select id,firstname,lastname,created,\'He, he\' he,\'"\' q  from ADOXYZ',10);
-
-	print "<pre>";
-	print rs2csv($rs);
-	print "</pre>";
-
-	$rs = $db->SelectLimit('select id,firstname,lastname,created,\'The	"young man", he said\' from ADOXYZ',10);
-
-	if (PHP_VERSION < 5) {
-		print "<pre>";
-		rs2tabout($rs);
-		print "</pre>";
-	}
-	#print " CacheFlush ";
-	#$db->CacheFlush();
-
-	$date = $db->SQLDate('d-m-M-Y-\QQ h:i:s A');
-	$sql = "SELECT $date from ADOXYZ";
-	print "<p>Test SQLDate: ".htmlspecialchars($sql)."</p>";
-	$rs = $db->SelectLimit($sql,1);
-	$d = date('d-m-M-Y-').'Q'.(ceil(date('m')/3.0)).date(' h:i:s A');
-	if (!$rs) Err("SQLDate query returned no recordset");
-	else if ($d != $rs->fields[0]) Err("SQLDate 1 failed expected: <br>act:$d <br>sql:".$rs->fields[0]);
-
-	$dbdate = $db->DBDate("1974-02-25");
-	if (substr($db->dataProvider, 0, 8) == 'postgres') {
-		$dbdate .= "::TIMESTAMP";
-	}
-
-	$date = $db->SQLDate('d-m-M-Y-\QQ h:i:s A', $dbdate);
-	$sql = "SELECT $date from ADOXYZ";
-	print "<p>Test SQLDate: ".htmlspecialchars($sql)."</p>";
-	$db->debug=1;
-	$rs = $db->SelectLimit($sql,1);
-	$ts = ADOConnection::UnixDate('1974-02-25');
-	$d = date('d-m-M-Y-',$ts).'Q'.(ceil(date('m',$ts)/3.0)).date(' h:i:s A',$ts);
-	if (!$rs) {
-		Err("SQLDate query returned no recordset");
-		echo $db->ErrorMsg(),'<br>';
-	} else if ($d != reset($rs->fields)) {
-		Err("SQLDate 2 failed expected: <br>act:$d <br>sql:".$rs->fields[0].' <br>'.$db->ErrorMsg());
-	}
-
-
-	print "<p>Test Filter</p>";
-	$db->debug = 1;
-
-	$rs = $db->SelectLimit('select * from ADOXYZ where id < 3 order by id');
-
-	$rs = RSFilter($rs,'do_strtolower');
-	if (trim($rs->fields[1]) != 'caroline'  && trim($rs->fields[2]) != 'miranda') {
-		err('**** RSFilter failed');
-		print_r($rs->fields);
-	}
-
-	rs2html($rs);
-
-	$db->debug=1;
-
-
-	print "<p>Test Replace</p>";
-
-	$ret = $db->Replace('ADOXYZ',
-		array('id'=>1,'firstname'=>'Caroline','lastname'=>'Miranda'),
-		array('id'),
-		$autoq = true);
-	if (!$ret) echo "<p>Error in replacing existing record</p>";
-	else {
-		$saved = $db->debug;
-		$db->debug = 0;
-		$savec = $ADODB_COUNTRECS;
-		$ADODB_COUNTRECS = true;
-		$rs = $db->Execute('select * FROM ADOXYZ where id=1');
-		$db->debug = $saved;
-		if ($rs->RecordCount() != 1) {
-			$cnt = $rs->RecordCount();
-			rs2html($rs);
-			print "<b>Error - Replace failed, count=$cnt</b><p>";
-		}
-		$ADODB_COUNTRECS = $savec;
-	}
-	$ret = $db->Replace('ADOXYZ',
-		array('id'=>1000,'firstname'=>'Harun','lastname'=>'Al-Rashid'),
-		array('id','firstname'),
-		$autoq = true);
-	if ($ret != 2) print "<b>Replace failed: </b>";
-	print "test A return value=$ret (2 expected) <p>";
-
-	$ret = $db->Replace('ADOXYZ',
-		array('id'=>1000,'firstname'=>'Sherazade','lastname'=>'Al-Rashid'),
-		'id',
-		$autoq = true);
-	if ($ret != 1)
-		if ($db->dataProvider == 'ibase' && $ret == 2);
-		else print "<b>Replace failed: </b>";
-	print "test B return value=$ret (1 or if ibase then 2 expected) <p>";
-
-	print "<h3>rs2rs Test</h3>";
-
-	$rs = $db->Execute('select * from ADOXYZ where id>= 1 order by id');
-	$rs = $db->_rs2rs($rs);
-	$rs->valueX = 'X';
-	$rs->MoveNext();
-	$rs = $db->_rs2rs($rs);
-	if (!isset($rs->valueX)) err("rs2rs does not preserve array recordsets");
-	if (reset($rs->fields) != 1) err("rs2rs does not move to first row: id=".reset($rs->fields));
-
-	/////////////////////////////////////////////////////////////
-	include_once('../pivottable.inc.php');
-	print "<h3>Pivot Test</h3>";
-	$db->debug=true;
- 	$sql = PivotTableSQL(
- 		$db,  			# adodb connection
- 		'ADOXYZ',  		# tables
-		'firstname',	# row fields
-		'lastname',		# column fields
-		false,			# join
-		'ID', 			# sum
-		'Sum ',			# label for sum
-		'sum',			# aggregate function
-		true
-	);
-	$rs = $db->Execute($sql);
-	if ($rs) rs2html($rs);
-	else Err("Pivot sql error");
-
-	$pear = false; //true;
-	$db->debug=false;
-
-	if ($pear) {
-	// PEAR TESTS BELOW
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-
-	include_once "PEAR.php";
-	$rs = $db->query('select * from ADOXYZ where id>0 and id<10 order by id');
-
-	$i = 0;
-	if ($rs && !$rs->EOF) {
-		while ($arr = $rs->fetchRow()) {
-			$i++;
-			//print "$i ";
-			if ($arr[0] != $i) {
-				print_r($arr);
-				print "<p><b>PEAR DB emulation error 1.</b></p>";
-				$pear = false;
-				break;
-			}
-		}
-		$rs->Close();
-	}
-
-
-	if ($i != $db->GetOne('select count(*) from ADOXYZ where id>0 and id<10')) {
-		print "<p><b>PEAR DB emulation error 1.1 EOF ($i)</b></p>";
-		$pear = false;
-	}
-
-	$rs = $db->limitQuery('select * from ADOXYZ where id>0 order by id',$i=3,$top=3);
-	$i2 = $i;
-	if ($rs && !$rs->EOF) {
-
-		while (!is_object($rs->fetchInto($arr))) {
-			$i2++;
-
-	//			print_r($arr);
-	//		print "$i ";print_r($arr);
-			if ($arr[0] != $i2) {
-				print "<p><b>PEAR DB emulation error 2.</b></p>";
-				$pear = false;
-				break;
-			}
-		}
-		$rs->Close();
-	}
-	if ($i2 != $i+$top) {
-		print "<p><b>PEAR DB emulation error 2.1 EOF (correct=$i+$top, actual=$i2)</b></p>";
-		$pear = false;
-	}
-	}
-	if ($pear) print "<p>PEAR DB emulation passed.</p>";
-	flush();
-
-
-	$rs = $db->SelectLimit("select ".$db->sysDate." from ADOXYZ",1);
-	$date = $rs->fields[0];
-	if (!$date) Err("Bad sysDate");
-	else {
-		$ds = $db->UserDate($date,"d m Y");
-		if ($ds != date("d m Y")) Err("Bad UserDate: ".$ds.' expected='.date("d m Y"));
-		else echo "Passed UserDate: $ds<p>";
-	}
-	$db->debug=1;
-	if ($db->dataProvider == 'oci8')
-		$rs = $db->SelectLimit("select to_char(".$db->sysTimeStamp.",'YYYY-MM-DD HH24:MI:SS') from ADOXYZ",1);
-	else
-		$rs = $db->SelectLimit("select ".$db->sysTimeStamp." from ADOXYZ",1);
-	$date = $rs->fields[0];
-	if (!$date) Err("Bad sysTimeStamp");
-	else {
-		$ds = $db->UserTimeStamp($date,"H \\h\\r\\s-d m Y");
-		if ($ds != date("H \\h\\r\\s-d m Y")) Err("Bad UserTimeStamp: ".$ds.", correct is ".date("H \\h\\r\\s-d m Y"));
-		else echo "Passed UserTimeStamp: $ds<p>";
-
-		$date = 100;
-		$ds = $db->UserTimeStamp($date,"H \\h\\r\\s-d m Y");
-		$ds2 = date("H \\h\\r\\s-d m Y",$date);
-		if ($ds != $ds2) Err("Bad UserTimeStamp 2: $ds: $ds2");
-		else echo "Passed UserTimeStamp 2: $ds<p>";
-	}
-	flush();
-
-	if ($db->hasTransactions) {
-		$db->debug=1;
-		echo "<p>Testing StartTrans CompleteTrans</p>";
-		$db->raiseErrorFn = false;
-
-		$db->SetTransactionMode('SERIALIZABLE');
-		$db->StartTrans();
-		$rs = $db->Execute('select * from notable');
-			$db->StartTrans();
-				$db->BeginTrans();
-			$db->Execute("update ADOXYZ set firstname='Carolx' where id=1");
-				$db->CommitTrans();
-			$db->CompleteTrans();
-		$rez = $db->CompleteTrans();
-		$db->SetTransactionMode('');
-		$db->debug=0;
-		if ($rez !== false) {
-			if (is_null($rez)) Err("Error: _transOK not modified");
-			else Err("Error: CompleteTrans (1) should have failed");
-		} else {
-			$name = $db->GetOne("Select firstname from ADOXYZ where id=1");
-			if ($name == "Carolx") Err("Error: CompleteTrans (2) should have failed");
-			else echo "<p> -- Passed StartTrans test1 - rolling back</p>";
-		}
-
-		$db->StartTrans();
-			$db->BeginTrans();
-		$db->Execute("update ADOXYZ set firstname='Carolx' where id=1");
-			$db->RollbackTrans();
-		$rez = $db->CompleteTrans();
-		if ($rez !== true) Err("Error: CompleteTrans (1) should have succeeded");
-		else {
-			$name = $db->GetOne("Select firstname from ADOXYZ where id=1");
-			if (trim($name) != "Carolx") Err("Error: CompleteTrans (2) should have succeeded, returned name=$name");
-			else echo "<p> -- Passed StartTrans test2 - commiting</p>";
-		}
-	}
-	flush();
-	$saved = $db->debug;
-	$db->debug=1;
-	$cnt = _adodb_getcount($db, 'select * from ADOXYZ where firstname in (select firstname from ADOXYZ)');
-	echo "<b>Count=</b> $cnt";
-	$db->debug=$saved;
-
-	global $TESTERRS;
-	$debugerr = true;
-
-	global $ADODB_LANG;$ADODB_LANG = 'fr';
-	$db->debug = false;
-	$TESTERRS = 0;
-	$db->raiseErrorFn = 'adodb_test_err';
-	global $ERRNO; // from adodb_test_err
-	$db->Execute('select * from nowhere');
-	$metae = $db->MetaError($ERRNO);
-	if ($metae !== DB_ERROR_NOSUCHTABLE) print "<p><b>MetaError=".$metae." wrong</b>, should be ".DB_ERROR_NOSUCHTABLE."</p>";
-	else print "<p>MetaError ok (".DB_ERROR_NOSUCHTABLE."): ".$db->MetaErrorMsg($metae)."</p>";
-	if ($TESTERRS != 1) print "<b>raiseErrorFn select nowhere failed</b><br>";
-	$rs = $db->Execute('select * from ADOXYZ');
-	if ($debugerr) print " Move";
-	$rs->Move(100);
-	$rs->_queryID = false;
-	if ($debugerr) print " MoveNext";
-	$rs->MoveNext();
-	if ($debugerr) print " $rs=false";
-	$rs = false;
-
-	flush();
-
-	print "<p>SetFetchMode() tests</p>";
-	$db->SetFetchMode(ADODB_FETCH_ASSOC);
-	$rs = $db->SelectLimit('select firstname from ADOXYZ',1);
-	if (!isset($rs->fields['firstname'])) Err("BAD FETCH ASSOC");
-
-	$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-	$rs = $db->SelectLimit('select firstname from ADOXYZ',1);
-	//var_dump($rs->fields);
-	if (!isset($rs->fields['firstname'])) Err("BAD FETCH ASSOC");
-
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$db->SetFetchMode(ADODB_FETCH_NUM);
-	$rs = $db->SelectLimit('select firstname from ADOXYZ',1);
-	if (!isset($rs->fields[0])) Err("BAD FETCH NUM");
-
-	flush();
-
-	print "<p>Test MetaTables again with SetFetchMode()</p>";
-	$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-	$db->SetFetchMode(ADODB_FETCH_ASSOC);
-	print_r($db->MetaTables());
-	print "<p>";
-
-	////////////////////////////////////////////////////////////////////
-
-	print "<p>Testing Bad Connection</p>";
-	flush();
-
-	if (true || PHP_VERSION < 5)  {
-		if ($db->dataProvider == 'odbtp') $db->databaseType = 'odbtp';
-		$conn = NewADOConnection($db->databaseType);
-		$conn->raiseErrorFn = 'adodb_test_err';
-		if (1) $conn->PConnect('abc','baduser','badpassword');
-		if ($TESTERRS == 2) print "raiseErrorFn tests passed<br>";
-		else print "<b>raiseErrorFn tests failed ($TESTERRS)</b><br>";
-
-		flush();
-	}
-	////////////////////////////////////////////////////////////////////
-
-	global $nocountrecs;
-
-	if (isset($nocountrecs) && $ADODB_COUNTRECS) err("Error: \$ADODB_COUNTRECS is set");
-	if (empty($nocountrecs) && $ADODB_COUNTRECS==false) err("Error: \$ADODB_COUNTRECS is not set");
-
-	flush();
-?>
-	</p>
-	<table width=100% ><tr><td bgcolor=beige>&nbsp;</td></tr></table>
-	</p></form>
-<?php
-
-	if ($rs1) $rs1->Close();
-	if ($rs2) $rs2->Close();
-	if ($rs) $rs->Close();
-	$db->Close();
-
-	if ($db->transCnt != 0) Err("Error in transCnt=$db->transCnt (should be 0)");
-
-
-	printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$CACHED, $CACHED);
-	flush();
-}
-
-function adodb_test_err($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false)
-{
-global $TESTERRS,$ERRNO;
-
-	$ERRNO = $errno;
-	$TESTERRS += 1;
-	print "<i>** $dbms ($fn): errno=$errno &nbsp; errmsg=$errmsg ($p1,$p2)</i><br>";
-}
-
-//--------------------------------------------------------------------------------------
-
-
-@set_time_limit(240); // increase timeout
-
-include("../tohtml.inc.php");
-include("../adodb.inc.php");
-include("../rsfilter.inc.php");
-
-/* White Space Check */
-
-if (isset($_SERVER['argv'][1])) {
-	//print_r($_SERVER['argv']);
-	$_GET[$_SERVER['argv'][1]] = 1;
-}
-
-if (@$_SERVER['COMPUTERNAME'] == 'TIGRESS') {
-	CheckWS('mysqlt');
-	CheckWS('postgres');
-	CheckWS('oci8po');
-
-	CheckWS('firebird');
-	CheckWS('sybase');
-	if (!ini_get('safe_mode')) CheckWS('informix');
-
-	CheckWS('ado_mssql');
-	CheckWS('ado_access');
-	CheckWS('mssql');
-
-	CheckWS('vfp');
-	CheckWS('sqlanywhere');
-	CheckWS('db2');
-	CheckWS('access');
-	CheckWS('odbc_mssql');
-	CheckWS('firebird15');
-	//
-	CheckWS('oracle');
-	CheckWS('proxy');
-	CheckWS('fbsql');
-	print "White Space Check complete<p>";
-}
-if (sizeof($_GET) == 0) $testmysql = true;
-
-
-foreach($_GET as $k=>$v)  {
-	// XSS protection (see Github issue #274) - only set variables for
-	// expected get parameters used in testdatabases.inc.php
-	if(preg_match('/^(test|no)\w+$/', $k)) {
-		$$k = $v;
-	}
-}
-
-?>
-<html>
-<title>ADODB Testing</title>
-<body bgcolor=white>
-<H1>ADODB Test</H1>
-
-This script tests the following databases: Interbase, Oracle, Visual FoxPro, Microsoft Access (ODBC and ADO), MySQL, MSSQL (ODBC, native, ADO).
-There is also support for Sybase, PostgreSQL.</p>
-For the latest version of ADODB, visit <a href=http://adodb.org//>adodb.org</a>.</p>
-
-Test <a href=test4.php>GetInsertSQL/GetUpdateSQL</a> &nbsp;
-	<a href=testsessions.php>Sessions</a> &nbsp;
-	<a href=testpaging.php>Paging</a> &nbsp;
-	<a href=test-perf.php>Perf Monitor</a><p>
-<?php
-
-
-include_once('../adodb-time.inc.php');
-if (isset($_GET['time'])) adodb_date_test();
-flush();
-
-include_once('./testdatabases.inc.php');
-
-echo "<br>vers=",ADOConnection::Version();
-
-
-
-?>
-<p><i>ADODB Database Library  (c) 2000-2014 John Lim. All rights reserved. Released under BSD and LGPL, PHP <?php echo PHP_VERSION ?>.</i></p>
-</body>
-</html>
diff --git tests/test2.php tests/test2.php
deleted file mode 100644
index eb3b0258..00000000
--- tests/test2.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-// BASIC ADO test
-
-	include_once('../adodb.inc.php');
-
-	$db = ADONewConnection("ado_access");
-	$db->debug=1;
-	$access = 'd:\inetpub\wwwroot\php\NWIND.MDB';
-	$myDSN =  'PROVIDER=Microsoft.Jet.OLEDB.4.0;'
-		. 'DATA SOURCE=' . $access . ';';
-
-	echo "<p>PHP ",PHP_VERSION,"</p>";
-
-	$db->Connect($myDSN) || die('fail');
-
-	print_r($db->ServerInfo());
-
-	try {
-	$rs = $db->Execute("select $db->sysTimeStamp,* from adoxyz where id>02xx");
-	print_r($rs->fields);
-	} catch(exception $e) {
-	print_r($e);
-	echo "<p> Date m/d/Y =",$db->UserDate($rs->fields[4],'m/d/Y');
-	}
diff --git tests/test3.php tests/test3.php
deleted file mode 100644
index 1497f98a..00000000
--- tests/test3.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/*
-  @version   v5.20.18  28-Jun-2020
-  @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-  @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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.
- */
-
-
-error_reporting(E_ALL);
-
-$path = dirname(__FILE__);
-
-include("$path/../adodb-exceptions.inc.php");
-include("$path/../adodb.inc.php");
-
-try {
-$db = NewADOConnection("oci8");
-$db->Connect('','scott','natsoft');
-$db->debug=1;
-
-$cnt = $db->GetOne("select count(*) from adoxyz");
-$rs = $db->Execute("select * from adoxyz order by id");
-
-$i = 0;
-foreach($rs as $k => $v) {
-	$i += 1;
-	echo $k; adodb_pr($v);
-	flush();
-}
-
-if ($i != $cnt) die("actual cnt is $i, cnt should be $cnt\n");
-
-
-
-$rs = $db->Execute("select bad from badder");
-
-} catch (exception $e) {
-	adodb_pr($e);
-	$e = adodb_backtrace($e->trace);
-}
diff --git tests/test4.php tests/test4.php
deleted file mode 100644
index d7c76e2c..00000000
--- tests/test4.php
+++ /dev/null
@@ -1,144 +0,0 @@
-<?php
-
-/**
- * @version   v5.20.18  28-Jun-2020
- * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
- * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
- * 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 4 for best viewing.
- *
- * Latest version is available at http://adodb.org/
- *
- * Test GetUpdateSQL and GetInsertSQL.
- */
-
-error_reporting(E_ALL);
-function testsql()
-{
-
-
-include('../adodb.inc.php');
-include('../tohtml.inc.php');
-
-global $ADODB_FORCE_TYPE;
-
-
-//==========================
-// This code tests an insert
-
-$sql = "
-SELECT *
-FROM ADOXYZ WHERE id = -1";
-// Select an empty record from the database
-
-
-#$conn = ADONewConnection("mssql");  // create a connection
-#$conn->PConnect("", "sa", "natsoft", "northwind"); // connect to MySQL, testdb
-
-$conn = ADONewConnection("mysql");  // create a connection
-$conn->PConnect("localhost", "root", "", "test"); // connect to MySQL, testdb
-
-
-#$conn = ADONewConnection('oci8po');
-#$conn->Connect('','scott','natsoft');
-
-if (PHP_VERSION  >= 5) {
-	$connstr = "mysql:dbname=northwind";
-	$u = 'root';$p='';
-	$conn = ADONewConnection('pdo');
-	$conn->Connect($connstr, $u, $p);
-}
-//$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-
-
-$conn->debug=1;
-$conn->Execute("delete from adoxyz where lastname like 'Smi%'");
-
-$rs = $conn->Execute($sql); // Execute the query and get the empty recordset
-$record = array(); // Initialize an array to hold the record data to insert
-
-if (strpos($conn->databaseType,'mysql')===false) $record['id'] = 751;
-$record["firstname"] = 'Jann';
-$record["lastname"] = "Smitts";
-$record["created"] = time();
-
-$insertSQL = $conn->GetInsertSQL($rs, $record);
-$conn->Execute($insertSQL); // Insert the record into the database
-
-if (strpos($conn->databaseType,'mysql')===false) $record['id'] = 752;
-// Set the values for the fields in the record
-$record["firstname"] = 'anull';
-$record["lastname"] = "Smith\$@//";
-$record["created"] = time();
-
-if (isset($_GET['f'])) $ADODB_FORCE_TYPE = $_GET['f'];
-
-//$record["id"] = -1;
-
-// Pass the empty recordset and the array containing the data to insert
-// into the GetInsertSQL function. The function will process the data and return
-// a fully formatted insert sql statement.
-$insertSQL = $conn->GetInsertSQL($rs, $record);
-$conn->Execute($insertSQL); // Insert the record into the database
-
-
-
-$insertSQL2 = $conn->GetInsertSQL($table='ADOXYZ', $record);
-if ($insertSQL != $insertSQL2) echo "<p><b>Walt's new stuff failed</b>: $insertSQL2</p>";
-//==========================
-// This code tests an update
-
-$sql = "
-SELECT *
-FROM ADOXYZ WHERE lastname=".$conn->Param('var'). " ORDER BY 1";
-// Select a record to update
-
-$varr = array('var'=>$record['lastname'].'');
-$rs = $conn->Execute($sql,$varr); // Execute the query and get the existing record to update
-if (!$rs || $rs->EOF) print "<p><b>No record found!</b></p>";
-
-$record = array(); // Initialize an array to hold the record data to update
-
-
-// Set the values for the fields in the record
-$record["firstName"] = "Caroline".rand();
-//$record["lasTname"] = ""; // Update Caroline's lastname from Miranda to Smith
-$record["creAted"] = '2002-12-'.(rand()%30+1);
-$record['num'] = '';
-// Pass the single record recordset and the array containing the data to update
-// into the GetUpdateSQL function. The function will process the data and return
-// a fully formatted update sql statement.
-// If the data has not changed, no recordset is returned
-
-$updateSQL = $conn->GetUpdateSQL($rs, $record);
-$conn->Execute($updateSQL,$varr); // Update the record in the database
-if ($conn->Affected_Rows() != 1)print "<p><b>Error1 </b>: Rows Affected=".$conn->Affected_Rows().", should be 1</p>";
-
-$record["firstName"] = "Caroline".rand();
-$record["lasTname"] = "Smithy Jones"; // Update Caroline's lastname from Miranda to Smith
-$record["creAted"] = '2002-12-'.(rand()%30+1);
-$record['num'] = 331;
-$updateSQL = $conn->GetUpdateSQL($rs, $record);
-$conn->Execute($updateSQL,$varr); // Update the record in the database
-if ($conn->Affected_Rows() != 1)print "<p><b>Error 2</b>: Rows Affected=".$conn->Affected_Rows().", should be 1</p>";
-
-$rs = $conn->Execute("select * from ADOXYZ where lastname like 'Sm%'");
-//adodb_pr($rs);
-rs2html($rs);
-
-$record["firstName"] = "Carol-new-".rand();
-$record["lasTname"] = "Smithy"; // Update Caroline's lastname from Miranda to Smith
-$record["creAted"] = '2002-12-'.(rand()%30+1);
-$record['num'] = 331;
-
-$conn->AutoExecute('ADOXYZ',$record,'UPDATE', "lastname like 'Sm%'");
-$rs = $conn->Execute("select * from ADOXYZ where lastname like 'Sm%'");
-//adodb_pr($rs);
-rs2html($rs);
-}
-
-
-testsql();
diff --git tests/test5.php tests/test5.php
deleted file mode 100644
index e0597690..00000000
--- tests/test5.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-
-
-// Select an empty record from the database
-
-include('../adodb.inc.php');
-include('../tohtml.inc.php');
-
-include('../adodb-errorpear.inc.php');
-
-if (0) {
-	$conn = ADONewConnection('mysql');
-	$conn->debug=1;
-	$conn->PConnect("localhost","root","","xphplens");
-	print $conn->databaseType.':'.$conn->GenID().'<br>';
-}
-
-if (0) {
-	$conn = ADONewConnection("oci8");  // create a connection
-	$conn->debug=1;
-	$conn->PConnect("falcon", "scott", "tiger", "juris8.ecosystem.natsoft.com.my"); // connect to MySQL, testdb
-	print $conn->databaseType.':'.$conn->GenID();
-}
-
-if (0) {
-	$conn = ADONewConnection("ibase");  // create a connection
-	$conn->debug=1;
-	$conn->Connect("localhost:c:\\Interbase\\Examples\\Database\\employee.gdb", "sysdba", "masterkey", ""); // connect to MySQL, testdb
-	print $conn->databaseType.':'.$conn->GenID().'<br>';
-}
-
-if (0) {
-	$conn = ADONewConnection('postgres');
-	$conn->debug=1;
-	@$conn->PConnect("susetikus","tester","test","test");
-	print $conn->databaseType.':'.$conn->GenID().'<br>';
-}
diff --git tests/test_rs_array.php tests/test_rs_array.php
deleted file mode 100644
index 547b20ad..00000000
--- tests/test_rs_array.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-include_once('../adodb.inc.php');
-$rs = new ADORecordSet_array();
-
-$array = array(
-array ('Name', 'Age'),
-array ('John', '12'),
-array ('Jill', '8'),
-array ('Bill', '49')
-);
-
-$typearr = array('C','I');
-
-
-$rs->InitArray($array,$typearr);
-
-while (!$rs->EOF) {
-	print_r($rs->fields);echo "<br>";
-	$rs->MoveNext();
-}
-
-echo "<hr /> 1 Seek<br>";
-$rs->Move(1);
-while (!$rs->EOF) {
-	print_r($rs->fields);echo "<br>";
-	$rs->MoveNext();
-}
-
-echo "<hr /> 2 Seek<br>";
-$rs->Move(2);
-while (!$rs->EOF) {
-	print_r($rs->fields);echo "<br>";
-	$rs->MoveNext();
-}
-
-echo "<hr /> 3 Seek<br>";
-$rs->Move(3);
-while (!$rs->EOF) {
-	print_r($rs->fields);echo "<br>";
-	$rs->MoveNext();
-}
-
-
-
-die();
diff --git tests/testcache.php tests/testcache.php
deleted file mode 100644
index af3a7465..00000000
--- tests/testcache.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<html>
-<body>
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-
-$ADODB_CACHE_DIR = dirname(tempnam('/tmp',''));
-include("../adodb.inc.php");
-
-if (isset($access)) {
-	$db=ADONewConnection('access');
-	$db->PConnect('nwind');
-} else {
-	$db = ADONewConnection('mysql');
-	$db->PConnect('mangrove','root','','xphplens');
-}
-if (isset($cache)) $rs = $db->CacheExecute(120,'select * from products');
-else $rs = $db->Execute('select * from products');
-
-$arr = $rs->GetArray();
-print sizeof($arr);
diff --git tests/testdatabases.inc.php tests/testdatabases.inc.php
deleted file mode 100644
index 03e69466..00000000
--- tests/testdatabases.inc.php
+++ /dev/null
@@ -1,478 +0,0 @@
-<?php
-
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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.
-*/
-
- /* this file is used by the ADODB test program: test.php */
- ?>
-
-<table><tr valign=top><td>
-<form method=get>
-<input type=checkbox name="testaccess" value=1 <?php echo !empty($testaccess) ? 'checked' : '' ?>> <b>Access</b><br>
-<input type=checkbox name="testibase" value=1 <?php echo !empty($testibase) ? 'checked' : '' ?>> <b>Interbase</b><br>
-<input type=checkbox name="testmssql" value=1 <?php echo !empty($testmssql) ? 'checked' : '' ?>> <b>MSSQL</b><br>
-<input type=checkbox name="testmysql" value=1 <?php echo !empty($testmysql) ? 'checked' : '' ?>> <b>MySQL</b><br>
-<input type=checkbox name="testmysqlodbc" value=1 <?php echo !empty($testmysqlodbc) ? 'checked' : '' ?>> <b>MySQL ODBC</b><br>
-<input type=checkbox name="testmysqli" value=1 <?php echo !empty($testmysqli) ? 'checked' : '' ?>> <b>MySQLi</b>
-<br>
-<td><input type=checkbox name="testsqlite" value=1 <?php echo !empty($testsqlite) ? 'checked' : '' ?>> <b>SQLite</b><br>
-<input type=checkbox name="testproxy" value=1 <?php echo !empty($testproxy) ? 'checked' : '' ?>> <b>MySQL Proxy</b><br>
-<input type=checkbox name="testoracle" value=1 <?php echo !empty($testoracle) ? 'checked' : '' ?>> <b>Oracle (oci8)</b> <br>
-<input type=checkbox name="testpostgres" value=1 <?php echo !empty($testpostgres) ? 'checked' : '' ?>> <b>PostgreSQL</b><br>
-<input type=checkbox name="testpostgres9" value=1 <?php echo !empty($testpostgres9) ? 'checked' : '' ?>> <b>PostgreSQL 9</b><br>
-<input type=checkbox name="testpgodbc" value=1 <?php echo !empty($testpgodbc) ? 'checked' : '' ?>> <b>PostgreSQL ODBC</b><br>
-<td>
-<input type=checkbox name="testpdopgsql" value=1 <?php echo !empty($testpdopgsql) ? 'checked' : '' ?>> <b>PgSQL PDO</b><br>
-<input type=checkbox name="testpdomysql" value=1 <?php echo !empty($testpdomysql) ? 'checked' : '' ?>> <b>MySQL PDO</b><br>
-<input type=checkbox name="testpdosqlite" value=1 <?php echo !empty($testpdosqlite) ? 'checked' : '' ?>> <b>SQLite PDO</b><br>
-<input type=checkbox name="testpdoaccess" value=1 <?php echo !empty($testpdoaccess) ? 'checked' : '' ?>> <b>Access PDO</b><br>
-<input type=checkbox name="testpdomssql" value=1 <?php echo !empty($testpdomssql) ? 'checked' : '' ?>> <b>MSSQL PDO</b><br>
-
-<input type=checkbox name="testpdoora" value=1 <?php echo !empty($testpdoora) ? 'checked' : '' ?>> <b>OCI PDO</b><br>
-
-<td><input type=checkbox name="testdb2" value=1 <?php echo !empty($testdb2) ? 'checked' : '' ?>> DB2<br>
-<input type=checkbox name="testvfp" value=1 <?php echo !empty($testvfp) ? 'checked' : '' ?>> VFP+ODBTP<br>
-<input type=checkbox name="testado" value=1 <?php echo !empty($testado) ? 'checked' : '' ?>> ADO (for mssql and access)<br>
-<input type=checkbox name="nocountrecs" value=1 <?php echo !empty($nocountrecs) ? 'checked' : '' ?>> $ADODB_COUNTRECS=false<br>
-<input type=checkbox name="nolog" value=1 <?php echo !empty($nolog) ? 'checked' : '' ?>> No SQL Logging<br>
-<input type=checkbox name="time" value=1 <?php echo !empty($_GET['time']) ? 'checked' : '' ?>> ADOdb time test
-</table>
-<input type=submit>
-</form>
-
-<?php
-
-if ($ADODB_FETCH_MODE != ADODB_FETCH_DEFAULT) print "<h3>FETCH MODE IS NOT ADODB_FETCH_DEFAULT</h3>";
-
-if (isset($nocountrecs)) $ADODB_COUNTRECS = false;
-
-// cannot test databases below, but we include them anyway to check
-// if they parse ok...
-
-if (sizeof($_GET) || !isset($_SERVER['HTTP_HOST'])) {
-	echo "<BR>";
-	ADOLoadCode2("sybase");
-	ADOLoadCode2("postgres");
-	ADOLoadCode2("postgres7");
-	ADOLoadCode2("firebird");
-	ADOLoadCode2("borland_ibase");
-	ADOLoadCode2("informix");
-	ADOLoadCode2('mysqli');
-	if (defined('ODBC_BINMODE_RETURN')) {
-		ADOLoadCode2("sqlanywhere");
-		ADOLoadCode2("access");
-	}
-	ADOLoadCode2("mysql");
-	ADOLoadCode2("oci8");
-}
-
-function ADOLoadCode2($d)
-{
-	ADOLoadCode($d);
-	$c = ADONewConnection($d);
-	echo "Loaded $d ",($c ? 'ok' : 'extension not installed'),"<br>";
-}
-
-flush();
-
-// dregad 2014-04-15 added serial field to avoid error with lastval()
-$pg_test_table = "create table ADOXYZ (id integer, firstname char(24), lastname varchar,created date, ser serial)";
-$pg_hostname = 'localhost';
-$pg_user = 'tester';
-$pg_password = 'test';
-$pg_database = 'northwind';
-$pg_errmsg = "ERROR: PostgreSQL requires a database called '$pg_database' "
-	. "on server '$pg_hostname', user '$pg_user', password '$pg_password'.<BR>";
-
-if (!empty($testpostgres)) {
-	//ADOLoadCode("postgres");
-
-	$db = ADONewConnection('postgres');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if ($db->Connect($pg_hostname, $pg_user, $pg_password, $pg_database)) {
-		testdb($db, $pg_test_table);
-	} else {
-		print $pg_errmsg . $db->ErrorMsg();
-	}
-}
-
-if (!empty($testpostgres9)) {
-	//ADOLoadCode("postgres");
-
-	$db = ADONewConnection('postgres9');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if ($db->Connect($pg_hostname, $pg_user, $pg_password, $pg_database)) {
-		testdb($db, $pg_test_table);
-	} else {
-		print $pg_errmsg . $db->ErrorMsg();
-	}
-}
-
-if (!empty($testpgodbc)) {
-
-	$db = ADONewConnection('odbc');
-	$db->hasTransactions = false;
-	print "<h1>Connecting $db->databaseType...</h1>";
-
-	if ($db->PConnect('Postgresql')) {
-		$db->hasTransactions = true;
-		testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date) type=innodb");
-	} else print "ERROR: PostgreSQL requires a database called test on server, user tester, password test.<BR>".$db->ErrorMsg();
-}
-
-if (!empty($testibase)) {
-	//$_GET['nolog'] = true;
-	$db = ADONewConnection('firebird');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if ($db->PConnect("localhost:d:\\firebird\\151\\examples\\EMPLOYEE.fdb", "sysdba", "masterkey", ""))
-		testdb($db,"create table ADOXYZ (id integer, firstname char(24), lastname char(24),price numeric(12,2),created date)");
-	 else print "ERROR: Interbase test requires a database called employee.gdb".'<BR>'.$db->ErrorMsg();
-
-}
-
-
-if (!empty($testsqlite)) {
-	$path =urlencode('d:\inetpub\adodb\sqlite.db');
-	$dsn = "sqlite://$path/";
-	$db = ADONewConnection($dsn);
-	//echo $dsn;
-
-	//$db = ADONewConnection('sqlite');
-
-
-	if ($db && $db->PConnect("d:\\inetpub\\adodb\\sqlite.db", "", "", "")) {
-		print "<h1>Connecting $db->databaseType...</h1>";
-		testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
-	} else
-		print "ERROR: SQLite";
-
-}
-
-if (!empty($testpdopgsql)) {
-	$connstr = "pgsql:dbname=test";
-	$u = 'tester';$p='test';
-	$db = ADONewConnection('pdo');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	$db->Connect($connstr,$u,$p) || die("CONNECT FAILED");
-	testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
-}
-
-if (!empty($testpdomysql)) {
-	$connstr = "mysql:dbname=northwind";
-	$u = 'root';$p='';
-	$db = ADONewConnection('pdo');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	$db->Connect($connstr,$u,$p) || die("CONNECT FAILED");
-
-	testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
-}
-
-if (!empty($testpdomssql)) {
-	$connstr = "mssql:dbname=northwind";
-	$u = 'sa';$p='natsoft';
-	$db = ADONewConnection('pdo');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	$db->Connect($connstr,$u,$p) || die("CONNECT FAILED");
-
-	testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
-}
-
-if (!empty($testpdosqlite)) {
-	$connstr = "sqlite:d:/inetpub/adodb/sqlite-pdo.db3";
-	$u = '';$p='';
-	$db = ADONewConnection('pdo');
-	$db->hasTransactions = false;
-	print "<h1>Connecting $db->databaseType...</h1>";
-	$db->Connect($connstr,$u,$p) || die("CONNECT FAILED");
-	testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
-}
-
-if (!empty($testpdoaccess)) {
-	$connstr = 'odbc:nwind';
-	$u = '';$p='';
-	$db = ADONewConnection('pdo');
-	$db->hasTransactions = false;
-	print "<h1>Connecting $db->databaseType...</h1>";
-	$db->Connect($connstr,$u,$p) || die("CONNECT FAILED");
-	testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
-}
-
-if (!empty($testpdoora)) {
-	$connstr = 'oci:';
-	$u = 'scott';$p='natsoft';
-	$db = ADONewConnection('pdo');
-	#$db->hasTransactions = false;
-	print "<h1>Connecting $db->databaseType...</h1>";
-	$db->Connect($connstr,$u,$p) || die("CONNECT FAILED");
-	testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
-}
-
-// REQUIRES ODBC DSN CALLED nwind
-if (!empty($testaccess)) {
-	$db = ADONewConnection('access');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	$access = 'd:\inetpub\wwwroot\php\NWIND.MDB';
-	$dsn = "nwind";
-	$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=$access;Uid=Admin;Pwd=;";
-
-	//$dsn =  'Provider=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=' . $access . ';';
-	if ($db->PConnect($dsn, "", "", ""))
-		testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
-	else print "ERROR: Access test requires a Windows ODBC DSN=nwind, Access driver";
-
-}
-
-if (!empty($testaccess) && !empty($testado)) { // ADO ACCESS
-
-	$db = ADONewConnection("ado_access");
-	print "<h1>Connecting $db->databaseType...</h1>";
-
-	$access = 'd:\inetpub\wwwroot\php\NWIND.MDB';
-	$myDSN =  'PROVIDER=Microsoft.Jet.OLEDB.4.0;'
-		. 'DATA SOURCE=' . $access . ';';
-		//. 'USER ID=;PASSWORD=;';
-	$_GET['nolog'] = 1;
-	if ($db->PConnect($myDSN, "", "", "")) {
-		print "ADO version=".$db->_connectionID->version."<br>";
-		testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
-	} else print "ERROR: Access test requires a Access database $access".'<BR>'.$db->ErrorMsg();
-
-}
-
-if (!empty($testvfp)) { // ODBC
-	$db = ADONewConnection('vfp');
-	print "<h1>Connecting $db->databaseType...</h1>";flush();
-
-	if ( $db->PConnect("vfp-adoxyz")) {
-		testdb($db,"create table d:\\inetpub\\adodb\\ADOXYZ (id int, firstname char(24), lastname char(24),created date)");
-	 } else print "ERROR: Visual FoxPro test requires a Windows ODBC DSN=vfp-adoxyz, VFP driver";
-
-	echo "<hr />";
-	$db = ADONewConnection('odbtp');
-
-	if ( $db->PConnect('localhost','DRIVER={Microsoft Visual FoxPro Driver};SOURCETYPE=DBF;SOURCEDB=d:\inetpub\adodb;EXCLUSIVE=NO;')) {
-	print "<h1>Connecting $db->databaseType...</h1>";flush();
-	testdb($db,"create table d:\\inetpub\\adodb\\ADOXYZ (id int, firstname char(24), lastname char(24),created date)");
-	 } else print "ERROR: Visual FoxPro odbtp requires a Windows ODBC DSN=vfp-adoxyz, VFP driver";
-
-}
-
-
-// REQUIRES MySQL server at localhost with database 'test'
-if (!empty($testmysql)) { // MYSQL
-
-
-	if (PHP_VERSION >= 5 || $_SERVER['HTTP_HOST'] == 'localhost') $server = 'localhost';
-	else $server = "mangrove";
-	$user = 'root'; $password = ''; $database = 'northwind';
-	$db = ADONewConnection("mysqlt://$user:$password@$server/$database?persist");
-	print "<h1>Connecting $db->databaseType...</h1>";
-
-	if (true || $db->PConnect($server, "root", "", "northwind")) {
-		//$db->Execute("DROP TABLE ADOXYZ") || die('fail drop');
-		//$db->debug=1;$db->Execute('drop table ADOXYZ');
-		testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date) Type=InnoDB");
-	} else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
-}
-
-// REQUIRES MySQL server at localhost with database 'test'
-if (!empty($testmysqli)) { // MYSQL
-
-	$db = ADONewConnection('mysqli');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if (PHP_VERSION >= 5 || $_SERVER['HTTP_HOST'] == 'localhost') $server = 'localhost';
-	else $server = "mangrove";
-	if ($db->PConnect($server, "root", "", "northwind")) {
-		//$db->debug=1;$db->Execute('drop table ADOXYZ');
-		testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
-	} else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
-}
-
-
-// REQUIRES MySQL server at localhost with database 'test'
-if (!empty($testmysqlodbc)) { // MYSQL
-
-	$db = ADONewConnection('odbc');
-	$db->hasTransactions = false;
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if ($_SERVER['HTTP_HOST'] == 'localhost') $server = 'localhost';
-	else $server = "mangrove";
-	if ($db->PConnect('mysql', "root", ""))
-		testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date) type=innodb");
-	else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
-}
-
-if (!empty($testproxy)){
-	$db = ADONewConnection('proxy');
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if ($_SERVER['HTTP_HOST'] == 'localhost') $server = 'localhost';
-
-	if ($db->PConnect('http://localhost/php/phplens/adodb/server.php'))
-		testdb($db,
-		"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date) type=innodb");
-	else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
-
-}
-
-ADOLoadCode('oci805');
-ADOLoadCode("oci8po");
-
-if (!empty($testoracle)) {
-	$dsn = "oci8";//://scott:natsoft@kk2?persist";
-	$db = ADONewConnection($dsn );//'oci8');
-
-	//$db->debug=1;
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if ($db->Connect('mobydick', "scott", "natsoft",'SID=mobydick'))
-		testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
-	else
-		print "ERROR: Oracle test requires an Oracle server setup with scott/natsoft".'<BR>'.$db->ErrorMsg();
-
-}
-ADOLoadCode("oracle"); // no longer supported
-if (false && !empty($testoracle)) {
-
-	$db = ADONewConnection();
-	print "<h1>Connecting $db->databaseType...</h1>";
-	if ($db->PConnect("", "scott", "tiger", "natsoft.domain"))
-		testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
-	else print "ERROR: Oracle test requires an Oracle server setup with scott/tiger".'<BR>'.$db->ErrorMsg();
-
-}
-
-ADOLoadCode("odbc_db2"); // no longer supported
-if (!empty($testdb2)) {
-	if (PHP_VERSION>=5.1) {
-		$db = ADONewConnection("db2");
-		print "<h1>Connecting $db->databaseType...</h1>";
-
-		#$db->curMode = SQL_CUR_USE_ODBC;
-		#$dsn = "driver={IBM db2 odbc DRIVER};Database=test;hostname=localhost;port=50000;protocol=TCPIP; uid=natsoft; pwd=guest";
-		if ($db->Connect('localhost','natsoft','guest','test')) {
-			testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
-		} else print "ERROR: DB2 test requires an server setup with odbc data source db2_sample".'<BR>'.$db->ErrorMsg();
-	} else {
-		$db = ADONewConnection("odbc_db2");
-		print "<h1>Connecting $db->databaseType...</h1>";
-
-		$dsn = "db2test";
-		#$db->curMode = SQL_CUR_USE_ODBC;
-		#$dsn = "driver={IBM db2 odbc DRIVER};Database=test;hostname=localhost;port=50000;protocol=TCPIP; uid=natsoft; pwd=guest";
-		if ($db->Connect($dsn)) {
-			testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
-		} else print "ERROR: DB2 test requires an server setup with odbc data source db2_sample".'<BR>'.$db->ErrorMsg();
-	}
-echo "<hr />";
-flush();
-	$dsn = "driver={IBM db2 odbc DRIVER};Database=sample;hostname=localhost;port=50000;protocol=TCPIP; uid=root; pwd=natsoft";
-
-	$db = ADONewConnection('odbtp');
-	if ($db->Connect('127.0.0.1',$dsn)) {
-
-		$db->debug=1;
-		 $arr = $db->GetArray( "||SQLProcedures" ); adodb_pr($arr);
-	     $arr = $db->GetArray( "||SQLProcedureColumns|||GET_ROUTINE_SAR" );adodb_pr($arr);
-
-		testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
-	} else echo ("ERROR Connection");
-	echo $db->ErrorMsg();
-}
-
-
-$server = 'localhost';
-
-
-
-ADOLoadCode("mssqlpo");
-if (false && !empty($testmssql)) { // MS SQL Server -- the extension is buggy -- probably better to use ODBC
-	$db = ADONewConnection("mssqlpo");
-	//$db->debug=1;
-	print "<h1>Connecting $db->databaseType...</h1>";
-
-	$ok = $db->Connect('','sa','natsoft','northwind');
-	echo $db->ErrorMsg();
-	if ($ok /*or $db->PConnect("mangrove", "sa", "natsoft", "ai")*/) {
-		AutoDetect_MSSQL_Date_Order($db);
-	//	$db->Execute('drop table adoxyz');
-		testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
-	} else print "ERROR: MSSQL test 2 requires a MS SQL 7 on a server='$server', userid='adodb', password='natsoft', database='ai'".'<BR>'.$db->ErrorMsg();
-
-}
-
-
-ADOLoadCode('odbc_mssql');
-if (!empty($testmssql)) { // MS SQL Server via ODBC
-	$db = ADONewConnection();
-
-	print "<h1>Connecting $db->databaseType...</h1>";
-
-	$dsn = "PROVIDER=MSDASQL;Driver={SQL Server};Server=$server;Database=northwind;";
-	$dsn = 'condor';
-	if ($db->PConnect($dsn, "sa", "natsoft", ""))  {
-		testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
-	}
-	else print "ERROR: MSSQL test 1 requires a MS SQL 7 server setup with DSN setup";
-
-}
-
-ADOLoadCode("ado_mssql");
-if (!empty($testmssql) && !empty($testado) ) { // ADO ACCESS MSSQL -- thru ODBC -- DSN-less
-
-	$db = ADONewConnection("ado_mssql");
-	//$db->debug=1;
-	print "<h1>Connecting DSN-less $db->databaseType...</h1>";
-
-	$myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"
-		. "SERVER=$server;DATABASE=NorthWind;UID=adodb;PWD=natsoft;Trusted_Connection=No";
-
-
-	if ($db->PConnect($myDSN, "", "", ""))
-		testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
-	else print "ERROR: MSSQL test 2 requires MS SQL 7";
-
-}
-
-if (!empty($testmssql) && !empty($testado)) { // ADO ACCESS MSSQL with OLEDB provider
-
-	$db = ADONewConnection("ado_mssql");
-	print "<h1>Connecting DSN-less OLEDB Provider $db->databaseType...</h1>";
-	//$db->debug=1;
-	$myDSN="SERVER=localhost;DATABASE=northwind;Trusted_Connection=yes";
-	if ($db->PConnect($myDSN, "adodb", "natsoft", 'SQLOLEDB')) {
-		testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
-	} else print "ERROR: MSSQL test 2 requires a MS SQL 7 on a server='mangrove', userid='sa', password='', database='ai'";
-
-}
-
-
-if (extension_loaded('odbtp') && !empty($testmssql)) { // MS SQL Server via ODBC
-	$db = ADONewConnection('odbtp');
-
-	$dsn = "PROVIDER=MSDASQL;Driver={SQL Server};Server=$server;Database=northwind;uid=adodb;pwd=natsoft";
-
-	if ($db->PConnect('localhost',$dsn, "", ""))  {
-		print "<h1>Connecting $db->databaseType...</h1>";
-		testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
-	}
-	else print "ERROR: MSSQL test 1 requires a MS SQL 7 server setup with DSN setup";
-
-}
-
-
-print "<h3>Tests Completed</h3>";
diff --git tests/testgenid.php tests/testgenid.php
deleted file mode 100644
index 3310734a..00000000
--- tests/testgenid.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/*
-	V4.50 6 July 2004
-
-	Run multiple copies of this php script at the same time
-	to test unique generation of id's in multiuser mode
-*/
-include_once('../adodb.inc.php');
-$testaccess = true;
-include_once('testdatabases.inc.php');
-
-function testdb(&$db,$createtab="create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)")
-{
-	$table = 'adodbseq';
-
-	$db->Execute("drop table $table");
-	//$db->debug=true;
-
-	$ctr = 5000;
-	$lastnum = 0;
-
-	while (--$ctr >= 0) {
-		$num = $db->GenID($table);
-		if ($num === false) {
-			print "GenID returned false";
-			break;
-		}
-		if ($lastnum + 1 == $num) print " $num ";
-		else {
-			print " <font color=red>$num</font> ";
-			flush();
-		}
-		$lastnum = $num;
-	}
-}
diff --git tests/testmssql.php tests/testmssql.php
deleted file mode 100644
index 292dc382..00000000
--- tests/testmssql.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-
-/**
- * @version   v5.20.18  28-Jun-2020
- * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
- * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
- * 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 4 for best viewing.
- *
- * Latest version is available at http://adodb.org/
- *
- * Test GetUpdateSQL and GetInsertSQL.
- */
-
-error_reporting(E_ALL);
-
-
-include('../adodb.inc.php');
-include('../tohtml.inc.php');
-
-//==========================
-// This code tests an insert
-
-
-
-$conn = ADONewConnection("mssql");  // create a connection
-$conn->Connect('127.0.0.1','adodb','natsoft','northwind') or die('Fail');
-
-$conn->debug =1;
-$query = 'select * from products';
-$conn->SetFetchMode(ADODB_FETCH_ASSOC);
-$rs = $conn->Execute($query);
-echo "<pre>";
-while( !$rs->EOF ) {
-	$output[] = $rs->fields;
-	var_dump($rs->fields);
-	$rs->MoveNext();
-	print "<p>";
-}
-die();
-
-
-$p = $conn->Prepare('insert into products (productname,unitprice,dcreated) values (?,?,?)');
-echo "<pre>";
-print_r($p);
-
-$conn->debug=1;
-$conn->Execute($p,array('John'.rand(),33.3,$conn->DBDate(time())));
-
-$p = $conn->Prepare('select * from products where productname like ?');
-$arr = $conn->getarray($p,array('V%'));
-print_r($arr);
-die();
-
-//$conn = ADONewConnection("mssql");
-//$conn->Connect('mangrove','sa','natsoft','ai');
-
-//$conn->Connect('mangrove','sa','natsoft','ai');
-$conn->debug=1;
-$conn->Execute('delete from blobtest');
-
-$conn->Execute('insert into blobtest (id) values(1)');
-$conn->UpdateBlobFile('blobtest','b1','../cute_icons_for_site/adodb.gif','id=1');
-$rs = $conn->Execute('select b1 from blobtest where id=1');
-
-$output = "c:\\temp\\test_out-".date('H-i-s').".gif";
-print "Saving file <b>$output</b>, size=".strlen($rs->fields[0])."<p>";
-$fd = fopen($output, "wb");
-fwrite($fd, $rs->fields[0]);
-fclose($fd);
-
-print " <a href=file://$output>View Image</a>";
-//$rs = $conn->Execute('SELECT id,SUBSTRING(b1, 1, 10) FROM blobtest');
-//rs2html($rs);
diff --git tests/testoci8.php tests/testoci8.php
deleted file mode 100644
index aa66ad94..00000000
--- tests/testoci8.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<html>
-<body>
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-error_reporting(E_ALL | E_STRICT);
-include("../adodb.inc.php");
-include("../tohtml.inc.php");
-
-if (0) {
-	$db = ADONewConnection('oci8po');
-
-	$db->PConnect('','scott','natsoft');
-	if (!empty($testblob)) {
-		$varHoldingBlob = 'ABC DEF GEF John TEST';
-		$num = time()%10240;
-		// create table atable (id integer, ablob blob);
-		$db->Execute('insert into ATABLE (id,ablob) values('.$num.',empty_blob())');
-		$db->UpdateBlob('ATABLE', 'ablob', $varHoldingBlob, 'id='.$num, 'BLOB');
-
-		$rs = $db->Execute('select * from atable');
-
-		if (!$rs) die("Empty RS");
-		if ($rs->EOF) die("EOF RS");
-		rs2html($rs);
-	}
-	$stmt = $db->Prepare('select * from adoxyz where id=?');
-	for ($i = 1; $i <= 10; $i++) {
-	$rs = $db->Execute(
-		$stmt,
-		array($i));
-
-		if (!$rs) die("Empty RS");
-		if ($rs->EOF) die("EOF RS");
-		rs2html($rs);
-	}
-}
-if (1) {
-	$db = ADONewConnection('oci8');
-	$db->PConnect('','scott','natsoft');
-	$db->debug = true;
-	$db->Execute("delete from emp where ename='John'");
-	print $db->Affected_Rows().'<BR>';
-	$stmt = $db->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
-	$rs = $db->Execute($stmt,array('empno'=>4321,'ename'=>'John'));
-	// prepare not quite ready for prime time
-	//$rs = $db->Execute($stmt,array('empno'=>3775,'ename'=>'John'));
-	if (!$rs) die("Empty RS");
-
-	$db->setfetchmode(ADODB_FETCH_NUM);
-
-	$vv = 'A%';
-	$stmt = $db->PrepareSP("BEGIN adodb.open_tab2(:rs,:tt); END;",true);
-	$db->OutParameter($stmt, $cur, 'rs', -1, OCI_B_CURSOR);
-	$db->OutParameter($stmt, $vv, 'tt');
-	$rs = $db->Execute($stmt);
-	while (!$rs->EOF) {
-		adodb_pr($rs->fields);
-		$rs->MoveNext();
-	}
-	echo " val = $vv";
-
-}
-
-if (0) {
-	$db = ADONewConnection('odbc_oracle');
-	if (!$db->PConnect('local_oracle','scott','tiger')) die('fail connect');
-	$db->debug = true;
-	$rs = $db->Execute(
-		'select * from adoxyz where firstname=? and trim(lastname)=?',
-		array('first'=>'Caroline','last'=>'Miranda'));
-	if (!$rs) die("Empty RS");
-	if ($rs->EOF) die("EOF RS");
-	rs2html($rs);
-}
diff --git tests/testoci8cursor.php tests/testoci8cursor.php
deleted file mode 100644
index 078ea7a6..00000000
--- tests/testoci8cursor.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-
-/*
-	Test for Oracle Variable Cursors, which are treated as ADOdb recordsets.
-
-	We have 2 examples. The first shows us using the Parameter statement.
-	The second shows us using the new ExecuteCursor($sql, $cursorName)
-	function.
-
-------------------------------------------------------------------
--- TEST PACKAGE YOU NEED TO INSTALL ON ORACLE - run from sql*plus
-------------------------------------------------------------------
-
-
--- TEST PACKAGE
-CREATE OR REPLACE PACKAGE adodb AS
-TYPE TabType IS REF CURSOR RETURN tab%ROWTYPE;
-PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar);
-PROCEDURE data_out(input IN varchar, output OUT varchar);
-
-procedure myproc (p1 in number, p2 out number);
-END adodb;
-/
-
-CREATE OR REPLACE PACKAGE BODY adodb AS
-PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar) IS
-	BEGIN
-		OPEN tabcursor FOR SELECT * FROM tab where tname like tablenames;
-	END open_tab;
-
-PROCEDURE data_out(input IN varchar, output OUT varchar) IS
-	BEGIN
-		output := 'Cinta Hati '||input;
-	END;
-
-procedure myproc (p1 in number, p2 out number) as
-begin
-p2 := p1;
-end;
-END adodb;
-/
-
-------------------------------------------------------------------
--- END PACKAGE
-------------------------------------------------------------------
-
-*/
-
-include('../adodb.inc.php');
-include('../tohtml.inc.php');
-
-	error_reporting(E_ALL);
-	$db = ADONewConnection('oci8');
-	$db->PConnect('','scott','natsoft');
-	$db->debug = 99;
-
-
-/*
-*/
-
-	define('MYNUM',5);
-
-
-	$rs = $db->ExecuteCursor("BEGIN adodb.open_tab(:RS,'A%'); END;");
-
-	if ($rs && !$rs->EOF) {
-		print "Test 1 RowCount: ".$rs->RecordCount()."<p>";
-	} else {
-		print "<b>Error in using Cursor Variables 1</b><p>";
-	}
-
-	print "<h4>Testing Stored Procedures for oci8</h4>";
-
-	$stid = $db->PrepareSP('BEGIN adodb.myproc('.MYNUM.', :myov); END;');
-	$db->OutParameter($stid, $myov, 'myov');
-	$db->Execute($stid);
-	if ($myov != MYNUM) print "<p><b>Error with myproc</b></p>";
-
-
-	$stmt = $db->PrepareSP("BEGIN adodb.data_out(:a1, :a2); END;",true);
-	$a1 = 'Malaysia';
-	//$a2 = ''; # a2 doesn't even need to be defined!
-	$db->InParameter($stmt,$a1,'a1');
-	$db->OutParameter($stmt,$a2,'a2');
-	$rs = $db->Execute($stmt);
-	if ($rs) {
-		if ($a2 !== 'Cinta Hati Malaysia') print "<b>Stored Procedure Error: a2 = $a2</b><p>";
-		else echo  "OK: a2=$a2<p>";
-	} else {
-		print "<b>Error in using Stored Procedure IN/Out Variables</b><p>";
-	}
-
-
-	$tname = 'A%';
-
-	$stmt = $db->PrepareSP('select * from tab where tname like :tablename');
-	$db->Parameter($stmt,$tname,'tablename');
-	$rs = $db->Execute($stmt);
-	rs2html($rs);
diff --git tests/testpaging.php tests/testpaging.php
deleted file mode 100644
index 5b4a5290..00000000
--- tests/testpaging.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-
-error_reporting(E_ALL);
-
-
-include_once('../adodb.inc.php');
-include_once('../adodb-pager.inc.php');
-
-$driver = 'oci8';
-$sql = 'select  ID, firstname as "First Name", lastname as "Last Name" from adoxyz  order  by  id';
-//$sql = 'select count(*),firstname from adoxyz group by firstname order by 2 ';
-//$sql = 'select distinct firstname, lastname from adoxyz  order  by  firstname';
-
-if ($driver == 'postgres') {
-	$db = NewADOConnection('postgres');
-	$db->PConnect('localhost','tester','test','test');
-}
-
-if ($driver == 'access') {
-	$db = NewADOConnection('access');
-	$db->PConnect("nwind", "", "", "");
-}
-
-if ($driver == 'ibase') {
-	$db = NewADOConnection('ibase');
-	$db->PConnect("localhost:e:\\firebird\\examples\\employee.gdb", "sysdba", "masterkey", "");
-	$sql = 'select distinct firstname, lastname  from adoxyz  order  by  firstname';
-
-}
-if ($driver == 'mssql') {
-	$db = NewADOConnection('mssql');
-	$db->Connect('JAGUAR\vsdotnet','adodb','natsoft','northwind');
-}
-if ($driver == 'oci8') {
-	$db = NewADOConnection('oci8');
-	$db->Connect('','scott','natsoft');
-
-$sql = "select * from (select  ID, firstname as \"First Name\", lastname as \"Last Name\" from adoxyz
-	 order  by  1)";
-}
-
-if ($driver == 'access') {
-	$db = NewADOConnection('access');
-	$db->Connect('nwind');
-}
-
-if (empty($driver) or $driver == 'mysql') {
-	$db = NewADOConnection('mysql');
-	$db->Connect('localhost','root','','test');
-}
-
-//$db->pageExecuteCountRows = false;
-
-$db->debug = true;
-
-if (0) {
-$rs = $db->Execute($sql);
-include_once('../toexport.inc.php');
-print "<pre>";
-print rs2csv($rs); # return a string
-
-print '<hr />';
-$rs->MoveFirst(); # note, some databases do not support MoveFirst
-print rs2tab($rs); # return a string
-
-print '<hr />';
-$rs->MoveFirst();
-rs2tabout($rs); # send to stdout directly
-print "</pre>";
-}
-
-$pager = new ADODB_Pager($db,$sql);
-$pager->showPageLinks = true;
-$pager->linksPerPage = 10;
-$pager->cache = 60;
-$pager->Render($rows=7);
diff --git tests/testpear.php tests/testpear.php
deleted file mode 100644
index 0c6d58f4..00000000
--- tests/testpear.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-
-error_reporting(E_ALL);
-
-include_once('../adodb-pear.inc.php');
-$username = 'root';
-$password = '';
-$hostname = 'localhost';
-$databasename = 'xphplens';
-$driver = 'mysql';
-
-$dsn = "$driver://$username:$password@$hostname/$databasename";
-
-$db = DB::Connect($dsn);
-$db->setFetchMode(ADODB_FETCH_ASSOC);
-$rs = $db->Query('select firstname,lastname from adoxyz');
-$cnt = 0;
-while ($arr = $rs->FetchRow()) {
-	print_r($arr);
-	print "<br>";
-	$cnt += 1;
-}
-
-if ($cnt != 50) print "<b>Error in \$cnt = $cnt</b>";
diff --git tests/testsessions.php tests/testsessions.php
deleted file mode 100644
index 34836060..00000000
--- tests/testsessions.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-/*
-@version   v5.20.18  28-Jun-2020
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
-  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 4 for best viewing.
-
-  Latest version is available at http://adodb.org/
-*/
-
-function NotifyExpire($ref,$key)
-{
-	print "<p><b>Notify Expiring=$ref, sessionkey=$key</b></p>";
-}
-
-//-------------------------------------------------------------------
-
-error_reporting(E_ALL);
-
-
-ob_start();
-include('../session/adodb-cryptsession2.php');
-
-
-$options['debug'] = 1;
-$db = 'postgres';
-
-#### CONNECTION
-switch($db) {
-case 'oci8':
-	$options['table'] = 'adodb_sessions2';
-	ADOdb_Session::config('oci8', 'mobydick', 'jdev', 'natsoft', 'mobydick',$options);
-	break;
-
-case 'postgres':
-	$options['table'] = 'sessions2';
-	ADOdb_Session::config('postgres', 'localhost', 'postgres', 'natsoft', 'northwind',$options);
-	break;
-
-case 'mysql':
-default:
-	$options['table'] = 'sessions2';
-	ADOdb_Session::config('mysql', 'localhost', 'root', '', 'xphplens_2',$options);
-	break;
-
-
-}
-
-
-
-#### SETUP NOTIFICATION
-	$USER = 'JLIM'.rand();
-	$ADODB_SESSION_EXPIRE_NOTIFY = array('USER','NotifyExpire');
-
-	adodb_session_create_table();
-	session_start();
-
-	adodb_session_regenerate_id();
-
-### SETUP SESSION VARIABLES
-	if (empty($_SESSION['MONKEY'])) $_SESSION['MONKEY'] = array(1,'abc',44.41);
-	else $_SESSION['MONKEY'][0] += 1;
-	if (!isset($_GET['nochange'])) @$_SESSION['AVAR'] += 1;
-
-
-### START DISPLAY
-	print "<h3>PHP ".PHP_VERSION."</h3>";
-	print "<p><b>\$_SESSION['AVAR']={$_SESSION['AVAR']}</b></p>";
-
-	print "<hr /> <b>Cookies</b>: ";
-	print_r($_COOKIE);
-
-	var_dump($_SESSION['MONKEY']);
-
-### RANDOMLY PERFORM Garbage Collection
-### In real-production environment, this is done for you
-### by php's session extension, which calls adodb_sess_gc()
-### automatically for you. See php.ini's
-### session.cookie_lifetime and session.gc_probability
-
-	if (rand() % 5 == 0) {
-
-		print "<hr /><p><b>Garbage Collection</b></p>";
-		adodb_sess_gc(10);
-
-		if (rand() % 2 == 0) {
-			print "<p>Random own session destroy</p>";
-			session_destroy();
-		}
-	} else {
-		$DB = ADODB_Session::_conn();
-		$sessk = $DB->qstr('%AZ'.rand().time());
-		$olddate = $DB->DBTimeStamp(time()-30*24*3600);
-		$rr = $DB->qstr(rand());
-		$DB->Execute("insert into {$options['table']} (sesskey,expiry,expireref,sessdata,created,modified) values ($sessk,$olddate, $rr,'',$olddate,$olddate)");
-	}
diff --git tests/time.php tests/time.php
deleted file mode 100644
index 8261e1e9..00000000
--- tests/time.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-include_once('../adodb-time.inc.php');
-adodb_date_test();
-?>
-<?php
-//require("adodb-time.inc.php");
-
-$datestring = "2063-12-24"; // string normally from mySQL
-$stringArray = explode("-", $datestring);
-$date = adodb_mktime(0,0,0,$stringArray[1],$stringArray[2],$stringArray[0]);
-
-$convertedDate = adodb_date("d-M-Y", $date); // converted string to UK style date
-
-echo( "Original: $datestring<br>" );
-echo( "Converted: $convertedDate" ); //why is string returned as one day (3 not 4) less for this example??
diff --git tests/tmssql.php tests/tmssql.php
deleted file mode 100644
index 0f81311a..00000000
--- tests/tmssql.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-error_reporting(E_ALL);
-ini_set('mssql.datetimeconvert',0);
-
-function tmssql()
-{
-	print "<h3>mssql</h3>";
-	$db = mssql_connect('JAGUAR\vsdotnet','adodb','natsoft') or die('No Connection');
-	mssql_select_db('northwind',$db);
-
-	$rs = mssql_query('select getdate() as date',$db);
-	$o = mssql_fetch_row($rs);
-	print_r($o);
-	mssql_free_result($rs);
-
-	print "<p>Delete</p>"; flush();
-	$rs2 = mssql_query('delete from adoxyz',$db);
-	$p = mssql_num_rows($rs2);
-	mssql_free_result($rs2);
-
-}
-
-function tpear()
-{
-include_once('DB.php');
-
-	print "<h3>PEAR</h3>";
-	$username = 'adodb';
-	$password = 'natsoft';
-	$hostname = 'JAGUAR\vsdotnet';
-	$databasename = 'northwind';
-
-	$dsn = "mssql://$username:$password@$hostname/$databasename";
-	$conn = DB::connect($dsn);
-	print "date=".$conn->GetOne('select getdate()')."<br>";
-	@$conn->query('create table tester (id integer)');
-	print "<p>Delete</p>"; flush();
-	$rs = $conn->query('delete from tester');
-	print "date=".$conn->GetOne('select getdate()')."<br>";
-}
-
-function tadodb()
-{
-include_once('../adodb.inc.php');
-
-	print "<h3>ADOdb</h3>";
-	$conn = NewADOConnection('mssql');
-	$conn->Connect('JAGUAR\vsdotnet','adodb','natsoft','northwind');
-//	$conn->debug=1;
-	print "date=".$conn->GetOne('select getdate()')."<br>";
-	$conn->Execute('create table tester (id integer)');
-	print "<p>Delete</p>"; flush();
-	$rs = $conn->Execute('delete from tester');
-	print "date=".$conn->GetOne('select getdate()')."<br>";
-}
-
-
-$ACCEPTIP = '127.0.0.1';
-
-$remote = $_SERVER["REMOTE_ADDR"];
-
-if (!empty($ACCEPTIP))
- if ($remote != '127.0.0.1' && $remote != $ACCEPTIP)
- 	die("Unauthorised client: '$remote'");
-
-?>
-<a href=tmssql.php?do=tmssql>mssql</a>
-<a href=tmssql.php?do=tpear>pear</a>
-<a href=tmssql.php?do=tadodb>adodb</a>
-<?php
-if (!empty($_GET['do'])) {
-	$do = $_GET['do'];
-	switch($do) {
-	case 'tpear':
-	case 'tadodb':
-	case 'tmssql':
-		$do();
-	}
-}
diff --git tests/xmlschema-mssql.xml tests/xmlschema-mssql.xml
deleted file mode 100644
index db2c3432..00000000
--- tests/xmlschema-mssql.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-<schema version="0.3">
-<table name="simple_table">
-<field name="id" type="I" size="11">
-<KEY/>
-<AUTOINCREMENT/>
-</field>
-<field name="name" type="C" size="3">
-<DEFAULT value="no"/>
-</field>
-<field name="description" type="X"></field>
-<index name="id">
-<UNIQUE/>
-<col>id</col>
-</index>
-<index name="id_2">
-<col>id</col>
-</index>
-<data>
-</data>
-</table>
-  <sql>
-    <descr>SQL to be executed only on specific platforms</descr>
-    <query platform="postgres|postgres7">
-      insert into mytable ( row1, row2 ) values ( 12, 'postgres stuff' )
-    </query>
-    <query platform="mysql">
-      insert into mytable ( row1, row2 ) values ( 12, 'mysql stuff' )
-    </query>
-	<query platform="mssql">
-      INSERT into simple_table ( name, description ) values ( '12', 'Microsoft stuff' )
-    </query>
-  </sql>
-</schema>
\ No newline at end of file
diff --git tests/xmlschema.xml tests/xmlschema.xml
deleted file mode 100644
index ea48ae2b..00000000
--- tests/xmlschema.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0"?>
-<schema version="0.3">
-  <table name="mytable">
-    <field name="row1" type="I">
-      <descr>An integer row that's a primary key and autoincrements</descr>
-      <KEY/>
-      <AUTOINCREMENT/>
-    </field>
-    <field name="row2" type="C" size="16">
-      <descr>A 16 character varchar row that can't be null</descr>
-      <NOTNULL/>
-    </field>
-    <index name="myindex">
-      <col>row1</col>
-      <col>row2</col>
-    </index>
-  </table>
-  <sql>
-    <descr>SQL to be executed only on specific platforms</descr>
-    <query platform="postgres|postgres7">
-      insert into mytable ( row1, row2 ) values ( 12, 'postgres stuff' )
-    </query>
-    <query platform="mysql">
-      insert into mytable ( row1, row2 ) values ( 12, 'mysql stuff' )
-    </query>
-	<query platform="mssql">
-      insert into mytable ( row1, row2 ) values ( 12, 'Microsoft stuff' )
-    </query>
-  </sql>
-  <table name="obsoletetable">
-    <DROP/>
-  </table>
-</schema>
\ No newline at end of file
