[TASK] Update ADOdb to 5.19 63/31163/3
authorAndreas Fernandez <andreas.fernandez@aspedia.de>
Thu, 26 Jun 2014 15:46:52 +0000 (17:46 +0200)
committerXavier Perseguers <xavier@typo3.org>
Sun, 6 Jul 2014 08:37:28 +0000 (10:37 +0200)
Updated ADOdb from 5.18 to 5.19 fixing several bugs.

Resolves: #59911
Releases: 6.3, 6.2
Change-Id: I3173c8b14b3d653f29d4992029dbaa9129200fa2
Reviewed-on: https://review.typo3.org/31163
Reviewed-by: Marcin Sągol
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
146 files changed:
typo3/sysext/adodb/adodb/README.md [new file with mode: 0644]
typo3/sysext/adodb/adodb/adodb-active-record.inc.php
typo3/sysext/adodb/adodb/adodb-active-recordx.inc.php
typo3/sysext/adodb/adodb/adodb-csvlib.inc.php
typo3/sysext/adodb/adodb/adodb-datadict.inc.php
typo3/sysext/adodb/adodb/adodb-error.inc.php
typo3/sysext/adodb/adodb/adodb-errorhandler.inc.php
typo3/sysext/adodb/adodb/adodb-errorpear.inc.php
typo3/sysext/adodb/adodb/adodb-exceptions.inc.php
typo3/sysext/adodb/adodb/adodb-iterator.inc.php
typo3/sysext/adodb/adodb/adodb-lib.inc.php
typo3/sysext/adodb/adodb/adodb-memcache.lib.inc.php
typo3/sysext/adodb/adodb/adodb-pager.inc.php
typo3/sysext/adodb/adodb/adodb-pear.inc.php
typo3/sysext/adodb/adodb/adodb-perf.inc.php
typo3/sysext/adodb/adodb/adodb-php4.inc.php
typo3/sysext/adodb/adodb/adodb-time.inc.php
typo3/sysext/adodb/adodb/adodb-xmlschema.inc.php
typo3/sysext/adodb/adodb/adodb-xmlschema03.inc.php
typo3/sysext/adodb/adodb/adodb.inc.php
typo3/sysext/adodb/adodb/composer.json [new file with mode: 0644]
typo3/sysext/adodb/adodb/contrib/toxmlrpc.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-access.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-db2.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-firebird.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-generic.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-ibase.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-informix.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-mssql.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-mssqlnative.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-mysql.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-oci8.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-postgres.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-sapdb.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-sqlite.inc.php
typo3/sysext/adodb/adodb/datadict/datadict-sybase.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-access.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-ado.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-ado5.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-ado_access.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-ado_mssql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-ads.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-borland_ibase.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-csv.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-db2.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-db2oci.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-db2ora.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-fbsql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-firebird.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-ibase.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-informix.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-informix72.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-ldap.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mssql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mssql_n.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mssqlnative.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mssqlpo.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mysql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mysqli.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mysqlpo.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-mysqlt.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-netezza.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-oci8.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-oci805.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-oci8po.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-oci8quercus.inc.php [new file with mode: 0644]
typo3/sysext/adodb/adodb/drivers/adodb-odbc.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-odbc_db2.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-odbc_mssql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-odbc_oracle.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-odbtp.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-odbtp_unicode.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-oracle.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-pdo.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-pdo_mssql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-pdo_mysql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-pdo_oci.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-pdo_pgsql.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-pdo_sqlite.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-postgres.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-postgres64.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-postgres7.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-postgres8.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-postgres9.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-proxy.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-sapdb.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-sqlanywhere.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-sqlite.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-sqlite3.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-sqlitepo.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-sybase.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-sybase_ase.inc.php
typo3/sysext/adodb/adodb/drivers/adodb-text.inc.php [new file with mode: 0644]
typo3/sysext/adodb/adodb/drivers/adodb-vfp.inc.php
typo3/sysext/adodb/adodb/lang/adodb-ar.inc.php
typo3/sysext/adodb/adodb/lang/adodb-bg.inc.php
typo3/sysext/adodb/adodb/lang/adodb-bgutf8.inc.php
typo3/sysext/adodb/adodb/lang/adodb-ca.inc.php
typo3/sysext/adodb/adodb/lang/adodb-cn.inc.php
typo3/sysext/adodb/adodb/lang/adodb-cz.inc.php
typo3/sysext/adodb/adodb/lang/adodb-da.inc.php
typo3/sysext/adodb/adodb/lang/adodb-de.inc.php
typo3/sysext/adodb/adodb/lang/adodb-en.inc.php
typo3/sysext/adodb/adodb/lang/adodb-es.inc.php
typo3/sysext/adodb/adodb/lang/adodb-esperanto.inc.php
typo3/sysext/adodb/adodb/lang/adodb-fa.inc.php
typo3/sysext/adodb/adodb/lang/adodb-fr.inc.php
typo3/sysext/adodb/adodb/lang/adodb-hu.inc.php
typo3/sysext/adodb/adodb/lang/adodb-it.inc.php
typo3/sysext/adodb/adodb/lang/adodb-nl.inc.php
typo3/sysext/adodb/adodb/lang/adodb-pl.inc.php
typo3/sysext/adodb/adodb/lang/adodb-pt-br.inc.php
typo3/sysext/adodb/adodb/lang/adodb-ro.inc.php
typo3/sysext/adodb/adodb/lang/adodb-ru1251.inc.php
typo3/sysext/adodb/adodb/lang/adodb-sv.inc.php
typo3/sysext/adodb/adodb/lang/adodb-uk1251.inc.php
typo3/sysext/adodb/adodb/lang/adodb_th.inc.php
typo3/sysext/adodb/adodb/pear/Auth/Container/ADOdb.php
typo3/sysext/adodb/adodb/perf/perf-db2.inc.php
typo3/sysext/adodb/adodb/perf/perf-informix.inc.php
typo3/sysext/adodb/adodb/perf/perf-mssql.inc.php
typo3/sysext/adodb/adodb/perf/perf-mssqlnative.inc.php
typo3/sysext/adodb/adodb/perf/perf-mysql.inc.php
typo3/sysext/adodb/adodb/perf/perf-oci8.inc.php
typo3/sysext/adodb/adodb/perf/perf-postgres.inc.php
typo3/sysext/adodb/adodb/pivottable.inc.php
typo3/sysext/adodb/adodb/readme.txt [deleted file]
typo3/sysext/adodb/adodb/rsfilter.inc.php
typo3/sysext/adodb/adodb/server.php
typo3/sysext/adodb/adodb/session/adodb-compress-bzip2.php
typo3/sysext/adodb/adodb/session/adodb-compress-gzip.php
typo3/sysext/adodb/adodb/session/adodb-cryptsession.php
typo3/sysext/adodb/adodb/session/adodb-cryptsession2.php
typo3/sysext/adodb/adodb/session/adodb-encrypt-mcrypt.php
typo3/sysext/adodb/adodb/session/adodb-encrypt-md5.php
typo3/sysext/adodb/adodb/session/adodb-encrypt-secret.php
typo3/sysext/adodb/adodb/session/adodb-encrypt-sha1.php
typo3/sysext/adodb/adodb/session/adodb-sess.txt
typo3/sysext/adodb/adodb/session/adodb-session-clob.php
typo3/sysext/adodb/adodb/session/adodb-session-clob2.php
typo3/sysext/adodb/adodb/session/adodb-session.php
typo3/sysext/adodb/adodb/session/adodb-session2.php
typo3/sysext/adodb/adodb/session/crypt.inc.php
typo3/sysext/adodb/adodb/toexport.inc.php
typo3/sysext/adodb/adodb/tohtml.inc.php
typo3/sysext/adodb/adodb/xmlschema03.dtd

diff --git a/typo3/sysext/adodb/adodb/README.md b/typo3/sysext/adodb/adodb/README.md
new file mode 100644 (file)
index 0000000..cc6e640
--- /dev/null
@@ -0,0 +1,94 @@
+ADODB Library for PHP5
+======================
+
+(c) 2000-2014 John Lim (jlim@natsoft.com)
+
+Released under both BSD and GNU Lesser GPL library license.
+This means you can use it in proprietary products.
+
+Home page: http://adodb.sourceforge.net/
+
+
+Introduction
+============
+
+PHP's database access functions are not standardized. This creates a
+need for a database class library to hide the differences between the
+different databases (encapsulate the differences) so we can easily
+switch databases.
+
+The library currently supports MySQL, Interbase, Sybase, PostgreSQL, Oracle,
+Microsoft SQL server,  Foxpro ODBC, Access ODBC, Informix, DB2,
+Sybase SQL Anywhere, generic ODBC and Microsoft's ADO.
+
+We hope more people will contribute drivers to support other databases.
+
+
+Installation
+============
+
+Unpack all the files into a directory accessible by your web server.
+
+To test, try modifying some of the tutorial examples.
+Make sure you customize the connection settings correctly.
+
+You can debug using:
+
+``` php
+<?php
+include('adodb/adodb.inc.php');
+
+$db = ADONewConnection($driver); # eg. 'mysql' or 'oci8'
+$db->debug = true;
+$db->Connect($server, $user, $password, $database);
+$rs = $db->Execute('select * from some_small_table');
+print "<pre>";
+print_r($rs->GetRows());
+print "</pre>";
+```
+
+
+Documentation and Examples
+==========================
+
+Refer to the `docs` directory for library documentation and examples.
+
+- Main documentation: `docs-adodb.htm`.
+  Query, update and insert records using a portable API.
+- Data dictionary docs: `docs-datadict.htm`.
+  Describes how to create database tables and indexes in a portable manner.
+- Database performance monitoring docs: `docs-perf.htm`.
+  Allows you to perform health checks, tune and monitor your database.
+- Database-backed session docs: `docs-session.htm`.
+
+There is also a tutorial `tute.htm` that contrasts ADOdb code with
+mysql code.
+
+
+Files
+=====
+
+- `adodb.inc.php` is the library's main file. You only need to include this file.
+- `adodb-*.inc.php` are the database specific driver code.
+- `adodb-session.php` is the PHP4 session handling code.
+- `test.php` contains a list of test commands to exercise the class library.
+- `testdatabases.inc.php` contains the list of databases to apply the tests on.
+- `Benchmark.php` is a simple benchmark to test the throughput of a SELECT
+statement for databases described in testdatabases.inc.php. The benchmark
+tables are created in test.php.
+
+
+Feature Requests and Bug Reports
+================================
+
+Please report bugs, issues and feature requests on Github:
+
+https://github.com/ADOdb/ADOdb/issues
+
+You may also find legacy issues in
+
+- the old [ADOdb forums](http://phplens.com/lens/lensforum/topics.php?id=4) on phplens.com
+- the [SourceForge tickets section](http://sourceforge.net/p/adodb/_list/tickets)
+
+However, please note that they are not actively monitored and should
+only be used as reference.
index 215f769..607fa94 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-@version V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+@version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Latest version is available at http://adodb.sourceforge.net
 
   Released under both BSD license and Lesser GPL library license.
@@ -999,4 +999,3 @@ global $_ADODB_ACTIVE_DBS;
 
        return $arr;
 }
-?>
\ No newline at end of file
index 03f4593..e820144 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-@version V5.06 29 Sept 2008   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+@version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Latest version is available at http://adodb.sourceforge.net
 
   Released under both BSD license and Lesser GPL library license.
@@ -1418,4 +1418,3 @@ function adodb_GetActiveRecordsClass(&$db, $class, $tableObj,$whereOrderBy,$bind
 
                return $arr;
 }
-?>
index 03a56f0..d70c16f 100644 (file)
@@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 1;
 
 /*
 
-  V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -315,4 +315,3 @@ $ADODB_INCLUDED_CSV = 1;
 
                return $ok;
        }
-?>
\ No newline at end of file
index 6a9fa6b..b8b881e 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -1029,4 +1029,3 @@ class ADODB_DataDict {
                return $sql;
        }
 } // class
-?>
\ No newline at end of file
index 559545f..29c6a9c 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
  * Whenever there is any discrepancy between the two licenses,
  * the BSD license will take precedence.
@@ -95,27 +95,27 @@ function adodb_error_pg($errormsg)
 {
        if (is_numeric($errormsg)) return (integer) $errormsg;
        // Postgres has no lock-wait timeout.  The best we could do would be to set a statement timeout.
-    static $error_regexps = array(
-            '/(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$/i' => DB_ERROR_NOSUCHTABLE,
-            '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key.*violates unique constraint/i'     => DB_ERROR_ALREADY_EXISTS,
-            '/database ".+" does not exist$/i'       => DB_ERROR_NOSUCHDB,
-            '/(divide|division) by zero$/i'          => DB_ERROR_DIVZERO,
-            '/pg_atoi: error in .*: can\'t parse /i' => DB_ERROR_INVALID_NUMBER,
-            '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/i' => DB_ERROR_NOSUCHFIELD,
-            '/(parser: parse|syntax) error at or near \"/i'   => DB_ERROR_SYNTAX,
-            '/referential integrity violation/i'     => DB_ERROR_CONSTRAINT,
-            '/deadlock detected$/i'                  => DB_ERROR_DEADLOCK,
-            '/canceling statement due to statement timeout$/i' => DB_ERROR_STATEMENT_TIMEOUT,
-            '/could not serialize access due to/i'   => DB_ERROR_SERIALIZATION_FAILURE
-        );
+       static $error_regexps = array(
+                       '(Table does not exist\.|Relation [\"\'].*[\"\'] does not exist|sequence does not exist|class ".+" not found)$' => DB_ERROR_NOSUCHTABLE,
+                       'Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key.*violates unique constraint'     => DB_ERROR_ALREADY_EXISTS,
+                       'database ".+" does not exist$'       => DB_ERROR_NOSUCHDB,
+                       '(divide|division) by zero$'          => DB_ERROR_DIVZERO,
+                       'pg_atoi: error in .*: can\'t parse ' => DB_ERROR_INVALID_NUMBER,
+                       'ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']' => DB_ERROR_NOSUCHFIELD,
+                       '(parser: parse|syntax) error at or near \"'   => DB_ERROR_SYNTAX,
+                       'referential integrity violation'     => DB_ERROR_CONSTRAINT,
+                       'deadlock detected$'                  => DB_ERROR_DEADLOCK,
+                       'canceling statement due to statement timeout$' => DB_ERROR_STATEMENT_TIMEOUT,
+                       'could not serialize access due to'   => DB_ERROR_SERIALIZATION_FAILURE
+               );
        reset($error_regexps);
-    while (list($regexp,$code) = each($error_regexps)) {
-        if (preg_match($regexp, $errormsg)) {
-            return $code;
-        }
-    }
-    // Fall back to DB_ERROR if there was no mapping.
-    return DB_ERROR;
+       while (list($regexp,$code) = each($error_regexps)) {
+               if (preg_match("/$regexp/mi", $errormsg)) {
+                       return $code;
+               }
+       }
+       // Fall back to DB_ERROR if there was no mapping.
+       return DB_ERROR;
 }
 
 function adodb_error_odbc()
@@ -261,4 +261,3 @@ static $MAP = array(
 
        return $MAP;
 }
-?>
\ No newline at end of file
index c64db27..680e76d 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
  * Whenever there is any discrepancy between the two licenses,
  * the BSD license will take precedence.
@@ -76,4 +76,3 @@ function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnec
        //print "<p>$s</p>";
        trigger_error($s,ADODB_ERROR_HANDLER_TYPE);
 }
-?>
index e378a57..10dbb97 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -84,5 +84,3 @@ global $ADODB_Last_PEAR_Error;
 
        return $ADODB_Last_PEAR_Error;
 }
-
-?>
\ No newline at end of file
index f198643..2300f11 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @version V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
  * Whenever there is any discrepancy between the two licenses,
  * the BSD license will take precedence.
@@ -77,6 +77,3 @@ global $ADODB_EXCEPTION;
        else $errfn = 'ADODB_EXCEPTION';
        throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
 }
-
-
-?>
\ No newline at end of file
index a3933b9..2d26326 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -22,9 +22,3 @@
 
        Moved to adodb.inc.php to improve performance.
  */
-
-
-
-
-
-?>
\ No newline at end of file
index 9413b0f..de35bc9 100644 (file)
@@ -6,7 +6,7 @@ global $ADODB_INCLUDED_LIB;
 $ADODB_INCLUDED_LIB = 1;
 
 /*
-  @version V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -17,10 +17,10 @@ $ADODB_INCLUDED_LIB = 1;
 
 function adodb_strip_order_by($sql)
 {
-       $rez = preg_match('/(\sORDER\s+BY\s[^)]*)/is',$sql,$arr);
+       $rez = preg_match('/(\sORDER\s+BY\s(?:[^)](?!limit))*)(?:\sLIMIT\s+[0-9]+)?/is', $sql, $arr);
        if ($arr)
-               if (strpos($arr[0],'(') !== false) {
-                       $at = strpos($sql,$arr[0]);
+               if (strpos($arr[1], '(') !== false) {
+                       $at = strpos($sql, $arr[1]);
                        $cntin = 0;
                        for ($i=$at, $max=strlen($sql); $i < $max; $i++) {
                                $ch = $sql[$i];
@@ -34,8 +34,9 @@ function adodb_strip_order_by($sql)
                                }
                        }
                        $sql = substr($sql,0,$at).substr($sql,$i);
-               } else
-                       $sql = str_replace($arr[0], '', $sql);
+               } else {
+                       $sql = str_replace($arr[1], '', $sql);
+               }
        return $sql;
  }
 
@@ -542,7 +543,7 @@ function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
        return $rsreturn;
 }
 
-// Ivn Oliva version
+// Iván Oliva version
 function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
 {
 
@@ -644,7 +645,7 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
                                        }
 
                                        if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
-                                               switch (ADODB_QUOTE_FIELDNAMES) {
+                                               switch ($ADODB_QUOTE_FIELDNAMES) {
                                                case 'LOWER':
                                                        $fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
                                                case 'NATIVE':
@@ -656,8 +657,6 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
                                        } else
                                                $fnameq = $upperfname;
 
-
-                // is_null requires php 4.0.4
                 //********************************************************//
                 if (is_null($arrFields[$upperfname])
                                        || (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
@@ -816,7 +815,7 @@ static $cacheCols;
                if (adodb_key_exists($upperfname,$arrFields,$force)) {
                        $bad = false;
                        if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) {
-                               switch (ADODB_QUOTE_FIELDNAMES) {
+                               switch ($ADODB_QUOTE_FIELDNAMES) {
                                case 'LOWER':
                                        $fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break;
                                case 'NATIVE':
@@ -1205,5 +1204,3 @@ function _adodb_find_from($sql)
        }
 }
 */
-
-?>
\ No newline at end of file
index 67fc1f2..6e0040d 100644 (file)
@@ -11,7 +11,7 @@ if (empty($ADODB_INCLUDED_CSV)) include(ADODB_DIR.'/adodb-csvlib.inc.php');
 
 /*
 
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -186,5 +186,3 @@ $db->CacheExecute($sql);
                        return true;
                }
        }
-
-?>
\ No newline at end of file
index 1a42dc5..a08ced4 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-       V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+       V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
          Released under both BSD license and Lesser GPL library license.
          Whenever there is any discrepancy between the two licenses,
          the BSD license will take precedence.
@@ -285,6 +285,3 @@ class ADODB_Pager {
                        "</td></tr></table>";
        }
 }
-
-
-?>
\ No newline at end of file
index d5c82b1..49ba936 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
  * Whenever there is any discrepancy between the two licenses,
  * the BSD license will take precedence.
@@ -370,5 +370,3 @@ class DB
                return true;
        }
 }
-
-?>
\ No newline at end of file
index 4cc8c7b..8e6e6cc 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -1095,5 +1095,3 @@ Committed_AS:   348732 kB
     }
     // end hack
 }
-
-?>
\ No newline at end of file
index e69ebb0..e999983 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -12,5 +12,3 @@
 
 class ADODB_BASE_RS {
 }
-
-?>
\ No newline at end of file
index e5f50ed..c74778b 100644 (file)
@@ -57,7 +57,7 @@ adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)
 
 COPYRIGHT
 
-(c) 2003-2005 John Lim and released under BSD-style license except for code by
+(c) 2003-2014 John Lim and released under BSD-style license except for code by
 jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
 and originally found at http://www.php.net/manual/en/function.mktime.php
 
@@ -1456,6 +1456,3 @@ global $ADODB_DATE_LOCALE;
        $ret = adodb_date($fmtdate, $ts, $is_gmt);
        return $ret;
 }
-
-
-?>
index b409376..72a9f9b 100644 (file)
@@ -2222,4 +2222,3 @@ function logMsg( $msg, $title = NULL, $force = FALSE ) {
                echo '</pre>';
        }
 }
-?>
\ No newline at end of file
index 1f09712..3ed5aec 100644 (file)
@@ -2403,4 +2403,3 @@ function logMsg( $msg, $title = NULL, $force = FALSE ) {
                echo '</pre>';
        }
 }
-?>
\ No newline at end of file
index 4eb06de..e9011e9 100644 (file)
@@ -14,7 +14,7 @@
 /**
        \mainpage
 
-        @version V5.18 3 Sep 2012   (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+        @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
 
        Released under both BSD license and Lesser GPL library license. You can choose which license
        you prefer.
@@ -32,8 +32,8 @@
 
  */
 
- if (!defined('_ADODB_LAYER')) {
-       define('_ADODB_LAYER',1);
+if (!defined('_ADODB_LAYER')) {
+       define('_ADODB_LAYER',1);
 
        //==============================================================================================
        // CONSTANT DEFINITIONS
 
        $ADODB_EXTENSION = defined('ADODB_EXTENSION');
 
-       //********************************************************//
-       /*
-       Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
-       Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi
+       // ********************************************************
+       // Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
+       // Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi
+       //
+       // 0 = ignore empty fields. All empty fields in array are ignored.
+       // 1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values.
+       // 2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values.
+       // 3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and empty fields '' are set to empty '' sql values.
 
-               0 = ignore empty fields. All empty fields in array are ignored.
-               1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values.
-               2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values.
-               3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and empty fields '' are set to empty '' sql values.
-       */
-        define('ADODB_FORCE_IGNORE',0);
-        define('ADODB_FORCE_NULL',1);
-        define('ADODB_FORCE_EMPTY',2);
-        define('ADODB_FORCE_VALUE',3);
-    //********************************************************//
+               define('ADODB_FORCE_IGNORE',0);
+               define('ADODB_FORCE_NULL',1);
+               define('ADODB_FORCE_EMPTY',2);
+               define('ADODB_FORCE_VALUE',3);
+       // ********************************************************
 
 
        if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) {
        Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names.
        This currently works only with mssql, odbc, oci8po and ibase derived drivers.
 
-               0 = assoc lowercase field names. $rs->fields['orderid']
+               0 = assoc lowercase field names. $rs->fields['orderid']
                1 = assoc uppercase field names. $rs->fields['ORDERID']
                2 = use native-case field names. $rs->fields['OrderID']
        */
+               define('ADODB_ASSOC_CASE_LOWER', 0);
+               define('ADODB_ASSOC_CASE_UPPER', 1);
+               define('ADODB_ASSOC_CASE_NATIVE', 2);
 
                define('ADODB_FETCH_DEFAULT',0);
                define('ADODB_FETCH_NUM',1);
                /**
                 * ADODB version as a string.
                 */
-               $ADODB_vers = 'V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.';
+               $ADODB_vers = 'V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved. Released BSD & LGPL.';
 
                /**
                 * Determines whether recordset->RecordCount() is used.
        /**
         * Connection object. For connecting to databases, and executing queries.
         */
-       class ADOConnection {
+       abstract class ADOConnection {
        //
        // PUBLIC VARS
        //
        var $_transmode = ''; // transaction mode
 
 
-
-       /**
-        * Constructor
-        */
-       function ADOConnection()
-       {
-               die('Virtual Class -- cannot instantiate');
-       }
-
        static function Version()
        {
        global $ADODB_vers;
 
-               $ok = preg_match( '/^[Vv]([0-9\.]+)/', $ADODB_vers, $matches );
+               $ok = preg_match( '/^[Vv]?([0-9]\.[0-9]+(dev|[a-z]))?/', $ADODB_vers, $matches );
                if (!$ok) return (float) substr($ADODB_vers,1);
                else return $matches[1];
        }
 
        function IsConnected()
        {
-       return !empty($this->_connectionID);
+               return !empty($this->_connectionID);
        }
 
        function _findvers($str)
        }
 
 
-   /**
-       * PEAR DB Compat - do not use internally.
-       */
+       /**
+        * PEAR DB Compat - do not use internally.
+        */
        function nextId($seq_name)
        {
                return $this->GenID($seq_name);
        }
 
        /**
-              Lock a row, will escalate and lock the table if row locking not supported
-             will normally free the lock at the end of the transaction
-       *
-       *  @param $table        name of table to lock
-       *  @param $where        where clause to use, eg: "WHERE row=12". If left empty, will escalate to table lock
-       */
+        *       Lock a row, will escalate and lock the table if row locking not supported
+        *      will normally free the lock at the end of the transaction
+        *
+        *  @param $table       name of table to lock
+        *  @param $where       where clause to use, eg: "WHERE row=12". If left empty, will escalate to table lock
+        */
        function RowLock($table,$where,$col='1 as adodbignore')
        {
                return false;
                return $this->Close();
        }
 
-       /*
-                Returns placeholder for parameter, eg.
-                $DB->Param('a')
-
-                will return ':a' for Oracle, and '?' for most other databases...
-
-                For databases that require positioned params, eg $1, $2, $3 for postgresql,
-                       pass in Param(false) before setting the first parameter.
-       */
+       /**
+        * Returns a placeholder for query parameters
+        * e.g. $DB->Param('a') will return
+        * - '?' for most databases
+        * - ':a' for Oracle
+        * - '$1', '$2', etc. for PostgreSQL
+        * @param string $name parameter's name, false to force a reset of the
+        *                     number to 1 (for databases that require positioned
+        *                     params such as PostgreSQL; note that ADOdb will
+        *                     automatically reset this when executing a query )
+        * @param string $type (unused)
+        * @return string query parameter placeholder
+        */
        function Param($name,$type='C')
        {
                return '?';
                        $ret = $fn($this,$sql,$inputarr);
                        if (isset($ret)) return $ret;
                }
-               if ($inputarr) {
+               if ($inputarr !== false) {
                        if (!is_array($inputarr)) $inputarr = array($inputarr);
 
                        $element0 = reset($inputarr);
                        $this->_queryID = @$this->_query($sql,$inputarr);
                }
 
-               /************************
+               /************************
                // OK, query executed
-               *************************/
+               // ************************
 
                if ($this->_queryID === false) { // error handling if query fails
                        if ($this->debug == 99) adodb_backtrace(true,5);
 
 
        /**
-       * Will select, getting rows from $offset (1-based), for $nrows.
-       * This simulates the MySQL "select * from table limit $offset,$nrows" , and
-       * the PostgreSQL "select * from table limit $nrows offset $offset". Note that
-       * MySQL and PostgreSQL parameter ordering is the opposite of the other.
-       * eg.
-       *  SelectLimit('select * from table',3); will return rows 1 to 3 (1-based)
-       *  SelectLimit('select * from table',3,2); will return rows 3 to 5 (1-based)
-       *
-       * Uses SELECT TOP for Microsoft databases (when $this->hasTop is set)
-       * BUG: Currently SelectLimit fails with $sql with LIMIT or TOP clause already set
-       *
-       * @param sql
-       * @param [offset]       is the row to start calculations from (1-based)
-       * @param [nrows]                is the number of rows to get
-       * @param [inputarr]     array of bind variables
-       * @param [secs2cache]           is a private parameter only used by jlim
-       * @return               the recordset ($rs->databaseType == 'array')
-       */
+        * Will select, getting rows from $offset (1-based), for $nrows.
+        * This simulates the MySQL "select * from table limit $offset,$nrows" , and
+        * the PostgreSQL "select * from table limit $nrows offset $offset". Note that
+        * MySQL and PostgreSQL parameter ordering is the opposite of the other.
+        * eg.
+        *  SelectLimit('select * from table',3); will return rows 1 to 3 (1-based)
+        *  SelectLimit('select * from table',3,2); will return rows 3 to 5 (1-based)
+        *
+        * Uses SELECT TOP for Microsoft databases (when $this->hasTop is set)
+        * BUG: Currently SelectLimit fails with $sql with LIMIT or TOP clause already set
+        *
+        * @param sql
+        * @param [offset]      is the row to start calculations from (1-based)
+        * @param [nrows]               is the number of rows to get
+        * @param [inputarr]    array of bind variables
+        * @param [secs2cache]          is a private parameter only used by jlim
+        * @return              the recordset ($rs->databaseType == 'array')
+        */
        function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                if ($this->hasTop && $nrows > 0) {
 
 
        /**
-       * Will select, getting rows from $offset (1-based), for $nrows.
-       * This simulates the MySQL "select * from table limit $offset,$nrows" , and
-       * the PostgreSQL "select * from table limit $nrows offset $offset". Note that
-       * MySQL and PostgreSQL parameter ordering is the opposite of the other.
-       * eg.
-       *  CacheSelectLimit(15,'select * from table',3); will return rows 1 to 3 (1-based)
-       *  CacheSelectLimit(15,'select * from table',3,2); will return rows 3 to 5 (1-based)
-       *
-       * BUG: Currently CacheSelectLimit fails with $sql with LIMIT or TOP clause already set
-       *
-       * @param [secs2cache]   seconds to cache data, set to 0 to force query. This is optional
-       * @param sql
-       * @param [offset]       is the row to start calculations from (1-based)
-       * @param [nrows]        is the number of rows to get
-       * @param [inputarr]     array of bind variables
-       * @return               the recordset ($rs->databaseType == 'array')
-       */
+        * Will select, getting rows from $offset (1-based), for $nrows.
+        * This simulates the MySQL "select * from table limit $offset,$nrows" , and
+        * the PostgreSQL "select * from table limit $nrows offset $offset". Note that
+        * MySQL and PostgreSQL parameter ordering is the opposite of the other.
+        * eg.
+        *  CacheSelectLimit(15,'select * from table',3); will return rows 1 to 3 (1-based)
+        *  CacheSelectLimit(15,'select * from table',3,2); will return rows 3 to 5 (1-based)
+        *
+        * BUG: Currently CacheSelectLimit fails with $sql with LIMIT or TOP clause already set
+        *
+        * @param [secs2cache]  seconds to cache data, set to 0 to force query. This is optional
+        * @param sql
+        * @param [offset]      is the row to start calculations from (1-based)
+        * @param [nrows]       is the number of rows to get
+        * @param [inputarr]    array of bind variables
+        * @return              the recordset ($rs->databaseType == 'array')
+        */
        function CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
        {
                if (!is_numeric($secs2cache)) {
 
 
        /**
-       * Flush cached recordsets that match a particular $sql statement.
-       * If $sql == false, then we purge all files in the cache.
-       */
+        * Flush cached recordsets that match a particular $sql statement.
+        * If $sql == false, then we purge all files in the cache.
+        */
 
        /**
-   * Flush cached recordsets that match a particular $sql statement.
-   * If $sql == false, then we purge all files in the cache.
-    */
+        * Flush cached recordsets that match a particular $sql statement.
+        * If $sql == false, then we purge all files in the cache.
+        */
        function CacheFlush($sql=false,$inputarr=false)
        {
        global $ADODB_CACHE_DIR, $ADODB_CACHE;
 
 
        /**
-       * Private function to generate filename for caching.
-       * Filename is generated based on:
-       *
-       *  - sql statement
-       *  - database type (oci8, ibase, ifx, etc)
-       *  - database name
-       *  - userid
-       *  - setFetchMode (adodb 4.23)
-       *
-       * When not in safe mode, we create 256 sub-directories in the cache directory ($ADODB_CACHE_DIR).
-       * Assuming that we can have 50,000 files per directory with good performance,
-       * then we can scale to 12.8 million unique cached recordsets. Wow!
-       */
+        * Private function to generate filename for caching.
+        * Filename is generated based on:
+        *
+        *  - sql statement
+        *  - database type (oci8, ibase, ifx, etc)
+        *  - database name
+        *  - userid
+        *  - setFetchMode (adodb 4.23)
+        *
+        * When not in safe mode, we create 256 sub-directories in the cache directory ($ADODB_CACHE_DIR).
+        * Assuming that we can have 50,000 files per directory with good performance,
+        * then we can scale to 12.8 million unique cached recordsets. Wow!
+        */
        function _gencachename($sql,$createdir)
        {
        global $ADODB_CACHE, $ADODB_CACHE_DIR;
         *               be a simple select stmt with no groupby/orderby/limit
         *
         * "Jonathan Younger" <jyounger@unilab.com>
-        */
+        */
        function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=null)
        {
                global $ADODB_INCLUDED_LIB;
 
-        //********************************************************//
-        //This is here to maintain compatibility
-        //with older adodb versions. Sets force type to force nulls if $forcenulls is set.
+               // ********************************************************
+               // This is here to maintain compatibility
+               // with older adodb versions. Sets force type to force nulls if $forcenulls is set.
                if (!isset($force)) {
                                global $ADODB_FORCE_TYPE;
                            $force = $ADODB_FORCE_TYPE;
                }
-               //********************************************************//
+               // ********************************************************
 
                if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
                return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force);
         * that should be assigned.
         *
         * Note: This function should only be used on a recordset
-        *         that is run against a single table.
-        */
+        *       that is run against a single table.
+        */
        function GetInsertSQL(&$rs, $arrFields,$magicq=false,$force=null)
        {
                global $ADODB_INCLUDED_LIB;
@@ -2282,28 +2279,27 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        return false;
                }
 
-         /**
-      * List procedures or functions in an array.
-      * @param procedureNamePattern  a procedure name pattern; must match the procedure name as it is stored in the database
-      * @param catalog a catalog name; must match the catalog name as it is stored in the database;
-      * @param schemaPattern a schema name pattern;
-      *
-      * @return array of procedures on current database.
-
-                Array (
-                   [name_of_procedure] => Array
-                     (
-                     [type] => PROCEDURE or FUNCTION
-                     [catalog] => Catalog_name
-                     [schema] => Schema_name
-                     [remarks] => explanatory comment on the procedure
-                     )
-                 )
-      */
-     function MetaProcedures($procedureNamePattern = null, $catalog  = null, $schemaPattern  = null)
-     {
-            return false;
-     }
+       /**
+        * List procedures or functions in an array.
+        * @param procedureNamePattern  a procedure name pattern; must match the procedure name as it is stored in the database
+        * @param catalog a catalog name; must match the catalog name as it is stored in the database;
+        * @param schemaPattern a schema name pattern;
+        *
+        * @return array of procedures on current database.
+        *
+        * Array(
+        *   [name_of_procedure] => Array(
+        *     [type] => PROCEDURE or FUNCTION
+        *     [catalog] => Catalog_name
+        *     [schema] => Schema_name
+        *     [remarks] => explanatory comment on the procedure
+        *   )
+        * )
+        */
+       function MetaProcedures($procedureNamePattern = null, $catalog  = null, $schemaPattern  = null)
+       {
+               return false;
+       }
 
 
        /**
@@ -2419,29 +2415,28 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $false;
        }
 
-    /**
-      * List indexes on a table as an array.
-      * @param table  table name to query
-      * @param primary true to only show primary keys. Not actually used for most databases
-         *
-      * @return array of indexes on current table. Each element represents an index, and is itself an associative array.
-
-                Array (
-                   [name_of_index] => Array
-                     (
-                 [unique] => true or false
-                 [columns] => Array
-                 (
-                       [0] => firstname
-                       [1] => lastname
-                 )
-               )
-      */
-     function MetaIndexes($table, $primary = false, $owner = false)
-     {
-                       $false = false;
-            return $false;
-     }
+       /**
+        * List indexes on a table as an array.
+        * @param table  table name to query
+        * @param primary true to only show primary keys. Not actually used for most databases
+        *
+        * @return array of indexes on current table. Each element represents an index, and is itself an associative array.
+        *
+        * Array(
+        *   [name_of_index] => Array(
+        *     [unique] => true or false
+        *     [columns] => Array(
+        *       [0] => firstname
+        *       [1] => lastname
+        *     )
+        *   )
+        * )
+        */
+       function MetaIndexes($table, $primary = false, $owner = false)
+       {
+               $false = false;
+               return $false;
+       }
 
        /**
         * List columns names in a table as an array.
@@ -2721,9 +2716,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        /**
        * Will select the supplied $page number from a recordset, given that it is paginated in pages of
        * $nrows rows per page. It also saves two boolean values saying if the given page is the first
-       * and/or last one of the recordset. Added by Ivn Oliva to provide recordset pagination.
+       * and/or last one of the recordset. Added by Iván Oliva to provide recordset pagination.
        *
-       * See readme.htm#ex8 for an example of usage.
+       * See docs-adodb.htm#ex8 for an example of usage.
        *
        * @param sql
        * @param nrows          is the number of rows per page to get
@@ -2748,7 +2743,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        /**
        * Will select the supplied $page number from a recordset, given that it is paginated in pages of
        * $nrows rows per page. It also saves two boolean values saying if the given page is the first
-       * and/or last one of the recordset. Added by Ivn Oliva to provide recordset pagination.
+       * and/or last one of the recordset. Added by Iván Oliva to provide recordset pagination.
        *
        * @param secs2cache     seconds to cache data, set to 0 to force query
        * @param sql
@@ -2910,7 +2905,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 
 
 
-   /**
+       /**
         * RecordSet class that represents the dataset returned by the database.
         * To keep memory overhead low, this class holds only the current row in memory.
         * No prefetching of data is done, so the RecordCount() can return -1 ( which
@@ -2948,9 +2943,9 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
        var $_obj;                              /** Used by FetchObj */
        var $_names;                    /** Used by FetchObj */
 
-       var $_currentPage = -1; /** Added by Ivn Oliva to implement recordset pagination */
-       var $_atFirstPage = false;      /** Added by Ivn Oliva to implement recordset pagination */
-       var $_atLastPage = false;       /** Added by Ivn Oliva to implement recordset pagination */
+       var $_currentPage = -1; /** Added by Iván Oliva to implement recordset pagination */
+       var $_atFirstPage = false;      /** Added by Iván Oliva to implement recordset pagination */
+       var $_atLastPage = false;       /** Added by Iván Oliva to implement recordset pagination */
        var $_lastPageNo = -1;
        var $_maxRecordCount = 0;
        var $datetime = false;
@@ -2968,8 +2963,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 
        function getIterator()
        {
-        return new ADODB_Iterator($this);
-    }
+               return new ADODB_Iterator($this);
+       }
 
        /* this is experimental - i don't really know what to return... */
        function __toString()
@@ -3161,7 +3156,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                        $false = false;
                        return $false;
                }
-               $numIndex = isset($this->fields[0]) && isset($this->fields[1]);
+               $numIndex = is_array($this->fields) && array_key_exists(0, $this->fields);
                $results = array();
 
                if (!$first2cols && ($cols > 2 || $force_array)) {
@@ -3483,38 +3478,56 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                return $this->fields[$colname];
        }
 
-       function GetAssocKeys($upper=true)
+       /**
+        * Builds the bind array associating keys to recordset fields
+        *
+        * @param int $upper Case for the array keys, defaults to uppercase
+        *                   (see ADODB_ASSOC_CASE_xxx constants)
+        */
+       function GetAssocKeys($upper=ADODB_ASSOC_CASE_UPPER)
        {
                $this->bind = array();
                for ($i=0; $i < $this->_numOfFields; $i++) {
                        $o = $this->FetchField($i);
-                       if ($upper === 2) $this->bind[$o->name] = $i;
-                       else $this->bind[($upper) ? strtoupper($o->name) : strtolower($o->name)] = $i;
+                       switch($upper) {
+                               case ADODB_ASSOC_CASE_LOWER:
+                                       $key = strtolower($o->name);
+                                       break;
+                               case ADODB_ASSOC_CASE_UPPER:
+                                       $key = strtoupper($o->name);
+                                       break;
+                               case ADODB_ASSOC_CASE_NATIVE:
+                               default:
+                                       $key = $o->name;
+                                       break;
+                       }
+                       $val = $this->fetchMode == ADODB_FETCH_ASSOC ? $o->name : $i;
+                       $this->bind[$key] = $val;
                }
        }
 
-  /**
-   * Use associative array to get fields array for databases that do not support
-   * associative arrays. Submitted by Paolo S. Asioli paolo.asioli#libero.it
-   *
-   * If you don't want uppercase cols, set $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC
-   * before you execute your SQL statement, and access $rs->fields['col'] directly.
-   *
-   * $upper  0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField
-   */
-       function GetRowAssoc($upper=1)
+       /**
+        * Use associative array to get fields array for databases that do not support
+        * associative arrays. Submitted by Paolo S. Asioli paolo.asioli#libero.it
+        *
+        * @param int $upper Case for the array keys, defaults to uppercase
+        *                   (see ADODB_ASSOC_CASE_xxx constants)
+        */
+       function GetRowAssoc($upper=ADODB_ASSOC_CASE_UPPER)
        {
                $record = array();
                if (!$this->bind) {
                        $this->GetAssocKeys($upper);
                }
                foreach($this->bind as $k => $v) {
-                       if( isset( $this->fields[$v] ) ) {
+                       if( array_key_exists( $v, $this->fields ) ) {
                                $record[$k] = $this->fields[$v];
-                       } else if (isset($this->fields[$k])) {
+                       } elseif( array_key_exists( $k, $this->fields ) ) {
                                $record[$k] = $this->fields[$k];
-                       } else
-                               $record[$k] = $this->fields[$v];
+                       } else {
+                               # This should not happen... trigger error ?
+                               $record[$k] = null;
+                       }
                }
                return $record;
        }
@@ -4166,11 +4179,17 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                                if (PHP_VERSION >= 5) $db = 'ado5';
                                $class = 'ado';
                                break;
+
                        case 'ifx':
-                       case 'maxsql': $class = $db = 'mysqlt'; break;
+                       case 'maxsql':
+                               $class = $db = 'mysqlt';
+                               break;
+
+                       case 'pgsql':
                        case 'postgres':
-                       case 'postgres8':
-                       case 'pgsql': $class = $db = 'postgres7'; break;
+                               $class = $db = 'postgres8';
+                               break;
+
                        default:
                                $class = $db; break;
                }
@@ -4218,17 +4237,18 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
                                $fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn);
                        }
 
-                        if ((strpos($origdsn, 'sqlite')) !== FALSE && stripos($origdsn, '%2F') === FALSE) {
-             // special handling for SQLite, it only might have the path to the database file.
-             // If you try to connect to a SQLite database using a dsn like 'sqlite:///path/to/database', the 'parse_url' php function
-             // will throw you an exception with a message such as "unable to parse url"
-                list($scheme, $path) = explode('://', $origdsn);
-                $dsna['scheme'] = $scheme;
+                       if ((strpos($origdsn, 'sqlite')) !== FALSE && stripos($origdsn, '%2F') === FALSE) {
+                               // special handling for SQLite, it only might have the path to the database file.
+                               // If you try to connect to a SQLite database using a dsn
+                               // like 'sqlite:///path/to/database', the 'parse_url' php function
+                               // will throw you an exception with a message such as "unable to parse url"
+                               list($scheme, $path) = explode('://', $origdsn);
+                               $dsna['scheme'] = $scheme;
                                if ($qmark = strpos($path,'?')) {
                                        $dsn['query'] = substr($path,$qmark+1);
                                        $path = substr($path,0,$qmark);
                                }
-               $dsna['path'] = '/' . urlencode($path);
+                               $dsna['path'] = '/' . urlencode($path);
                        } else
                                $dsna = @parse_url($fakedsn);
 
@@ -4478,4 +4498,3 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1
 
 
 }
-?>
diff --git a/typo3/sysext/adodb/adodb/composer.json b/typo3/sysext/adodb/adodb/composer.json
new file mode 100644 (file)
index 0000000..73eedb5
--- /dev/null
@@ -0,0 +1,33 @@
+{
+       "name" : "adodb/adodb-php",
+       "description" : "ADOdb is a PHP database abstraction layer library",
+       "license" : [ "LGPL-2.1", " BSD-2-Clause" ],
+       "authors" : [
+               {
+                       "name": "John Lim",
+                       "email" : "jlim@natsoft.com",
+                       "role": "Author"
+               },
+               {
+                       "name": "Damien Regad",
+                       "role": "Current maintainer"
+               }
+       ],
+
+       "keywords" : [ "database" ],
+
+       "homepage": "http://adodb.sourceforge.net/",
+       "support" : {
+               "issues" : "https://github.com/ADOdb/ADOdb/issues",
+               "source" : "https://github.com/ADOdb/ADOdb"
+       },
+
+       "require" : {
+               "php" : ">=5.3.2"
+       },
+
+       "autoload" : {
+               "files" : ["adodb.inc.php"]
+       }
+
+}
index 4a3ad15..6a0a2cd 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -77,20 +77,17 @@ class ADODB2_access extends ADODB_DataDict {
        {
        }
 
-       function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
+       function AlterColumnSQL($tabname, $flds)
        {
                if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
                return array();
        }
 
 
-       function DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
+       function DropColumnSQL($tabname, $flds)
        {
                if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
                return array();
        }
 
 }
-
-
-?>
\ No newline at end of file
index 59c5f16..95a693f 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -139,6 +139,3 @@ class ADODB2_db2 extends ADODB_DataDict {
        }
 
 }
-
-
-?>
\ No newline at end of file
index 93e6abc..d4471df 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -147,6 +147,3 @@ end;
        }
 
 }
-
-
-?>
\ No newline at end of file
index b5ec876..e6336da 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -123,4 +123,3 @@ function ActualType($meta)
                }
        }
 */
-?>
\ No newline at end of file
index 72d3a1d..e08ae3c 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -63,6 +63,3 @@ class ADODB2_ibase extends ADODB_DataDict {
        }
 
 }
-
-
-?>
\ No newline at end of file
index b3f3de9..76c7585 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -77,5 +77,3 @@ class ADODB2_informix extends ADODB_DataDict {
        }
 
 }
-
-?>
\ No newline at end of file
index bed4377..3374ebd 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -52,7 +52,7 @@ class ADODB2_mssql extends ADODB_DataDict {
 
        //var $alterCol = ' ALTER COLUMN ';
 
-       function MetaType($t, $len=-1, $fieldobj=false)
+       function MetaType($t,$len=-1,$fieldobj=false)
        {
                if (is_object($t)) {
                        $fieldobj = $t;
@@ -281,4 +281,3 @@ CREATE TABLE
 
        }
 }
-?>
\ No newline at end of file
index 12e2ed8..0741c79 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -43,16 +43,15 @@ if (!defined('ADODB_DIR')) die();
 
 class ADODB2_mssqlnative extends ADODB_DataDict {
        var $databaseType = 'mssqlnative';
-       var $dropIndex = 'DROP INDEX %2$s.%1$s';
+       var $dropIndex = 'DROP INDEX %1$s ON %2$s';
        var $renameTable = "EXEC sp_rename '%s','%s'";
        var $renameColumn = "EXEC sp_rename '%s.%s','%s'";
-
        var $typeX = 'TEXT';  ## Alternatively, set it to VARCHAR(4000)
        var $typeXL = 'TEXT';
 
        //var $alterCol = ' ALTER COLUMN ';
 
-       function MetaType($t, $len=-1, $fieldobj=false)
+       function MetaType($t,$len=-1,$fieldobj=false)
        {
                if (is_object($t)) {
                        $fieldobj = $t;
@@ -60,24 +59,47 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
                        $len = $fieldobj->max_length;
                }
 
-               $len = -1; // mysql max_length is not accurate
-               switch (strtoupper($t)) {
-               case 'R':
-               case 'INT':
-               case 'INTEGER': return  'I';
-               case 'BIT':
-               case 'TINYINT': return  'I1';
-               case 'SMALLINT': return 'I2';
-               case 'BIGINT':  return  'I8';
-
-               case 'REAL':
-               case 'FLOAT': return 'F';
-               default: return parent::MetaType($t,$len,$fieldobj);
-               }
+               $_typeConversion = array(
+                       -155 => 'D',
+                         93 => 'D',
+                       -154 => 'D',
+                         -2 => 'D',
+                         91 => 'D',
+
+                         12 => 'C',
+                          1 => 'C',
+                         -9 => 'C',
+                         -8 => 'C',
+
+                         -7 => 'L',
+                         -6 => 'I2',
+                         -5 => 'I8',
+                        -11 => 'I',
+                          4 => 'I',
+                          5 => 'I4',
+
+                         -1 => 'X',
+                        -10 => 'X',
+
+                          2 => 'N',
+                          3 => 'N',
+                          6 => 'N',
+                          7 => 'N',
+
+                       -152 => 'X',
+                       -151 => 'X',
+                         -4 => 'X',
+                         -3 => 'X'
+                       );
+
+               return $_typeConversion($t);
+
        }
 
        function ActualType($meta)
        {
+               $DATE_TYPE = 'DATETIME';
+
                switch(strtoupper($meta)) {
 
                case 'C': return 'VARCHAR';
@@ -88,8 +110,8 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
 
                case 'B': return 'IMAGE';
 
-               case 'D': return 'DATETIME';
-               case 'T': return 'DATETIME';
+               case 'D': return $DATE_TYPE;
+               case 'T': return 'TIME';
                case 'L': return 'BIT';
 
                case 'R':
@@ -102,6 +124,7 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
                case 'F': return 'REAL';
                case 'N': return 'NUMERIC';
                default:
+                       print "RETURN $meta";
                        return $meta;
                }
        }
@@ -135,15 +158,26 @@ class ADODB2_mssqlnative extends ADODB_DataDict {
        }
        */
 
-       function DropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
+       /**
+        * Drop a column, syntax is ALTER TABLE table DROP COLUMN column,column
+        *
+        * @param string   $tabname      Table Name
+        * @param string[] $flds         One, or an array of Fields To Drop
+        * @param string   $tableflds    Throwaway value to make the function match the parent
+        * @param string   $tableoptions Throway value to make the function match the parent
+        *
+        * @return string  The SQL necessary to drop the column
+        */
+       function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
        {
                $tabname = $this->TableName ($tabname);
                if (!is_array($flds))
                        $flds = explode(',',$flds);
                $f = array();
-               $s = 'ALTER TABLE ' . $tabname;
+               $s = 'ALTER TABLE ' . $tabname . ' DROP COLUMN ';
                foreach($flds as $v) {
-                       $f[] = "\n$this->dropCol ".$this->NameQuote($v);
+                       //$f[] = "\n$this->dropCol ".$this->NameQuote($v);
+                       $f[] = $this->NameQuote($v);
                }
                $s .= implode(', ',$f);
                $sql[] = $s;
@@ -279,4 +313,3 @@ CREATE TABLE
 
        }
 }
-?>
\ No newline at end of file
index 2fec09a..773aa0c 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -179,4 +179,3 @@ class ADODB2_mysql extends ADODB_DataDict {
                return $sql;
        }
 }
-?>
\ No newline at end of file
index d270616..e499b87 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -24,7 +24,7 @@ class ADODB2_oci8 extends ADODB_DataDict {
        var $typeX = 'VARCHAR(4000)';
        var $typeXL = 'CLOB';
 
-       function MetaType($t, $len=-1, $fieldobj=false)
+       function MetaType($t,$len=-1, $fieldobj=false)
        {
                if (is_object($t)) {
                        $fieldobj = $t;
@@ -219,7 +219,7 @@ end;
                $seqStart = '';
                if (isset($tableoptions['SEQUENCE_START'])){$seqIncr = ' START WITH '.$tableoptions['SEQUENCE_START'];}
                $sql[] = "CREATE SEQUENCE $seqname $seqStart $seqIncr $seqCache";
-               $sql[] = "CREATE OR REPLACE TRIGGER $trigname BEFORE insert ON $tabname FOR EACH ROW WHEN (NEW.$this->seqField IS NULL OR NEW.$this->seqField = 0) BEGIN select $seqname.nextval into :new.$this->seqField from dual; END";
+               $sql[] = "CREATE OR REPLACE TRIGGER $trigname BEFORE insert ON $tabname FOR EACH ROW WHEN (NEW.$this->seqField IS NULL OR NEW.$this->seqField = 0) BEGIN select $seqname.nextval into :new.$this->seqField from dual; END;";
 
                $this->seqField = false;
                return $sql;
@@ -294,4 +294,3 @@ end;
                return  "COMMENT ON COLUMN $table.$col IS $cmt";
        }
 }
-?>
\ No newline at end of file
index 14e76de..965314d 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -182,80 +182,91 @@ class ADODB2_postgres extends ADODB_DataDict {
 
        function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
        {
-          // Check if alter single column datatype available - works with 8.0+
-          $has_alter_column = 8.0 <= (float) @$this->serverInfo['version'];
-
-          if ($has_alter_column) {
-             $tabname = $this->TableName($tabname);
-             $sql = array();
-             list($lines,$pkey) = $this->_GenFields($flds);
-                 $set_null = false;
-             $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
-             foreach($lines as $v) {
-               if ($not_null = preg_match('/NOT NULL/i',$v)) {
-                   $v = preg_replace('/NOT NULL/i','',$v);
-               }
-                // this next block doesn't work - there is no way that I can see to
-                // explicitly ask a column to be null using $flds
-               else if ($set_null = preg_match('/NULL/i',$v)) {
-                   // if they didn't specify not null, see if they explicitely asked for null
-                   $v = preg_replace('/\sNULL/i','',$v);
-               }
-
-                       if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
-                               $existing = $this->MetaColumns($tabname);
-                               list(,$colname,$default) = $matches;
-                               if ($this->connection) $old_coltype = $this->connection->MetaType($existing[strtoupper($colname)]);
-                               else $old_coltype = $t;
-                               $v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v);
-                               $t = trim(str_replace('DEFAULT '.$default,'',$v));
-
-                               // Type change from bool to int
-                               if ( $old_coltype == 'L' && $t == 'INTEGER' ) {
-                                       $sql[] = $alter . $colname . ' DROP DEFAULT';
-                                       $sql[] = $alter . $colname . " TYPE $t USING ($colname::BOOL)::INT";
-                                       $sql[] = $alter . $colname . " SET DEFAULT $default";
+               // Check if alter single column datatype available - works with 8.0+
+               $has_alter_column = 8.0 <= (float) @$this->serverInfo['version'];
+
+               if ($has_alter_column) {
+                       $tabname = $this->TableName($tabname);
+                       $sql = array();
+                       list($lines,$pkey) = $this->_GenFields($flds);
+                       $set_null = false;
+                       $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
+                       foreach($lines as $v) {
+                               if ($not_null = preg_match('/NOT NULL/i',$v)) {
+                                       $v = preg_replace('/NOT NULL/i','',$v);
+                               }
+                                // this next block doesn't work - there is no way that I can see to
+                                // explicitly ask a column to be null using $flds
+                               else if ($set_null = preg_match('/NULL/i',$v)) {
+                                       // if they didn't specify not null, see if they explicitely asked for null
+                                       // Lookbehind pattern covers the case 'fieldname NULL datatype DEFAULT NULL'
+                                       // only the first NULL should be removed, not the one specifying
+                                       // the default value
+                                       $v = preg_replace('/(?<!DEFAULT)\sNULL/i','',$v);
                                }
-                               // Type change from int to bool
-                               else if ( $old_coltype == 'I' && $t == 'BOOLEAN' ) {
-                                       $sql[] = $alter . $colname . ' DROP DEFAULT';
-                                       $sql[] = $alter . $colname . " TYPE $t USING CASE WHEN $colname = 0 THEN false ELSE true END";
-                                       $sql[] = $alter . $colname . " SET DEFAULT " . $this->connection->qstr($default);
+
+                               if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) {
+                                       $existing = $this->MetaColumns($tabname);
+                                       list(,$colname,$default) = $matches;
+                                       $alter .= $colname;
+                                       if ($this->connection) {
+                                               $old_coltype = $this->connection->MetaType($existing[strtoupper($colname)]);
+                                       }
+                                       else {
+                                               $old_coltype = $t;
+                                       }
+                                       $v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v);
+                                       $t = trim(str_replace('DEFAULT '.$default,'',$v));
+
+                                       // Type change from bool to int
+                                       if ( $old_coltype == 'L' && $t == 'INTEGER' ) {
+                                               $sql[] = $alter . ' DROP DEFAULT';
+                                               $sql[] = $alter . " TYPE $t USING ($colname::BOOL)::INT";
+                                               $sql[] = $alter . " SET DEFAULT $default";
+                                       }
+                                       // Type change from int to bool
+                                       else if ( $old_coltype == 'I' && $t == 'BOOLEAN' ) {
+                                               if( strcasecmp('NULL', trim($default)) != 0 ) {
+                                                       $default = $this->connection->qstr($default);
+                                               }
+                                               $sql[] = $alter . ' DROP DEFAULT';
+                                               $sql[] = $alter . " TYPE $t USING CASE WHEN $colname = 0 THEN false ELSE true END";
+                                               $sql[] = $alter . " SET DEFAULT $default";
+                                       }
+                                       // Any other column types conversion
+                                       else {
+                                               $sql[] = $alter . " TYPE $t";
+                                               $sql[] = $alter . " SET DEFAULT $default";
+                                       }
+
                                }
-                               // Any other column types conversion
                                else {
-                                       $sql[] = $alter . $colname . " TYPE $t";
-                                       $sql[] = $alter . $colname . " SET DEFAULT $default";
+                                       // drop default?
+                                       preg_match ('/^\s*(\S+)\s+(.*)$/',$v,$matches);
+                                       list (,$colname,$rest) = $matches;
+                                       $alter .= $colname;
+                                       $sql[] = $alter . ' TYPE ' . $rest;
                                }
 
+#                              list($colname) = explode(' ',$v);
+                               if ($not_null) {
+                                       // this does not error out if the column is already not null
+                                       $sql[] = $alter . ' SET NOT NULL';
+                               }
+                               if ($set_null) {
+                                       // this does not error out if the column is already null
+                                       $sql[] = $alter . ' DROP NOT NULL';
+                               }
+                       }
+                       return $sql;
+               }
 
-                }
-                else {
-                   // drop default?
-                   preg_match ('/^\s*(\S+)\s+(.*)$/',$v,$matches);
-                   list (,$colname,$rest) = $matches;
-                   $sql[] = $alter . $colname . ' TYPE ' . $rest;
-                }
-
-#               list($colname) = explode(' ',$v);
-                if ($not_null) {
-                   // this does not error out if the column is already not null
-                               $sql[] = $alter . $colname . ' SET NOT NULL';
-                }
-                if ($set_null) {
-                   // this does not error out if the column is already null
-                   $sql[] = $alter . $colname . ' DROP NOT NULL';
-                }
-             }
-             return $sql;
-          }
-
-          // does not have alter column
-          if (!$tableflds) {
-             if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
-             return array();
-          }
-          return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
+               // does not have alter column
+               if (!$tableflds) {
+                       if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
+                       return array();
+               }
+               return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions);
        }
 
        /**
@@ -277,7 +288,7 @@ class ADODB2_postgres extends ADODB_DataDict {
                return array();
        }
                if ($has_drop_column) {
-                       return ADODB_DataDict::DropColumnSQL($tabname, $flds, $tableflds, $tableoptions);
+                       return ADODB_DataDict::DropColumnSQL($tabname, $flds);
                }
                return $this->_recreate_copy_table($tabname,$flds,$tableflds,$tableoptions);
        }
@@ -469,4 +480,3 @@ CREATE [ UNIQUE ] INDEX index_name ON table
                return $ftype;
        }
 }
-?>
\ No newline at end of file
index 554d92e..8241b20 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V4.50 6 July 2004  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -50,7 +50,7 @@ class ADODB2_sapdb extends ADODB_DataDict {
                }
        }
 
-       function MetaType($t, $len=-1, $fieldobj=false)
+       function MetaType($t,$len=-1,$fieldobj=false)
        {
                if (is_object($t)) {
                        $fieldobj = $t;
@@ -118,5 +118,3 @@ class ADODB2_sapdb extends ADODB_DataDict {
                return array( 'ALTER TABLE ' . $tabname . ' DROP (' . implode(', ',$flds) . ')' );
        }
 }
-
-?>
\ No newline at end of file
index 13c1e9c..5ff76b9 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -86,4 +86,3 @@ class ADODB2_sqlite extends ADODB_DataDict {
        }
 
 }
-?>
index 2ee42ea..b2118fd 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -18,7 +18,7 @@ class ADODB2_sybase extends ADODB_DataDict {
 
        var $dropIndex = 'DROP INDEX %2$s.%1$s';
 
-       function MetaType($t, $len=-1, $fieldobj=false)
+       function MetaType($t,$len=-1,$fieldobj=false)
        {
                if (is_object($t)) {
                        $fieldobj = $t;
@@ -226,4 +226,3 @@ CREATE TABLE
                return $sql;
        }
 }
-?>
\ No newline at end of file
index c456c45..a0932a0 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -84,4 +84,3 @@ class  ADORecordSet_access extends ADORecordSet_odbc {
        }
 }// class
 }
-?>
\ No newline at end of file
index 25c87f7..2c312f7 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -656,5 +656,3 @@ class ADORecordSet_ado extends ADORecordSet {
        }
 
 }
-
-?>
\ No newline at end of file
index c8c96a8..9f5cea2 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -704,5 +704,3 @@ class ADORecordSet_ado extends ADORecordSet {
        }
 
 }
-
-?>
\ No newline at end of file
index 8223ec3..ad8a982 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
 Released under both BSD license and Lesser GPL library license.
 Whenever there is any discrepancy between the two licenses,
 the BSD license will take precedence. See License.txt.
@@ -51,4 +51,3 @@ class  ADORecordSet_ado_access extends ADORecordSet_ado {
                return $this->ADORecordSet_ado($id,$mode);
        }
 }
-?>
\ No newline at end of file
index 4edb1df..c03c0fa 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -151,4 +151,3 @@ class  ADODB_ado_mssql extends ADODB_ado {
                return $this->ADORecordSet_ado($id,$mode);
        }
 }
-?>
\ No newline at end of file
index 0de57ca..4481d2b 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+  (c) 2000-2014 John Lim (jlim#natsoft.com.my). All rights reserved.
   Portions Copyright (c) 2007-2009, iAnywhere Solutions, Inc.
   All rights reserved. All unpublished rights reserved.
 
@@ -749,18 +749,8 @@ class ADORecordSet_ads extends ADORecordSet {
   {
     if ($this->_numOfRows != 0 && !$this->EOF) {
       $this->_currentRow++;
-
-      if ($this->_has_stupid_odbc_fetch_api_change)
-        $rez = @ads_fetch_into($this->_queryID,$this->fields);
-      else {
-        $row = 0;
-        $rez = @ads_fetch_into($this->_queryID,$row,$this->fields);
-      }
-      if ($rez) {
-        if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-          $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
-        }
-        return true;
+      if( $this->_fetch() ) {
+          return true;
       }
     }
     $this->fields = false;
@@ -770,7 +760,7 @@ class ADORecordSet_ads extends ADORecordSet {
 
   function _fetch()
   {
-
+    $this->fields = false;
     if ($this->_has_stupid_odbc_fetch_api_change)
       $rez = @ads_fetch_into($this->_queryID,$this->fields);
     else {
@@ -783,7 +773,6 @@ class ADORecordSet_ads extends ADORecordSet {
       }
       return true;
     }
-    $this->fields = false;
     return false;
   }
 
@@ -793,4 +782,3 @@ class ADORecordSet_ads extends ADORecordSet {
   }
 
 }
-?>
\ No newline at end of file
index d909ca3..3338db7 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -89,4 +89,3 @@ class  ADORecordSet_borland_ibase extends ADORecordSet_ibase {
                $this->ADORecordSet_ibase($id,$mode);
        }
 }
-?>
\ No newline at end of file
index 2faee30..4fb2dcc 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -203,5 +203,3 @@ class ADORecordset_csv extends ADORecordset {
 }
 
 } // define
-
-?>
\ No newline at end of file
index a71e36a..d7ff91a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V5.18 3 Sep 2012  (c) 2000-2012 (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2012 (jlim#natsoft.com). All rights reserved.
 
   This is a version of the ADODB driver for DB2.  It uses the 'ibm_db2' PECL extension
   for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
@@ -845,4 +845,3 @@ class ADORecordSet_db2 extends ADORecordSet {
        }
 
 }
-?>
\ No newline at end of file
index f0c4113..b58ec1a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -227,4 +227,3 @@ class  ADORecordSet_db2oci extends ADORecordSet_db2 {
 }
 
 } //define
-?>
\ No newline at end of file
index 52b013f..ebcdab6 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -77,4 +77,3 @@ class  ADORecordSet_db2oci extends ADORecordSet_odbc {
 }
 
 } //define
-?>
\ No newline at end of file
index ee9fb93..5695707 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- @version V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
  Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -263,4 +263,3 @@ class ADORecordSet_fbsql extends ADORecordSet{
 
 } //class
 } // defined
-?>
\ No newline at end of file
index a6bbd5d..2e0917d 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -74,4 +74,3 @@ class  ADORecordSet_firebird extends ADORecordSet_ibase {
                $this->ADORecordSet_ibase($id,$mode);
        }
 }
-?>
\ No newline at end of file
index fa217f0..a638f58 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -884,4 +884,3 @@ class ADORecordset_ibase extends ADORecordSet
        }
 
 }
-?>
\ No newline at end of file
index 7b8bc2d..93205a8 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+* @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
 * Released under both BSD license and Lesser GPL library license.
 * Whenever there is any discrepancy between the two licenses,
 * the BSD license will take precedence.
@@ -37,4 +37,3 @@ class ADORecordset_informix extends ADORecordset_informix72 {
                $this->ADORecordset_informix72($id,$mode);
        }
 }
-?>
\ No newline at end of file
index f86cd90..267407b 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim. All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim. All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -515,6 +515,3 @@ function ifx_props($coltype,$collength){
        }
        return array($mtype,$length,$precision,$nullable);
 }
-
-
-?>
\ No newline at end of file
index 5e32791..720f469 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
    Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -420,4 +420,3 @@ class ADORecordSet_ldap extends ADORecordSet{
        }
 
 }
-?>
\ No newline at end of file
index 243b620..58a0259 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -76,7 +76,7 @@ class ADODB_mssql extends ADOConnection {
        var $dataProvider = "mssql";
        var $replaceQuote = "''"; // string to use to replace quotes
        var $fmtDate = "'Y-m-d'";
-       var $fmtTimeStamp = "'Y-m-d H:i:s'";
+       var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
        var $hasInsertID = true;
        var $substr = "substring";
        var $length = 'len';
@@ -1170,5 +1170,3 @@ order by constraint_name, ordinal_position
 
 http://www.databasejournal.com/scripts/article.php/1440551
 */
-
-?>
\ No newline at end of file
index 017133f..69338b4 100644 (file)
@@ -9,7 +9,7 @@
 // ADOdb  - Database Abstraction Library for PHP                         //
 //          http://adodb.sourceforge.net/                                //
 //                                                                       //
-// Copyright (c) 2000-2012 John Lim (jlim\@natsoft.com.my)               //
+// Copyright (c) 2000-2014 John Lim (jlim\@natsoft.com.my)               //
 //          All rights reserved.                                         //
 //          Released under both BSD license and LGPL library license.    //
 //          Whenever there is any discrepancy between the two licenses,  //
@@ -168,4 +168,3 @@ class ADORecordset_mssql_n extends ADORecordset_mssql {
                $this->ADORecordset_mssql($id,$mode);
        }
 }
-?>
\ No newline at end of file
index 7ff7bae..b10d555 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -78,32 +78,12 @@ if (ADODB_PHPVER >= 0x4300) {
                'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
 }
 
-//---------------------------------------------------------------------------
-// Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
-// just after you connect to the database. Supports mdy and dmy only.
-// Not required for PHP 4.2.0 and above.
-function AutoDetect_MSSQL_Date_Order($conn)
-{
-    global $ADODB_mssql_date_order;
-       $adate = $conn->GetOne('select getdate()');
-       if ($adate) {
-               $anum = (int) $adate;
-               if ($anum > 0) {
-                       if ($anum > 31) {
-                               //ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
-                       } else
-                               $ADODB_mssql_date_order = 'dmy';
-               } else
-                       $ADODB_mssql_date_order = 'mdy';
-       }
-}
-
 class ADODB_mssqlnative extends ADOConnection {
        var $databaseType = "mssqlnative";
        var $dataProvider = "mssqlnative";
        var $replaceQuote = "''"; // string to use to replace quotes
        var $fmtDate = "'Y-m-d'";
-       var $fmtTimeStamp = "'Y-m-d H:i:s'";
+       var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
        var $hasInsertID = true;
        var $substr = "substring";
        var $length = 'len';
@@ -111,11 +91,23 @@ class ADODB_mssqlnative extends ADOConnection {
        var $poorAffectedRows = false;
        var $metaDatabasesSQL = "select name from sys.sysdatabases where name <> 'master'";
        var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
-       var $metaColumnsSQL = # xtype==61 is datetime
-        "select c.name,t.name,c.length,
-           (case when c.xusertype=61 then 0 else c.xprec end),
-           (case when c.xusertype=61 then 0 else c.xscale end)
-           from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
+       var $metaColumnsSQL =
+               "select c.name,
+               t.name as type,
+               c.length,
+               c.xprec as precision,
+               c.xscale as scale,
+               c.isnullable as nullable,
+               c.cdefault as default_value,
+               c.xtype,
+               t.length as type_length,
+               sc.is_identity
+               from syscolumns c
+               join systypes t on t.xusertype=c.xusertype
+               join sysobjects o on o.id=c.id
+               join sys.tables st on st.name=o.name
+               join sys.columns sc on sc.object_id = st.object_id and sc.name=c.name
+               where o.name='%s'";
        var $hasTop = 'top';            // support mssql SELECT TOP 10 * FROM TABLE
        var $hasGenID = true;
        var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
@@ -131,6 +123,8 @@ class ADODB_mssqlnative extends ADOConnection {
        var $_bindInputArray = true;
        var $_dropSeqSQL = "drop table %s";
        var $connectionInfo = array();
+       var $sequences = false;
+       var $mssql_version = '';
 
        function ADODB_mssqlnative()
        {
@@ -147,15 +141,40 @@ class ADODB_mssqlnative extends ADOConnection {
             sqlsrv_configure('warnings_return_as_errors', 0);
         }
        }
+       function ServerVersion() {
+               $data = $this->ServerInfo();
+               if (preg_match('/^09/',$data['version'])){
+                       /*
+                        * SQL Server 2005
+                        */
+                       $this->mssql_version = 9;
+               } elseif (preg_match('/^10/',$data['version'])){
+                       /*
+                        * SQL Server 2008
+                        */
+                       $this->mssql_version = 10;
+               } elseif (preg_match('/^11/',$data['version'])){
+                       /*
+                        * SQL Server 2012
+                        */
+                       $this->mssql_version = 11;
+               } else
+                       die("SQL SERVER VERSION {$data['version']} NOT SUPPORTED IN mssqlnative DRIVER");
+       }
 
-       function ServerInfo()
-       {
+       function ServerInfo() {
        global $ADODB_FETCH_MODE;
+               static $arr = false;
+               if (is_array($arr))
+                       return $arr;
                if ($this->fetchMode === false) {
                        $savem = $ADODB_FETCH_MODE;
                        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+               } elseif ($this->fetchMode >=0 && $this->fetchMode <=2) {
+                       $savem = $this->fetchMode;
                } else
                        $savem = $this->SetFetchMode(ADODB_FETCH_NUM);
+
                $arrServerInfo = sqlsrv_server_info($this->_connectionID);
                $ADODB_FETCH_MODE = $savem;
                $arr['description'] = $arrServerInfo['SQLServerName'].' connected to '.$arrServerInfo['CurrentDatabase'];
@@ -175,49 +194,127 @@ class ADODB_mssqlnative extends ADOConnection {
        // the same scope. A scope is a module -- a stored procedure, trigger,
        // function, or batch. Thus, two statements are in the same scope if
        // they are in the same stored procedure, function, or batch.
-               return $this->GetOne($this->identitySQL);
+               return $this->lastInsertID;
        }
 
        function _affectedrows()
        {
-        return sqlsrv_rows_affected($this->_queryID);
+               if ($this->_queryID)
+               return sqlsrv_rows_affected($this->_queryID);
+       }
+
+       function GenID($seq='adodbseq',$start=1) {
+               if (!$this->mssql_version)
+                       $this->ServerVersion();
+               switch($this->mssql_version){
+               case 9:
+               case 10:
+                       return $this->GenID2008();
+                       break;
+               case 11:
+                       return $this->GenID2012();
+                       break;
+               }
        }
 
        function CreateSequence($seq='adodbseq',$start=1)
        {
+               if (!$this->mssql_vesion)
+                       $this->ServerVersion();
+
+               switch($this->mssql_version){
+               case 9:
+               case 10:
+                       return $this->CreateSequence2008();
+                       break;
+               case 11:
+                       return $this->CreateSequence2012();
+                       break;
+               }
+
+       }
+
+       /**
+        * For Server 2005,2008, duplicate a sequence with an identity table
+        */
+       function CreateSequence2008($seq='adodbseq',$start=1)
+       {
                if($this->debug) error_log("<hr>CreateSequence($seq,$start)");
-        sqlsrv_begin_transaction($this->_connectionID);
+               sqlsrv_begin_transaction($this->_connectionID);
                $start -= 1;
                $this->Execute("create table $seq (id int)");//was float(53)
                $ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
                if (!$ok) {
-            if($this->debug) error_log("<hr>Error: ROLLBACK");
-            sqlsrv_rollback($this->_connectionID);
+                       if($this->debug) error_log("<hr>Error: ROLLBACK");
+                       sqlsrv_rollback($this->_connectionID);
                        return false;
                }
-        sqlsrv_commit($this->_connectionID);
+               sqlsrv_commit($this->_connectionID);
                return true;
        }
 
-       function GenID($seq='adodbseq',$start=1)
+       /**
+        * Proper Sequences Only available to Server 2012 and up
+        */
+       function CreateSequence2012($seq='adodb',$start=1){
+               if (!$this->sequences){
+                       $sql = "SELECT name FROM sys.sequences";
+                       $this->sequences = $this->GetCol($sql);
+               }
+               $ok = $this->Execute("CREATE SEQUENCE $seq START WITH $start INCREMENT BY 1");
+               if (!$ok)
+                       die("CANNOT CREATE SEQUENCE" . print_r(sqlsrv_errors(),true));
+               $this->sequences[] = $seq;
+       }
+
+       /**
+        * For Server 2005,2008, duplicate a sequence with an identity table
+        */
+       function GenID2008($seq='adodbseq',$start=1)
        {
-        if($this->debug) error_log("<hr>GenID($seq,$start)");
-        sqlsrv_begin_transaction($this->_connectionID);
+               if($this->debug) error_log("<hr>CreateSequence($seq,$start)");
+               sqlsrv_begin_transaction($this->_connectionID);
                $ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
                if (!$ok) {
-                       $this->Execute("create table $seq (id int)");
+                       $start -= 1;
+                       $this->Execute("create table $seq (id int)");//was float(53)
                        $ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
                        if (!$ok) {
-                if($this->debug) error_log("<hr>Error: ROLLBACK");
-                sqlsrv_rollback($this->_connectionID);
+                               if($this->debug) error_log("<hr>Error: ROLLBACK");
+                               sqlsrv_rollback($this->_connectionID);
                                return false;
                        }
-                       sqlsrv_commit($this->_connectionID);
-                       return $start;
                }
                $num = $this->GetOne("select id from $seq");
-        sqlsrv_commit($this->_connectionID);
-        if($this->debug) error_log(" Returning: $num");
+               sqlsrv_commit($this->_connectionID);
+               return true;
+       }
+       /**
+        * Only available to Server 2012 and up
+        * Cannot do this the normal adodb way by trapping an error if the
+        * sequence does not exist because sql server will auto create a
+        * sequence with the starting number of -9223372036854775808
+        */
+       function GenID2012($seq='adodbseq',$start=1)
+       {
+
+               /*
+                * First time in create an array of sequence names that we
+                * can use in later requests to see if the sequence exists
+                * the overhead is creating a list of sequences every time
+                * we need access to at least 1. If we really care about
+                * performance, we could maybe flag a 'nocheck' class variable
+                */
+               if (!$this->sequences){
+                       $sql = "SELECT name FROM sys.sequences";
+                       $this->sequences = $this->GetCol($sql);
+               }
+               if (!is_array($this->sequences)
+               || is_array($this->sequences) && !in_array($seq,$this->sequences)){
+                       $this->CreateSequence2012($seq='adodbseq',$start=1);
+
+               }
+               $num = $this->GetOne("SELECT NEXT VALUE FOR $seq");
                return $num;
        }
 
@@ -286,15 +383,15 @@ class ADODB_mssqlnative extends ADOConnection {
        {
                if ($this->transOff) return true;
                $this->transCnt += 1;
-        if ($this->debug) error_log('<hr>begin transaction');
+               if ($this->debug) error_log('<hr>begin transaction');
                sqlsrv_begin_transaction($this->_connectionID);
-               return true;
+               return true;
        }
 
        function CommitTrans($ok=true)
        {
                if ($this->transOff) return true;
-        if ($this->debug) error_log('<hr>commit transaction');
+               if ($this->debug) error_log('<hr>commit transaction');
                if (!$ok) return $this->RollbackTrans();
                if ($this->transCnt) $this->transCnt -= 1;
                sqlsrv_commit($this->_connectionID);
@@ -303,7 +400,7 @@ class ADODB_mssqlnative extends ADOConnection {
        function RollbackTrans()
        {
                if ($this->transOff) return true;
-        if ($this->debug) error_log('<hr>rollback transaction');
+               if ($this->debug) error_log('<hr>rollback transaction');
                if ($this->transCnt) $this->transCnt -= 1;
                sqlsrv_rollback($this->_connectionID);
                return true;
@@ -344,10 +441,10 @@ class ADODB_mssqlnative extends ADOConnection {
                $this->database = $dbName;
                $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
                if ($this->_connectionID) {
-            $rs = $this->Execute('USE '.$dbName);
-            if($rs) {
-                return true;
-            } else return false;
+                       $rs = $this->Execute('USE '.$dbName);
+                       if($rs) {
+                               return true;
+                       } else return false;
                }
                else return false;
        }
@@ -371,8 +468,8 @@ class ADODB_mssqlnative extends ADOConnection {
        {
                if ($this->_logsql && $this->_errorCode !== false) return $this->_errorCode;
                $err = sqlsrv_errors(SQLSRV_ERR_ALL);
-        if($err[0]) return $err[0]['code'];
-        else return -1;
+               if($err[0]) return $err[0]['code'];
+               else return -1;
        }
 
        // returns true or false
@@ -383,14 +480,14 @@ class ADODB_mssqlnative extends ADOConnection {
                $connectionInfo["Database"]=$argDatabasename;
                $connectionInfo["UID"]=$argUsername;
                $connectionInfo["PWD"]=$argPassword;
-        if ($this->debug) error_log("<hr>connecting... hostname: $argHostname params: ".var_export($connectionInfo,true));
-        //if ($this->debug) error_log("<hr>_connectionID before: ".serialize($this->_connectionID));
-        if(!($this->_connectionID = sqlsrv_connect($argHostname,$connectionInfo))) {
-            if ($this->debug) error_log( "<hr><b>errors</b>: ".print_r( sqlsrv_errors(), true));
-            return false;
-        }
-        //if ($this->debug) error_log(" _connectionID after: ".serialize($this->_connectionID));
-        //if ($this->debug) error_log("<hr>defined functions: <pre>".var_export(get_defined_functions(),true)."</pre>");
+               if ($this->debug) error_log("<hr>connecting... hostname: $argHostname params: ".var_export($connectionInfo,true));
+               //if ($this->debug) error_log("<hr>_connectionID before: ".serialize($this->_connectionID));
+               if(!($this->_connectionID = sqlsrv_connect($argHostname,$connectionInfo))) {
+                       if ($this->debug) error_log( "<hr><b>errors</b>: ".print_r( sqlsrv_errors(), true));
+                       return false;
+               }
+               //if ($this->debug) error_log(" _connectionID after: ".serialize($this->_connectionID));
+               //if ($this->debug) error_log("<hr>defined functions: <pre>".var_export(get_defined_functions(),true)."</pre>");
                return true;
        }
 
@@ -398,7 +495,7 @@ class ADODB_mssqlnative extends ADOConnection {
        function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
        {
                //return null;//not implemented. NOTE: Persistent connections have no effect if PHP is used as a CGI program. (FastCGI!)
-        return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
+               return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
        }
 
        function Prepare($sql)
@@ -411,28 +508,28 @@ class ADODB_mssqlnative extends ADOConnection {
        }
 
        // returns concatenated string
-    // MSSQL requires integers to be cast as strings
-    // automatically cast every datatype to VARCHAR(255)
-    // @author David Rogers (introspectshun)
-    function Concat()
-    {
-        $s = "";
-        $arr = func_get_args();
-
-        // Split single record on commas, if possible
-        if (sizeof($arr) == 1) {
-            foreach ($arr as $arg) {
-                $args = explode(',', $arg);
-            }
-            $arr = $args;
-        }
+       // MSSQL requires integers to be cast as strings
+       // automatically cast every datatype to VARCHAR(255)
+       // @author David Rogers (introspectshun)
+       function Concat()
+       {
+               $s = "";
+               $arr = func_get_args();
+
+               // Split single record on commas, if possible
+               if (sizeof($arr) == 1) {
+                       foreach ($arr as $arg) {
+                               $args = explode(',', $arg);
+                       }
+                       $arr = $args;
+               }
 
-        array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
-        $s = implode('+',$arr);
-        if (sizeof($arr) > 0) return "$s";
+               array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";'));
+               $s = implode('+',$arr);
+               if (sizeof($arr) > 0) return "$s";
 
                return '';
-    }
+       }
 
        /*
                Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
@@ -461,16 +558,31 @@ class ADODB_mssqlnative extends ADOConnection {
        function _query($sql,$inputarr=false)
        {
                $this->_errorMsg = false;
-               if (is_array($inputarr)) {
-            $rez = sqlsrv_query($this->_connectionID,$sql,$inputarr);
-               } else if (is_array($sql)) {
-                       // $inputarr is prepared in sqlsrv_prepare();
-            $rez = sqlsrv_execute($this->_connectionID,$sql[1]);
+               
+               if (is_array($sql)) $sql = $sql[1];
+               
+               $insert = false;
+               // handle native driver flaw for retrieving the last insert ID
+               if(preg_match('/^\W*(insert [^;]+);?$/i', $sql)) {
+                       $insert = true;
+                       $sql .= '; '.$this->identitySQL; // select scope_identity()
+               }
+               if($inputarr) {
+                       $rez = sqlsrv_query($this->_connectionID, $sql, $inputarr);
                } else {
                        $rez = sqlsrv_query($this->_connectionID,$sql);
                }
-        if ($this->debug) error_log("<hr>running query: ".var_export($sql,true)."<hr>input array: ".var_export($inputarr,true)."<hr>result: ".var_export($rez,true));
-        if(!$rez) $rez = false;
+
+               if ($this->debug) error_log("<hr>running query: ".var_export($sql,true)."<hr>input array: ".var_export($inputarr,true)."<hr>result: ".var_export($rez,true));
+
+               if(!$rez) {
+                       $rez = false;
+               } else if ($insert) {
+                       // retrieve the last insert ID (where applicable)
+                       sqlsrv_next_result($rez);
+                       sqlsrv_fetch($rez);
+                       $this->lastInsertID = sqlsrv_get_field($rez, 0);
+               }
                return $rez;
        }
 
@@ -494,7 +606,7 @@ class ADODB_mssqlnative extends ADOConnection {
                return ADORecordSet_array_mssqlnative::UnixTimeStamp($v);
        }
 
-       function &MetaIndexes($table,$primary=false, $owner = false)
+       function MetaIndexes($table,$primary=false, $owner = false)
        {
                $table = $this->qstr($table);
 
@@ -509,47 +621,47 @@ class ADODB_mssqlnative extends ADOConnection {
 
                global $ADODB_FETCH_MODE;
                $save = $ADODB_FETCH_MODE;
-        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-        if ($this->fetchMode !== FALSE) {
-               $savem = $this->SetFetchMode(FALSE);
-        }
+               $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+               if ($this->fetchMode !== FALSE) {
+                       $savem = $this->SetFetchMode(FALSE);
+               }
 
-        $rs = $this->Execute($sql);
-        if (isset($savem)) {
-               $this->SetFetchMode($savem);
-        }
-        $ADODB_FETCH_MODE = $save;
+               $rs = $this->Execute($sql);
+               if (isset($savem)) {
+                       $this->SetFetchMode($savem);
+               }
+               $ADODB_FETCH_MODE = $save;
 
-        if (!is_object($rs)) {
-               return FALSE;
-        }
+               if (!is_object($rs)) {
+                       return FALSE;
+               }
 
                $indexes = array();
                while ($row = $rs->FetchRow()) {
                        if (!$primary && $row[5]) continue;
 
-            $indexes[$row[0]]['unique'] = $row[6];
-            $indexes[$row[0]]['columns'][] = $row[1];
-       }
-        return $indexes;
+                       $indexes[$row[0]]['unique'] = $row[6];
+                       $indexes[$row[0]]['columns'][] = $row[1];
+               }
+               return $indexes;
        }
 
        function MetaForeignKeys($table, $owner=false, $upper=false)
        {
-       global $ADODB_FETCH_MODE;
+               global $ADODB_FETCH_MODE;
 
                $save = $ADODB_FETCH_MODE;
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
                $table = $this->qstr(strtoupper($table));
 
                $sql =
-            "select object_name(constid) as constraint_name,
-                   col_name(fkeyid, fkey) as column_name,
-                   object_name(rkeyid) as referenced_table_name,
-                   col_name(rkeyid, rkey) as referenced_column_name
-            from sysforeignkeys
-            where upper(object_name(fkeyid)) = $table
-            order by constraint_name, referenced_table_name, keyno";
+                       "select object_name(constid) as constraint_name,
+                               col_name(fkeyid, fkey) as column_name,
+                               object_name(rkeyid) as referenced_table_name,
+                               col_name(rkeyid, rkey) as referenced_column_name
+                       from sysforeignkeys
+                       where upper(object_name(fkeyid)) = $table
+                       order by constraint_name, referenced_table_name, keyno";
 
                $constraints =& $this->GetArray($sql);
 
@@ -576,25 +688,25 @@ class ADODB_mssqlnative extends ADOConnection {
        //From: Fernando Moreira <FMoreira@imediata.pt>
        function MetaDatabases()
        {
-           $this->SelectDB("master");
-        $rs =& $this->Execute($this->metaDatabasesSQL);
-        $rows = $rs->GetRows();
-        $ret = array();
-        for($i=0;$i<count($rows);$i++) {
-            $ret[] = $rows[$i][0];
-        }
-        $this->SelectDB($this->database);
-        if($ret)
-            return $ret;
-        else
-            return false;
+               $this->SelectDB("master");
+               $rs =& $this->Execute($this->metaDatabasesSQL);
+               $rows = $rs->GetRows();
+               $ret = array();
+               for($i=0;$i<count($rows);$i++) {
+                       $ret[] = $rows[$i][0];
+               }
+               $this->SelectDB($this->database);
+               if($ret)
+                       return $ret;
+               else
+                       return false;
        }
 
        // "Stein-Aksel Basma" <basma@accelero.no>
        // tested with MSSQL 2000
        function MetaPrimaryKeys($table, $owner=false)
        {
-       global $ADODB_FETCH_MODE;
+               global $ADODB_FETCH_MODE;
 
                $schema = '';
                $this->_findschema($table,$schema);
@@ -617,20 +729,101 @@ class ADODB_mssqlnative extends ADOConnection {
        }
 
 
-       function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+       function MetaTables($ttype=false,$showSchema=false,$mask=false)
        {
-           if ($mask) {
+               if ($mask) {
                        $save = $this->metaTablesSQL;
                        $mask = $this->qstr(($mask));
                        $this->metaTablesSQL .= " AND name like $mask";
                }
-               $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+               $ret = ADOConnection::MetaTables($ttype,$showSchema);
 
                if ($mask) {
                        $this->metaTablesSQL = $save;
                }
                return $ret;
        }
+       function MetaColumns($table, $upper=true, $schema=false){
+
+               # start adg
+               static $cached_columns = array();
+               if ($this->cachedSchemaFlush)
+                       $cached_columns = array();
+
+               if (array_key_exists($table,$cached_columns)){
+                       return $cached_columns[$table];
+               }
+               # end adg
+
+               if (!$this->mssql_version)
+                       $this->ServerVersion();
+
+               $this->_findschema($table,$schema);
+               if ($schema) {
+                       $dbName = $this->database;
+                       $this->SelectDB($schema);
+               }
+               global $ADODB_FETCH_MODE;
+               $save = $ADODB_FETCH_MODE;
+               $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+
+               if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
+               $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
+
+               if ($schema) {
+                       $this->SelectDB($dbName);
+               }
+
+               if (isset($savem)) $this->SetFetchMode($savem);
+               $ADODB_FETCH_MODE = $save;
+               if (!is_object($rs)) {
+                       $false = false;
+                       return $false;
+               }
+
+               $retarr = array();
+               while (!$rs->EOF){
+
+                       $fld = new ADOFieldObject();
+                       if (array_key_exists(0,$rs->fields)) {
+                               $fld->name          = $rs->fields[0];
+                               $fld->type          = $rs->fields[1];
+                               $fld->max_length    = $rs->fields[2];
+                               $fld->precision     = $rs->fields[3];
+                               $fld->scale             = $rs->fields[4];
+                               $fld->not_null      =!$rs->fields[5];
+                               $fld->has_default   = $rs->fields[6];
+                               $fld->xtype         = $rs->fields[7];
+                               $fld->type_length   = $rs->fields[8];
+                               $fld->auto_increment= $rs->fields[9];
+                       } else {
+                               $fld->name          = $rs->fields['name'];
+                               $fld->type          = $rs->fields['type'];
+                               $fld->max_length    = $rs->fields['length'];
+                               $fld->precision     = $rs->fields['precision'];
+                               $fld->scale             = $rs->fields['scale'];
+                               $fld->not_null      =!$rs->fields['nullable'];
+                               $fld->has_default   = $rs->fields['default_value'];
+                               $fld->xtype         = $rs->fields['xtype'];
+                               $fld->type_length   = $rs->fields['type_length'];
+                               $fld->auto_increment= $rs->fields['is_identity'];
+                       }
+
+                       if ($save == ADODB_FETCH_NUM)
+                               $retarr[] = $fld;
+                       else
+                               $retarr[strtoupper($fld->name)] = $fld;
+
+                       $rs->MoveNext();
+
+               }
+               $rs->Close();
+               # start adg
+               $cached_columns[$table] = $retarr;
+               # end adg
+               return $retarr;
+       }
+
 }
 
 /*--------------------------------------------------------------------------------------
@@ -658,15 +851,24 @@ class ADORecordset_mssqlnative extends ADORecordSet {
 
        function _initrs()
        {
-           global $ADODB_COUNTRECS;
-        if ($this->connection->debug) error_log("(before) ADODB_COUNTRECS: {$ADODB_COUNTRECS} _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
-        /*$retRowsAff = sqlsrv_rows_affected($this->_queryID);//"If you need to determine the number of rows a query will return before retrieving the actual results, appending a SELECT COUNT ... query would let you get that information, and then a call to next_result would move you to the "real" results."
-        error_log("rowsaff: ".serialize($retRowsAff));
+               global $ADODB_COUNTRECS;
+               # KMN # if ($this->connection->debug) error_log("(before) ADODB_COUNTRECS: {$ADODB_COUNTRECS} _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
+               /*$retRowsAff = sqlsrv_rows_affected($this->_queryID);//"If you need to determine the number of rows a query will return before retrieving the actual results, appending a SELECT COUNT ... query would let you get that information, and then a call to next_result would move you to the "real" results."
+               error_log("rowsaff: ".serialize($retRowsAff));
                $this->_numOfRows = ($ADODB_COUNTRECS)? $retRowsAff:-1;*/
-        $this->_numOfRows = -1;//not supported
-        $fieldmeta = sqlsrv_field_metadata($this->_queryID);
-        $this->_numOfFields = ($fieldmeta)? count($fieldmeta):-1;
-        if ($this->connection->debug) error_log("(after) _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
+               $this->_numOfRows = -1;//not supported
+               $fieldmeta = sqlsrv_field_metadata($this->_queryID);
+               $this->_numOfFields = ($fieldmeta)? count($fieldmeta):-1;
+               # KMN # if ($this->connection->debug) error_log("(after) _numOfRows: {$this->_numOfRows} _numOfFields: {$this->_numOfFields}");
+               /*
+                * Copy the oracle method and cache the metadata at init time
+                */
+               if ($this->_numOfFields>0) {
+                       $this->_fieldobjs = array();
+                       $max = $this->_numOfFields;
+                       for ($i=0;$i<$max; $i++) $this->_fieldobjs[] = $this->_FetchField($i);
+               }
+
        }
 
 
@@ -700,33 +902,91 @@ class ADORecordset_mssqlnative extends ADORecordSet {
        /*      Returns: an object containing field information.
                Get column information in the Recordset object. fetchField() can be used in order to obtain information about
                fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
-               fetchField() is retrieved.      */
-
-       function FetchField($fieldOffset = -1)
+               fetchField() is retrieved.
+               Designed By jcortinap#jc.com.mx
+       */
+       function _FetchField($fieldOffset = -1)
        {
-        if ($this->connection->debug) error_log("<hr>fetchfield: $fieldOffset, fetch array: <pre>".print_r($this->fields,true)."</pre> backtrace: ".adodb_backtrace(false));
-               if ($fieldOffset != -1) $this->fieldOffset = $fieldOffset;
-               /*$arrKeys = array_keys($this->fields);
-               if(array_key_exists($this->fieldOffset,$arrKeys) && !array_key_exists($arrKeys[$this->fieldOffset],$this->fields)) {
-                       $f = false;
-               } else {
-                       $f = new ADOFetchObj();
-                       $f->name = $arrKeys[$this->fieldOffset];
-                       if($fieldOffset == -1) $this->fieldOffset++;
+               $_typeConversion = array(
+                       -155 => 'datetimeoffset',
+                       -154 => 'time',
+                       -152 => 'xml',
+                       -151 => 'udt',
+                       -11 => 'uniqueidentifier',
+                       -10 => 'ntext',
+                       -9 => 'nvarchar',
+                       -8 => 'nchar',
+                       -7 => 'bit',
+                       -6 => 'tinyint',
+                       -5 => 'bigint',
+                       -4 => 'image',
+                       -3 => 'varbinary',
+                       -2 => 'timestamp',
+                       -1 => 'text',
+                       1 => 'char',
+                       2 => 'numeric',
+                       3 => 'decimal',
+                       4 => 'int',
+                       5 => 'smallint',
+                       6 => 'float',
+                       7 => 'real',
+                       12 => 'varchar',
+                       91 => 'date',
+                       93 => 'datetime'
+                       );
+
+               $fa = @sqlsrv_field_metadata($this->_queryID);
+               if ($fieldOffset != -1) {
+                       $fa = $fa[$fieldOffset];
+               }
+               $false = false;
+               if (empty($fa)) {
+                       $f = false;//PHP Notice: Only variable references should be returned by reference
+               }
+               else
+               {
+                       // Convert to an object
+                       $fa = array_change_key_case($fa, CASE_LOWER);
+                       $fb = array();
+                       if ($fieldOffset != -1)
+                       {
+                               $fb = array(
+                                       'name' => $fa['name'],
+                                       'max_length' => $fa['size'],
+                                       'column_source' => $fa['name'],
+                                       'type' => $_typeConversion[$fa['type']]
+                                       );
+                       }
+                       else
+                       {
+                               foreach ($fa as $key => $value)
+                               {
+                                       $fb[] = array(
+                                               'name' => $value['name'],
+                                               'max_length' => $value['size'],
+                                               'column_source' => $value['name'],
+                                               'type' => $_typeConversion[$value['type']]
+                                               );
+                               }
+                       }
+                       $f = (object) $fb;
                }
-
-        if (empty($f)) {
-            $f = false;//PHP Notice: Only variable references should be returned by reference
-        }*/
-               $fieldMeta = @sqlsrv_field_metadata($this->_queryID);
-               $f = new ADOFieldObject();
-               $f->name = $fieldMeta[$this->fieldOffset]['Name'];
-               $f->type = $fieldMeta[$this->fieldOffset]['Type'];
-               $f->max_length = $fieldMeta[$this->fieldOffset]['Size'];
-
                return $f;
        }
 
+       /*
+        * Fetchfield copies the oracle method, it loads the field information
+        * into the _fieldobjs array once, to save multiple calls to the
+        * sqlsrv_field_metadata function
+        *
+        * @author      KM Newnham
+        * @date        02/20/2013
+        */
+       function FetchField($fieldOffset = -1)
+       {
+               return $this->_fieldobjs[$fieldOffset];
+       }
+
        function _seek($row)
        {
                return false;//There is no support for cursors in the driver at this time.  All data is returned via forward-only streams.
@@ -735,16 +995,16 @@ class ADORecordset_mssqlnative extends ADORecordSet {
        // speedup
        function MoveNext()
        {
-        if ($this->connection->debug) error_log("movenext()");
-        //if ($this->connection->debug) error_log("eof (beginning): ".$this->EOF);
+               //# KMN # if ($this->connection->debug) error_log("movenext()");
+               //# KMN # if ($this->connection->debug) error_log("eof (beginning): ".$this->EOF);
                if ($this->EOF) return false;
 
                $this->_currentRow++;
-        if ($this->connection->debug) error_log("_currentRow: ".$this->_currentRow);
+               // # KMN # if ($this->connection->debug) error_log("_currentRow: ".$this->_currentRow);
 
                if ($this->_fetch()) return true;
                $this->EOF = true;
-        //if ($this->connection->debug) error_log("eof (end): ".$this->EOF);
+               //# KMN # if ($this->connection->debug) error_log("eof (end): ".$this->EOF);
 
                return false;
        }
@@ -754,13 +1014,13 @@ class ADORecordset_mssqlnative extends ADORecordSet {
        // also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
        function _fetch($ignore_fields=false)
        {
-        if ($this->connection->debug) error_log("_fetch()");
-               if ($this->fetchMode & ADODB_FETCH_BOTH) {
+               # KMN # if ($this->connection->debug) error_log("_fetch()");
+               if ($this->fetchMode & ADODB_FETCH_ASSOC) {
                        if ($this->fetchMode & ADODB_FETCH_NUM) {
-                if ($this->connection->debug) error_log("fetch mode: both");
+                               //# KMN # if ($this->connection->debug) error_log("fetch mode: both");
                                $this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_BOTH);
                        } else {
-                if ($this->connection->debug) error_log("fetch mode: assoc");
+                               //# KMN # if ($this->connection->debug) error_log("fetch mode: assoc");
                                $this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_ASSOC);
                        }
 
@@ -776,21 +1036,21 @@ class ADORecordset_mssqlnative extends ADORecordSet {
                                }
                        }
                } else {
-            if ($this->connection->debug) error_log("fetch mode: num");
+                       //# KMN # if ($this->connection->debug) error_log("fetch mode: num");
                        $this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_NUMERIC);
                }
-        if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based
-            $arrFixed = array();
-            foreach($this->fields as $key=>$value) {
-                if(is_numeric($key)) {
-                    $arrFixed[$key-1] = $value;
-                } else {
-                    $arrFixed[$key] = $value;
-                }
-            }
-            //if($this->connection->debug) error_log("<hr>fixing non 0 based return array, old: ".print_r($this->fields,true)." new: ".print_r($arrFixed,true));
-            $this->fields = $arrFixed;
-        }
+               if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based
+                       $arrFixed = array();
+                       foreach($this->fields as $key=>$value) {
+                               if(is_numeric($key)) {
+                                       $arrFixed[$key-1] = $value;
+                               } else {
+                                       $arrFixed[$key] = $value;
+                               }
+                       }
+                       //if($this->connection->debug) error_log("<hr>fixing non 0 based return array, old: ".print_r($this->fields,true)." new: ".print_r($arrFixed,true));
+                       $this->fields = $arrFixed;
+               }
                if(is_array($this->fields)) {
                        foreach($this->fields as $key=>$value) {
                                if (is_object($value) && method_exists($value, 'format')) {//is DateTime object
@@ -798,12 +1058,12 @@ class ADORecordset_mssqlnative extends ADORecordSet {
                                }
                        }
                }
-        if($this->fields === null) $this->fields = false;
-        if ($this->connection->debug) error_log("<hr>after _fetch, fields: <pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
+               if($this->fields === null) $this->fields = false;
+               # KMN # if ($this->connection->debug) error_log("<hr>after _fetch, fields: <pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
                return $this->fields;
        }
 
-    /* close() only needs to be called if you are worried about using too much memory while your script
+       /*      close() only needs to be called if you are worried about using too much memory while your script
                is running. All associated result memory for the specified result identifier will automatically be freed.       */
        function _close()
        {
@@ -837,7 +1097,7 @@ class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
 
                if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
 
-       global $ADODB_mssql_mths,$ADODB_mssql_date_order;
+               global $ADODB_mssql_mths,$ADODB_mssql_date_order;
 
                //Dec 30 2000 12:00AM
                if ($ADODB_mssql_date_order == 'dmy') {
@@ -868,7 +1128,7 @@ class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
 
                if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
 
-           global $ADODB_mssql_mths,$ADODB_mssql_date_order;
+               global $ADODB_mssql_mths,$ADODB_mssql_date_order;
 
                //Dec 30 2000 12:00AM
                 if ($ADODB_mssql_date_order == 'dmy') {
@@ -908,17 +1168,17 @@ class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
 /*
 Code Example 1:
 
-select         object_name(constid) as constraint_name,
-               object_name(fkeyid) as table_name,
-        col_name(fkeyid, fkey) as column_name,
+select object_name(constid) as constraint_name,
+               object_name(fkeyid) as table_name,
+               col_name(fkeyid, fkey) as column_name,
        object_name(rkeyid) as referenced_table_name,
-       col_name(rkeyid, rkey) as referenced_column_name
+       col_name(rkeyid, rkey) as referenced_column_name
 from sysforeignkeys
 where object_name(fkeyid) = x
 order by constraint_name, table_name, referenced_table_name,  keyno
 
 Code Example 2:
-select         constraint_name,
+select constraint_name,
        column_name,
        ordinal_position
 from information_schema.key_column_usage
@@ -928,5 +1188,3 @@ order by constraint_name, ordinal_position
 
 http://www.databasejournal.com/scripts/article.php/1440551
 */
-
-?>
\ No newline at end of file
index a206bbc..ab226a6 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+* @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
 * Released under both BSD license and Lesser GPL library license.
 * Whenever there is any discrepancy between the two licenses,
 * the BSD license will take precedence.
@@ -59,4 +59,3 @@ class ADORecordset_mssqlpo extends ADORecordset_mssql {
                $this->ADORecordset_mssql($id,$mode);
        }
 }
-?>
\ No newline at end of file
index d208edb..d82f169 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -23,7 +23,11 @@ class ADODB_mysql extends ADOConnection {
        var $dataProvider = 'mysql';
        var $hasInsertID = true;
        var $hasAffectedRows = true;
-       var $metaTablesSQL = "SELECT TABLE_NAME, CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=SCHEMA()";
+       var $metaTablesSQL = "SELECT
+                       TABLE_NAME,
+                       CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
+               FROM INFORMATION_SCHEMA.TABLES
+               WHERE TABLE_SCHEMA=";
        var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
        var $fmtTimeStamp = "'Y-m-d H:i:s'";
        var $hasLimit = true;
@@ -136,16 +140,27 @@ class ADODB_mysql extends ADOConnection {
         return $procedures;
     }
 
+       /**
+        * Retrieves a list of tables based on given criteria
+        *
+        * @param string $ttype Table type = 'TABLE', 'VIEW' or false=both (default)
+        * @param string $showSchema schema name, false = current schema (default)
+        * @param string $mask filters the table by name
+        *
+        * @return array list of tables
+        */
        function MetaTables($ttype=false,$showSchema=false,$mask=false)
        {
                $save = $this->metaTablesSQL;
                if ($showSchema && is_string($showSchema)) {
-                       $this->metaTablesSQL .= " from $showSchema";
+                       $this->metaTablesSQL .= $this->qstr($showSchema);
+               } else {
+                       $this->metaTablesSQL .= "schema()";
                }
 
                if ($mask) {
                        $mask = $this->qstr($mask);
-                       $this->metaTablesSQL .= " like $mask";
+                       $this->metaTablesSQL .= " AND table_name LIKE $mask";
                }
                $ret = ADOConnection::MetaTables($ttype,$showSchema);
 
@@ -580,10 +595,15 @@ class ADODB_mysql extends ADOConnection {
        // returns queryID or false
        function _query($sql,$inputarr=false)
        {
-       //global $ADODB_COUNTRECS;
-               //if($ADODB_COUNTRECS)
-               return mysql_query($sql,$this->_connectionID);
-               //else return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
+
+       return mysql_query($sql,$this->_connectionID);
+       /*
+       global $ADODB_COUNTRECS;
+               if($ADODB_COUNTRECS)
+                       return mysql_query($sql,$this->_connectionID);
+               else
+                       return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
+       */
        }
 
        /*      Returns: the last error message from previous database operation        */
@@ -872,4 +892,3 @@ class ADORecordSet_ext_mysql extends ADORecordSet_mysql {
 
 
 }
-?>
\ No newline at end of file
index 574c666..6de3e7f 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -31,7 +31,11 @@ class ADODB_mysqli extends ADOConnection {
        var $dataProvider = 'mysql';
        var $hasInsertID = true;
        var $hasAffectedRows = true;
-       var $metaTablesSQL = "SELECT TABLE_NAME, CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=SCHEMA()";
+       var $metaTablesSQL = "SELECT
+                       TABLE_NAME,
+                       CASE WHEN TABLE_TYPE = 'VIEW' THEN 'V' ELSE 'T' END
+               FROM INFORMATION_SCHEMA.TABLES
+               WHERE TABLE_SCHEMA=";
        var $metaColumnsSQL = "SHOW COLUMNS FROM `%s`";
        var $fmtTimeStamp = "'Y-m-d H:i:s'";
        var $hasLimit = true;
@@ -210,7 +214,7 @@ class ADODB_mysqli extends ADOConnection {
        }
 
        // if magic quotes disabled, use mysql_real_escape_string()
-       // From readme.htm:
+       // From docs-adodb.htm:
        // Quotes a string to be sent to the database. The $magic_quotes_enabled
        // parameter may look funny, but the idea is if you are quoting a
        // string extracted from a POST/GET variable, then
@@ -530,16 +534,27 @@ class ADODB_mysqli extends ADOConnection {
         return $procedures;
     }
 
+       /**
+        * Retrieves a list of tables based on given criteria
+        *
+        * @param string $ttype Table type = 'TABLE', 'VIEW' or false=both (default)
+        * @param string $showSchema schema name, false = current schema (default)
+        * @param string $mask filters the table by name
+        *
+        * @return array list of tables
+        */
        function MetaTables($ttype=false,$showSchema=false,$mask=false)
        {
                $save = $this->metaTablesSQL;
                if ($showSchema && is_string($showSchema)) {
-                       $this->metaTablesSQL .= " from $showSchema";
+                       $this->metaTablesSQL .= $this->qstr($showSchema);
+               } else {
+                       $this->metaTablesSQL .= "schema()";
                }
 
                if ($mask) {
                        $mask = $this->qstr($mask);
-                       $this->metaTablesSQL .= " like $mask";
+                       $this->metaTablesSQL .= " AND table_name LIKE $mask";
                }
                $ret = ADOConnection::MetaTables($ttype,$showSchema);
 
@@ -1265,5 +1280,3 @@ class ADORecordSet_array_mysqli extends ADORecordSet_array {
        } // function
 
 }
-
-?>
\ No newline at end of file
index 7b4d7f6..9077301 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -134,5 +134,3 @@ class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
                return adodb_movenext($this);
        }
 }
-
-?>
\ No newline at end of file
index a5d2448..74ee4b4 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -151,5 +151,3 @@ class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
                return adodb_movenext($this);
        }
 }
-
-?>
\ No newline at end of file
index aefb23c..7c1631b 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
 
   First cut at the Netezza Driver by Josh Eldridge joshuae74#hotmail.com
  Based on the previous postgres drivers.
@@ -167,4 +167,3 @@ class ADORecordSet_netezza extends ADORecordSet_postgres64
        }
 
 }
-?>
index 05a076e..6eac31a 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-  version V5.18 3 Sep 2012 (c) 2000-2012 John Lim. All rights reserved.
+  version V5.19  23-Apr-2014  (c) 2000-2014 John Lim. All rights reserved.
 
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
@@ -30,8 +30,8 @@ For Oracle the default is dd-mon-yy or dd-mon-yyyy, and for SQL-92 the default i
 yy-mm-dd or yyyy-mm-dd.
 
 Using 'RR' in the format forces two-digit years less than or equal to 49 to be
-interpreted as years in the 21st century (20002049), and years over 50 as years in
-the 20th century (19501999). Setting the RR format as the default for all two-digit
+interpreted as years in the 21st century (2000-2049), and years over 50 as years in
+the 20th century (1950-1999). Setting the RR format as the default for all two-digit
 year entries allows you to become year-2000 compliant. For example:
 NLS_DATE_FORMAT='RR-MM-DD'
 
@@ -75,7 +75,7 @@ class ADODB_oci8 extends ADOConnection {
        var $_genIDSQL = "SELECT (%s.nextval) FROM DUAL";
        var $_genSeqSQL = "
 DECLARE
-  PRAGMA AUTONOMOUS_TRANSACTION;
+       PRAGMA AUTONOMOUS_TRANSACTION;
 BEGIN
        execute immediate 'CREATE SEQUENCE %s START WITH %s';
 END;
@@ -96,7 +96,7 @@ END;
        var $selectOffsetAlg1 = 1000; // when to use 1st algorithm of selectlimit.
        var $NLS_DATE_FORMAT = 'YYYY-MM-DD';  // To include time, use 'RRRR-MM-DD HH24:MI:SS'
        var $dateformat = 'YYYY-MM-DD'; // DBDate format
-       var $useDBDateFormatForTextInput=false;
+       var $useDBDateFormatForTextInput=false;
        var $datetime = false; // MetaType('DATE') returns 'D' (datetime==false) or 'T' (datetime == true)
        var $_refLOBs = array();
 
@@ -134,15 +134,15 @@ END;
                $retarr = array();
                while (!$rs->EOF) {
                        $fld = new ADOFieldObject();
-                       $fld->name = $rs->fields[0];
-                       $fld->type = $rs->fields[1];
-                       $fld->max_length = $rs->fields[2];
+                       $fld->name = $rs->fields[0];
+                       $fld->type = $rs->fields[1];
+                       $fld->max_length = $rs->fields[2];
                        $fld->scale = $rs->fields[3];
                        if ($rs->fields[1] == 'NUMBER') {
                                if ($rs->fields[3] == 0) $fld->type = 'INT';
-                       $fld->max_length = $rs->fields[4];
-               }
-                       $fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
+                               $fld->max_length = $rs->fields[4];
+                       }
+                       $fld->not_null = (strncmp($rs->fields[5], 'NOT',3) === 0);
                        $fld->binary = (strpos($fld->type,'BLOB') !== false);
                        $fld->default_value = $rs->fields[6];
 
@@ -165,46 +165,38 @@ END;
                return false;
        }
 
-/*
-
-  Multiple modes of connection are supported:
-
-  a. Local Database
-    $conn->Connect(false,'scott','tiger');
-
-  b. From tnsnames.ora
-    $conn->Connect(false,'scott','tiger',$tnsname);
-    $conn->Connect($tnsname,'scott','tiger');
-
-  c. Server + service name
-    $conn->Connect($serveraddress,'scott,'tiger',$service_name);
-
-  d. Server + SID
-       $conn->connectSID = true;
-       $conn->Connect($serveraddress,'scott,'tiger',$SID);
-
-
-Example TNSName:
----------------
-NATSOFT.DOMAIN =
-  (DESCRIPTION =
-       (ADDRESS_LIST =
-         (ADDRESS = (PROTOCOL = TCP)(HOST = kermit)(PORT = 1523))
-       )
-       (CONNECT_DATA =
-         (SERVICE_NAME = natsoft.domain)
-       )
-  )
-
-  There are 3 connection modes, 0 = non-persistent, 1 = persistent, 2 = force new connection
-
-*/
-       function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$mode=0)
+       /**
+        * Multiple modes of connection are supported:
+        *
+        * a. Local Database
+        *    $conn->Connect(false,'scott','tiger');
+        *
+        * b. From tnsnames.ora
+        *    $conn->Connect($tnsname,'scott','tiger');
+        *    $conn->Connect(false,'scott','tiger',$tnsname);
+        *
+        * c. Server + service name
+        *    $conn->Connect($serveraddress,'scott,'tiger',$service_name);
+        *
+        * d. Server + SID
+        *    $conn->connectSID = true;
+        *    $conn->Connect($serveraddress,'scott,'tiger',$SID);
+        *
+        * @param string|false $argHostname DB server hostname or TNS name
+        * @param string $argUsername
+        * @param string $argPassword
+        * @param string $argDatabasename Service name, SID (defaults to null)
+        * @param int $mode Connection mode, defaults to 0
+        *                  (0 = non-persistent, 1 = persistent, 2 = force new connection)
+        *
+        * @return bool
+        */
+       function _connect($argHostname, $argUsername, $argPassword, $argDatabasename=null, $mode=0)
        {
                if (!function_exists('oci_pconnect')) return null;
                #adodb_backtrace();
 
-        $this->_errorMsg = false;
+               $this->_errorMsg = false;
                $this->_errorCode = false;
 
                if($argHostname) { // added by Jorma Tuomainen <jorma.tuomainen@ppoy.fi>
@@ -212,11 +204,11 @@ NATSOFT.DOMAIN =
                        else {
                                if(strpos($argHostname,":")) {
                                        $argHostinfo=explode(":",$argHostname);
-                                       $argHostname=$argHostinfo[0];
+                                       $argHostname=$argHostinfo[0];
                                        $argHostport=$argHostinfo[1];
-                               } else {
+                               } else {
                                        $argHostport = empty($this->port)?  "1521" : $this->port;
-                               }
+                               }
 
                                if (strncasecmp($argDatabasename,'SID=',4) == 0) {
                                        $argDatabasename = substr($argDatabasename,4);
@@ -232,27 +224,25 @@ NATSOFT.DOMAIN =
                        }
                }
 
-               //if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
+               //if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
                if ($mode==1) {
-                       $this->_connectionID = ($this->charSet) ?
-                               oci_pconnect($argUsername,$argPassword, $argDatabasename,$this->charSet)
-                               :
-                               oci_pconnect($argUsername,$argPassword, $argDatabasename)
-                               ;
+                       $this->_connectionID = ($this->charSet)
+                               ? oci_pconnect($argUsername,$argPassword, $argDatabasename,$this->charSet)
+                               : oci_pconnect($argUsername,$argPassword, $argDatabasename);
                        if ($this->_connectionID && $this->autoRollback)  oci_rollback($this->_connectionID);
                } else if ($mode==2) {
-                       $this->_connectionID = ($this->charSet) ?
-                               oci_new_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
-                               :
-                               oci_new_connect($argUsername,$argPassword, $argDatabasename);
-
+                       $this->_connectionID = ($this->charSet)
+                               ? oci_new_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
+                               : oci_new_connect($argUsername,$argPassword, $argDatabasename);
                } else {
-                       $this->_connectionID = ($this->charSet) ?
-                               oci_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
-                               :
-                               oci_connect($argUsername,$argPassword, $argDatabasename);
+                       $this->_connectionID = ($this->charSet)
+                               ? oci_connect($argUsername,$argPassword, $argDatabasename,$this->charSet)
+                               : oci_connect($argUsername,$argPassword, $argDatabasename);
                }
-               if (!$this->_connectionID) return false;
+               if (!$this->_connectionID) {
+                       return false;
+               }
+
                if ($this->_initdate) {
                        $this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='".$this->NLS_DATE_FORMAT."'");
                }
@@ -262,7 +252,7 @@ NATSOFT.DOMAIN =
                // $vers = oci_server_version($this->_connectionID);
                // if (strpos($vers,'8i') !== false) $this->ansiOuter = true;
                return true;
-       }
+       }
 
        function ServerInfo()
        {
@@ -368,15 +358,15 @@ NATSOFT.DOMAIN =
        // Mark Newnham
        function MetaIndexes ($table, $primary = FALSE, $owner=false)
        {
-        // save old fetch mode
-        global $ADODB_FETCH_MODE;
+               // save old fetch mode
+               global $ADODB_FETCH_MODE;
 
-        $save = $ADODB_FETCH_MODE;
-        $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+               $save = $ADODB_FETCH_MODE;
+               $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
 
-        if ($this->fetchMode !== FALSE) {
-               $savem = $this->SetFetchMode(FALSE);
-        }
+               if ($this->fetchMode !== FALSE) {
+                       $savem = $this->SetFetchMode(FALSE);
+               }
 
                // get index details
                $table = strtoupper($table);
@@ -390,53 +380,53 @@ NATSOFT.DOMAIN =
                        if (isset($savem))
                                $this->SetFetchMode($savem);
                        $ADODB_FETCH_MODE = $save;
-            return $false;
-        }
+                       return $false;
+               }
 
                if ($row = $rs->FetchRow())
-                  $primary_key = $row[1]; //constraint_name
+                       $primary_key = $row[1]; //constraint_name
 
                if ($primary==TRUE && $primary_key=='') {
-                        if (isset($savem))
-                $this->SetFetchMode($savem);
+                       if (isset($savem))
+                               $this->SetFetchMode($savem);
                        $ADODB_FETCH_MODE = $save;
                        return $false; //There is no primary key
                }
 
-        $rs = $this->Execute(sprintf("SELECT ALL_INDEXES.INDEX_NAME, ALL_INDEXES.UNIQUENESS, ALL_IND_COLUMNS.COLUMN_POSITION, ALL_IND_COLUMNS.COLUMN_NAME FROM ALL_INDEXES,ALL_IND_COLUMNS WHERE UPPER(ALL_INDEXES.TABLE_NAME)='%s' AND ALL_IND_COLUMNS.INDEX_NAME=ALL_INDEXES.INDEX_NAME",$table));
+               $rs = $this->Execute(sprintf("SELECT ALL_INDEXES.INDEX_NAME, ALL_INDEXES.UNIQUENESS, ALL_IND_COLUMNS.COLUMN_POSITION, ALL_IND_COLUMNS.COLUMN_NAME FROM ALL_INDEXES,ALL_IND_COLUMNS WHERE UPPER(ALL_INDEXES.TABLE_NAME)='%s' AND ALL_IND_COLUMNS.INDEX_NAME=ALL_INDEXES.INDEX_NAME",$table));
 
 
-        if (!is_object($rs)) {
+               if (!is_object($rs)) {
                        if (isset($savem))
                                $this->SetFetchMode($savem);
                        $ADODB_FETCH_MODE = $save;
-            return $false;
-        }
+                       return $false;
+               }
 
                $indexes = array ();
-        // parse index data into array
+               // parse index data into array
 
-        while ($row = $rs->FetchRow()) {
+               while ($row = $rs->FetchRow()) {
                        if ($primary && $row[0] != $primary_key) continue;
-            if (!isset($indexes[$row[0]])) {
+                       if (!isset($indexes[$row[0]])) {
                                $indexes[$row[0]] = array(
-                                  'unique' => ($row[1] == 'UNIQUE'),
-                                  'columns' => array()
+                                       'unique' => ($row[1] == 'UNIQUE'),
+                                       'columns' => array()
                                );
-            }
-            $indexes[$row[0]]['columns'][$row[2] - 1] = $row[3];
-        }
+                       }
+                       $indexes[$row[0]]['columns'][$row[2] - 1] = $row[3];
+               }
 
-        // sort columns by order in the index
-        foreach ( array_keys ($indexes) as $index ) {
-            ksort ($indexes[$index]['columns']);
-        }
+               // sort columns by order in the index
+               foreach ( array_keys ($indexes) as $index ) {
+                       ksort ($indexes[$index]['columns']);
+               }
 
                if (isset($savem)) {
-            $this->SetFetchMode($savem);
+                       $this->SetFetchMode($savem);
                        $ADODB_FETCH_MODE = $save;
                }
-        return $indexes;
+               return $indexes;
        }
 
        function BeginTrans()
@@ -512,7 +502,9 @@ NATSOFT.DOMAIN =
                return $arr['code'];
        }
 
-       // Format date column in sql string given an input format that understands Y M D
+       /**
+        * Format date column in sql string given an input format that understands Y M D
+        */
        function SQLDate($fmt, $col=false)
        {
                if (!$col) $col = $this->sysTimeStamp;
@@ -572,7 +564,7 @@ NATSOFT.DOMAIN =
                                $s .= 'DAY';
                                break;
 
-                        case 'W':
+                       case 'W':
                                $s .= 'WW';
                                break;
 
@@ -597,21 +589,22 @@ NATSOFT.DOMAIN =
                return $this->GetRow($sql,$arr);
        }
 
-       /*
-       This algorithm makes use of
-
-       a. FIRST_ROWS hint
-       The FIRST_ROWS hint explicitly chooses the approach to optimize response time,
-       that is, minimum resource usage to return the first row. Results will be returned
-       as soon as they are identified.
-
-       b. Uses rownum tricks to obtain only the required rows from a given offset.
-        As this uses complicated sql statements, we only use this if the $offset >= 100.
-        This idea by Tomas V V Cox.
-
-        This implementation does not appear to work with oracle 8.0.5 or earlier. Comment
-        out this function then, and the slower SelectLimit() in the base class will be used.
-       */
+       /**
+        * This algorithm makes use of
+        *
+        * a. FIRST_ROWS hint
+        * The FIRST_ROWS hint explicitly chooses the approach to optimize response
+        * time, that is, minimum resource usage to return the first row. Results
+        * will be returned as soon as they are identified.
+        *
+        * b. Uses rownum tricks to obtain only the required rows from a given offset.
+        * As this uses complicated sql statements, we only use this if $offset >= 100.
+        * This idea by Tomas V V Cox.
+        *
+        * This implementation does not appear to work with oracle 8.0.5 or earlier.
+        * Comment out this function then, and the slower SelectLimit() in the base
+        * class will be used.
+        */
        function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
        {
                // seems that oracle only supports 1 hint comment in 8i
@@ -623,7 +616,9 @@ NATSOFT.DOMAIN =
                                $sql = str_replace('/*+ ',"/*+$hint ",$sql);
                        else
                                $sql = preg_replace('/^[ \t\n]*select/i',"SELECT /*+$hint*/",$sql);
-               }
+                       $hint = "/*+ $hint */";
+               } else
+                       $hint = '';
 
                if ($offset == -1 || ($offset < $this->selectOffsetAlg1 && 0 < $nrows && $nrows < 1000)) {
                        if ($nrows > 0) {
@@ -643,9 +638,9 @@ NATSOFT.DOMAIN =
                        return $rs;
 
                } else {
-                        // Algorithm by Tomas V V Cox, from PEAR DB oci8.php
+                       // Algorithm by Tomas V V Cox, from PEAR DB oci8.php
 
-                        // Let Oracle return the name of the columns
+                       // Let Oracle return the name of the columns
                        $q_fields = "SELECT * FROM (".$sql.") WHERE NULL = NULL";
 
                        $false = false;
@@ -655,7 +650,7 @@ NATSOFT.DOMAIN =
                        $stmt = $stmt_arr[1];
 
                        if (is_array($inputarr)) {
-                               foreach($inputarr as $k => $v) {
+                               foreach($inputarr as $k => $v) {
                                        if (is_array($v)) {
                                                if (sizeof($v) == 2) // suggested by g.giunta@libero.
                                                        oci_bind_by_name($stmt,":$k",$inputarr[$k][0],$v[1]);
@@ -668,39 +663,38 @@ NATSOFT.DOMAIN =
                                                        $bindarr[$k] = $v;
                                                } else {                                // dynamic sql, so rebind every time
                                                        oci_bind_by_name($stmt,":$k",$inputarr[$k],$len);
-
                                                }
                                        }
                                }
                        }
 
-                        if (!oci_execute($stmt, OCI_DEFAULT)) {
-                                oci_free_statement($stmt);
-                                return $false;
-                        }
+                       if (!oci_execute($stmt, OCI_DEFAULT)) {
+                               oci_free_statement($stmt);
+                               return $false;
+                       }
 
-                        $ncols = oci_num_fields($stmt);
-                        for ( $i = 1; $i <= $ncols; $i++ ) {
-                                $cols[] = '"'.oci_field_name($stmt, $i).'"';
-                        }
-                        $result = false;
+                       $ncols = oci_num_fields($stmt);
+                       for ( $i = 1; $i <= $ncols; $i++ ) {
+                               $cols[] = '"'.oci_field_name($stmt, $i).'"';
+                       }
+                       $result = false;
 
-                        oci_free_statement($stmt);
-                        $fields = implode(',', $cols);
-                        if ($nrows <= 0) $nrows = 999999999999;
-                        else $nrows += $offset;
-                        $offset += 1; // in Oracle rownum starts at 1
+                       oci_free_statement($stmt);
+                       $fields = implode(',', $cols);
+                       if ($nrows <= 0) $nrows = 999999999999;
+                       else $nrows += $offset;
+                       $offset += 1; // in Oracle rownum starts at 1
 
                        if ($this->databaseType == 'oci8po') {
-                                        $sql = "SELECT /*+ FIRST_ROWS */ $fields FROM".
-                                         "(SELECT rownum as adodb_rownum, $fields FROM".
-                                         " ($sql) WHERE rownum <= ?".
-                                         ") WHERE adodb_rownum >= ?";
+                                       $sql = "SELECT $hint $fields FROM".
+                                               "(SELECT rownum as adodb_rownum, $fields FROM".
+                                               " ($sql) WHERE rownum <= ?".
+                                               ") WHERE adodb_rownum >= ?";
                                } else {
-                                        $sql = "SELECT /*+ FIRST_ROWS */ $fields FROM".
-                                         "(SELECT rownum as adodb_rownum, $fields FROM".
-                                         " ($sql) WHERE rownum <= :adodb_nrows".
-                                         ") WHERE adodb_rownum >= :adodb_offset";
+                                       $sql = "SELECT $hint $fields FROM".
+                                               "(SELECT rownum as adodb_rownum, $fields FROM".
+                                               " ($sql) WHERE rownum <= :adodb_nrows".
+                                               ") WHERE adodb_rownum >= :adodb_offset";
                                }
                                $inputarr['adodb_nrows'] = $nrows;
                                $inputarr['adodb_offset'] = $offset;
@@ -709,29 +703,26 @@ NATSOFT.DOMAIN =
                        else $rs = $this->Execute($sql,$inputarr);
                        return $rs;
                }
-
        }
 
        /**
-       * Usage:
-       * Store BLOBs and CLOBs
-       *
-       * Example: to store $var in a blob
-       *
-       *       $conn->Execute('insert into TABLE (id,ablob) values(12,empty_blob())');
-       *       $conn->UpdateBlob('TABLE', 'ablob', $varHoldingBlob, 'ID=12', 'BLOB');
-       *
-       *       $blobtype supports 'BLOB' and 'CLOB', but you need to change to 'empty_clob()'.
-       *
-       *  to get length of LOB:
-       *       select DBMS_LOB.GETLENGTH(ablob) from TABLE
-       *
-       * If you are using CURSOR_SHARING = force, it appears this will case a segfault
-       * under oracle 8.1.7.0. Run:
-       *        $db->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
-       * before UpdateBlob() then...
-       */
-
+        * Usage:
+        * Store BLOBs and CLOBs
+        *
+        * Example: to store $var in a blob
+        *    $conn->Execute('insert into TABLE (id,ablob) values(12,empty_blob())');
+        *    $conn->UpdateBlob('TABLE', 'ablob', $varHoldingBlob, 'ID=12', 'BLOB');
+        *
+        * $blobtype supports 'BLOB' and 'CLOB', but you need to change to 'empty_clob()'.
+        *
+        * to get length of LOB:
+        *    select DBMS_LOB.GETLENGTH(ablob) from TABLE
+        *
+        * If you are using CURSOR_SHARING = force, it appears this will case a segfault
+        * under oracle 8.1.7.0. Run:
+        *    $db->Execute('ALTER SESSION SET CURSOR_SHARING=EXACT');
+        * before UpdateBlob() then...
+        */
        function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
        {
 
@@ -764,8 +755,8 @@ NATSOFT.DOMAIN =
        }
 
        /**
-       * Usage:  store file pointed to by $val in a blob
-       */
+        * Usage:  store file pointed to by $val in a blob
+        */
        function UpdateBlobFile($table,$column,$val,$where,$blobtype='BLOB')
        {
                switch(strtoupper($blobtype)) {
@@ -792,7 +783,7 @@ NATSOFT.DOMAIN =
                return $rez;
        }
 
-               /**
+       /**
         * Execute SQL
         *
         * @param sql           SQL statement to execute, or possibly an array holding prepared statement ($sql[0] will hold sql text)
@@ -806,8 +797,8 @@ NATSOFT.DOMAIN =
                        $ret = $fn($this,$sql,$inputarr);
                        if (isset($ret)) return $ret;
                }
-               if ($inputarr) {
-                       #if (!is_array($inputarr)) $inputarr = array($inputarr);
+               if ($inputarr !== false) {
+                       if (!is_array($inputarr)) $inputarr = array($inputarr);
 
                        $element0 = reset($inputarr);
                        $array2d =  $this->bulkBind && is_array($element0) && !is_object(reset($element0));
@@ -872,9 +863,8 @@ NATSOFT.DOMAIN =
        }
 
        /*
-               Example of usage:
-
-               $stmt = $this->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
+        * Example of usage:
+        *    $stmt = $this->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
        */
        function Prepare($sql,$cursor=false)
        {
@@ -941,44 +931,43 @@ NATSOFT.DOMAIN =
                return $rs;
        }
 
-       /*
-               Bind a variable -- very, very fast for executing repeated statements in oracle.
-               Better than using
-                       for ($i = 0; $i < $max; $i++) {
-                               $p1 = ?; $p2 = ?; $p3 = ?;
-                               $this->Execute("insert into table (col0, col1, col2) values (:0, :1, :2)",
-                                       array($p1,$p2,$p3));
-                       }
-
-               Usage:
-                       $stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
-                       $DB->Bind($stmt, $p1);
-                       $DB->Bind($stmt, $p2);
-                       $DB->Bind($stmt, $p3);
-                       for ($i = 0; $i < $max; $i++) {
-                               $p1 = ?; $p2 = ?; $p3 = ?;
-                               $DB->Execute($stmt);
-                       }
-
-               Some timings:
-                       ** Test table has 3 cols, and 1 index. Test to insert 1000 records
-                       Time 0.6081s (1644.60 inserts/sec) with direct oci_parse/oci_execute
-                       Time 0.6341s (1577.16 inserts/sec) with ADOdb Prepare/Bind/Execute
-                       Time 1.5533s ( 643.77 inserts/sec) with pure SQL using Execute
-
-               Now if PHP only had batch/bulk updating like Java or PL/SQL...
-
-               Note that the order of parameters differs from oci_bind_by_name,
-               because we default the names to :0, :1, :2
-       */
+       /**
+        * Bind a variable -- very, very fast for executing repeated statements in oracle.
+        *
+        * Better than using
+        *    for ($i = 0; $i < $max; $i++) {
+        *        $p1 = ?; $p2 = ?; $p3 = ?;
+        *        $this->Execute("insert into table (col0, col1, col2) values (:0, :1, :2)", array($p1,$p2,$p3));
+        *    }
+        *
+        * Usage:
+        *    $stmt = $DB->Prepare("insert into table (col0, col1, col2) values (:0, :1, :2)");
+        *    $DB->Bind($stmt, $p1);
+        *    $DB->Bind($stmt, $p2);
+        *    $DB->Bind($stmt, $p3);
+        *    for ($i = 0; $i < $max; $i++) {
+        *        $p1 = ?; $p2 = ?; $p3 = ?;
+        *        $DB->Execute($stmt);
+        *    }
+        *
+        * Some timings to insert 1000 records, test table has 3 cols, and 1 index.
+        * - Time 0.6081s (1644.60 inserts/sec) with direct oci_parse/oci_execute
+        * - Time 0.6341s (1577.16 inserts/sec) with ADOdb Prepare/Bind/Execute
+        * - Time 1.5533s ( 643.77 inserts/sec) with pure SQL using Execute
+        *
+        * Now if PHP only had batch/bulk updating like Java or PL/SQL...
+        *
+        * Note that the order of parameters differs from oci_bind_by_name,
+        * because we default the names to :0, :1, :2
+        */
        function Bind(&$stmt,&$var,$size=4000,$type=false,$name=false,$isOutput=false)
        {
 
                if (!is_array($stmt)) return false;
 
-        if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) {
-            return oci_bind_by_name($stmt[1],":".$name,$stmt[4],$size,$type);
-        }
+               if (($type == OCI_B_CURSOR) && sizeof($stmt) >= 5) {
+                       return oci_bind_by_name($stmt[1],":".$name,$stmt[4],$size,$type);
+               }
 
                if ($name == false) {
                        if ($type !== false) $rez = oci_bind_by_name($stmt[1],":".$stmt[2],$var,$size,$type);
@@ -988,13 +977,13 @@ NATSOFT.DOMAIN =
                        if ($this->debug) {
                                ADOConnection::outp("<b>Bind</b>: name = $name");
                        }
-            //we have to create a new Descriptor here
+                       //we have to create a new Descriptor here
                        $numlob = count($this->_refLOBs);
-               $this->_refLOBs[$numlob]['LOB'] = oci_new_descriptor($this->_connectionID, oci_lob_desc($type));
+                       $this->_refLOBs[$numlob]['LOB'] = oci_new_descriptor($this->_connectionID, oci_lob_desc($type));
                        $this->_refLOBs[$numlob]['TYPE'] = $isOutput;
 
                        $tmp = $this->_refLOBs[$numlob]['LOB'];
-               $rez = oci_bind_by_name($stmt[1], ":".$name, $tmp, -1, $type);
+                       $rez = oci_bind_by_name($stmt[1], ":".$name, $tmp, -1, $type);
                        if ($this->debug) {
                                ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (".$name.") binded");
                        }
@@ -1027,21 +1016,21 @@ NATSOFT.DOMAIN =
                return ':'.$name;
        }
 
-       /*
-       Usage:
-               $stmt = $db->Prepare('select * from table where id =:myid and group=:group');
-               $db->Parameter($stmt,$id,'myid');
-               $db->Parameter($stmt,$group,'group');
-               $db->Execute($stmt);
-
-               @param $stmt Statement returned by Prepare() or PrepareSP().
-               @param $var PHP variable to bind to
-               @param $name Name of stored procedure variable name to bind to.
-               @param [$isOutput] Indicates direction of parameter 0/false=IN  1=OUT  2= IN/OUT. This is ignored in oci8.
-               @param [$maxLen] Holds an maximum length of the variable.
-               @param [$type] The data type of $var. Legal values depend on driver.
-
-               See oci_bind_by_name documentation at php.net.
+       /**
+        * Usage:
+        *    $stmt = $db->Prepare('select * from table where id =:myid and group=:group');
+        *    $db->Parameter($stmt,$id,'myid');
+        *    $db->Parameter($stmt,$group,'group');
+        *    $db->Execute($stmt);
+        *
+        * @param $stmt Statement returned by Prepare() or PrepareSP().
+        * @param $var PHP variable to bind to
+        * @param $name Name of stored procedure variable name to bind to.
+        * @param [$isOutput] Indicates direction of parameter 0/false=IN  1=OUT  2= IN/OUT. This is ignored in oci8.
+        * @param [$maxLen] Holds an maximum length of the variable.
+        * @param [$type] The data type of $var. Legal values depend on driver.
+        *
+        * @link http://php.net/oci_bind_by_name
        */
        function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false)
        {
@@ -1053,21 +1042,21 @@ NATSOFT.DOMAIN =
                        return $this->Bind($stmt,$var,$maxLen,$type,$name,$isOutput);
        }
 
-       /*
-       returns query ID if successful, otherwise false
-       this version supports:
-
-          1. $db->execute('select * from table');
-
-          2. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
-                 $db->execute($prepared_statement, array(1,2,3));
-
-          3. $db->execute('insert into table (a,b,c) values (:a,:b,:c)',array('a'=>1,'b'=>2,'c'=>3));
-
-          4. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
-                 $db->bind($stmt,1); $db->bind($stmt,2); $db->bind($stmt,3);
-                 $db->execute($stmt);
-       */
+       /**
+        * returns query ID if successful, otherwise false
+        * this version supports:
+        *
+        * 1. $db->execute('select * from table');
+        *
+        * 2. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
+        *    $db->execute($prepared_statement, array(1,2,3));
+        *
+        * 3. $db->execute('insert into table (a,b,c) values (:a,:b,:c)',array('a'=>1,'b'=>2,'c'=>3));
+        *
+        * 4. $db->prepare('insert into table (a,b,c) values (:0,:1,:2)');
+        *    $db->bind($stmt,1); $db->bind($stmt,2); $db->bind($stmt,3);
+        *    $db->execute($stmt);
+        */
        function _query($sql,$inputarr=false)
        {
                if (is_array($sql)) { // is prepared sql
@@ -1126,7 +1115,7 @@ NATSOFT.DOMAIN =
                        }
                }
 
-        $this->_errorMsg = false;
+               $this->_errorMsg = false;
                $this->_errorCode = false;
                if (oci_execute($stmt,$this->_commit)) {
 
@@ -1141,41 +1130,41 @@ NATSOFT.DOMAIN =
                                                //$_GLOBALS[$this -> _refLOBs[$key]['VAR']] = $tmp;
                                                $this -> _refLOBs[$key]['VAR'] = $tmp;
                                        } else {
-                        $this->_refLOBs[$key]['LOB']->save($this->_refLOBs[$key]['VAR']);
+                                               $this->_refLOBs[$key]['LOB']->save($this->_refLOBs[$key]['VAR']);
                                                $this -> _refLOBs[$key]['LOB']->free();
                                                unset($this -> _refLOBs[$key]);
-                        if ($this->debug) {
+                                               if ($this->debug) {
                                                        ADOConnection::outp("<b>IN LOB</b>: LOB has been saved. <br>");
                                                }
-                    }
+                                       }
                                }
                        }
 
-            switch (@oci_statement_type($stmt)) {
-                case "SELECT":
+                       switch (@oci_statement_type($stmt)) {
+                               case "SELECT":
                                        return $stmt;
 
                                case 'DECLARE':
-                case "BEGIN":
-                    if (is_array($sql) && !empty($sql[4])) {
+                               case "BEGIN":
+                                       if (is_array($sql) && !empty($sql[4])) {
                                                $cursor = $sql[4];
                                                if (is_resource($cursor)) {
                                                        $ok = oci_execute($cursor);
-                               return $cursor;
+                                                       return $cursor;
                                                }
                                                return $stmt;
-                    } else {
+                                       } else {
                                                if (is_resource($stmt)) {
                                                        oci_free_statement($stmt);
                                                        return true;
                                                }
-                        return $stmt;
-                    }
-                    break;
-                default :
+                                               return $stmt;
+                                       }
+                                       break;
+                               default :
 
-                    return true;
-            }
+                                       return true;
+                       }
                }
                return false;
        }
@@ -1228,7 +1217,7 @@ NATSOFT.DOMAIN =
        {
                if ($internalKey) return array('ROWID');
 
-       // tested with oracle 8.1.7
+               // tested with oracle 8.1.7
                $table = strtoupper($table);
                if ($owner) {
                        $owner_clause = "AND ((a.OWNER = b.OWNER) AND (a.OWNER = UPPER('$owner')))";
@@ -1246,7 +1235,7 @@ SELECT /*+ RULE */ distinct b.column_name
        $owner_clause
        AND (a.constraint_name = b.constraint_name)";
 
-               $rs = $this->Execute($sql);
+               $rs = $this->Execute($sql);
                if ($rs && !$rs->EOF) {
                        $arr = $rs->GetArray();
                        $a = array();
@@ -1258,10 +1247,19 @@ SELECT /*+ RULE */ distinct b.column_name
                else return false;
        }
 
-       // http://gis.mit.edu/classes/11.521/sqlnotes/referential_integrity.html
-       function MetaForeignKeys($table, $owner=false)
+       /**
+        * returns assoc array where keys are tables, and values are foreign keys
+        *
+        * @param       str             $table
+        * @param       str             $owner  [optional][default=NULL]
+        * @param       bool    $upper  [optional][discarded]
+        * @return      mixed[]                 Array of foreign key information
+        *
+        * @link http://gis.mit.edu/classes/11.521/sqlnotes/referential_integrity.html
+        */
+       function MetaForeignKeys($table, $owner=false, $upper=false)
        {
-       global $ADODB_FETCH_MODE;
+               global $ADODB_FETCH_MODE;
 
                $save = $ADODB_FETCH_MODE;
                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
@@ -1313,11 +1311,11 @@ SELECT /*+ RULE */ distinct b.column_name
         * Quotes a string.
         * An example is  $db->qstr("Don't bother",magic_quotes_runtime());
         *
-        * @param s                     the string to quote
-        * @param [magic_quotes]        if $s is GET/POST var, set to get_magic_quotes_gpc().
-        *                              This undoes the stupidity of magic quotes for GPC.
+        * @param string $s the string to quote
+        * @param bool $magic_quotes if $s is GET/POST var, set to get_magic_quotes_gpc().
+        *             This undoes the stupidity of magic quotes for GPC.
         *
-        * @return  quoted string to be sent back to database
+        * @return string quoted string to be sent back to database
         */
        function qstr($s,$magic_quotes=false)
        {
@@ -1344,7 +1342,7 @@ SELECT /*+ RULE */ distinct b.column_name
 }
 
 /*--------------------------------------------------------------------------------------
-                Class Name: Recordset
+       Class Name: Recordset
 --------------------------------------------------------------------------------------*/
 
 class ADORecordset_oci8 extends ADORecordSet {
@@ -1418,11 +1416,14 @@ class ADORecordset_oci8 extends ADORecordSet {
                }
        }
 
-         /*            Returns: an object containing field information.
-                         Get column information in the Recordset object. fetchField() can be used in order to obtain information about
-                         fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
-                         fetchField() is retrieved.            */
-
+       /**
+        * Get column information in the Recordset object.
+        * fetchField() can be used in order to obtain information about fields
+        * in a certain query result. If the field offset isn't specified, the next
+        * field that wasn't yet retrieved by fetchField() is retrieved
+        *
+        * @return object containing field information
+        */
        function _FetchField($fieldOffset = -1)
        {
                $fld = new ADOFieldObject;
@@ -1430,19 +1431,20 @@ class ADORecordset_oci8 extends ADORecordSet {
                $fld->name =oci_field_name($this->_queryID, $fieldOffset);
                $fld->type = oci_field_type($this->_queryID, $fieldOffset);
                $fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
-               switch($fld->type) {
-               case 'NUMBER':
-                       $p = oci_field_precision($this->_queryID, $fieldOffset);
-                       $sc = oci_field_scale($this->_queryID, $fieldOffset);
-                       if ($p != 0 && $sc == 0) $fld->type = 'INT';
-                       $fld->scale = $p;
-                       break;
-
-               case 'CLOB':
-               case 'NCLOB':
-               case 'BLOB':
-                       $fld->max_length = -1;
-                       break;
+
+               switch($fld->type) {
+                       case 'NUMBER':
+                               $p = oci_field_precision($this->_queryID, $fieldOffset);
+                               $sc = oci_field_scale($this->_queryID, $fieldOffset);
+                               if ($p != 0 && $sc == 0) $fld->type = 'INT';
+                               $fld->scale = $p;
+                               break;
+
+                       case 'CLOB':
+                       case 'NCLOB':
+                       case 'BLOB':
+                               $fld->max_length = -1;
+                               break;
                }
                return $fld;
        }
@@ -1454,7 +1456,7 @@ class ADORecordset_oci8 extends ADORecordSet {
        }
 
 
-       /*
+/*
        // 10% speedup to move MoveNext to child class
        function _MoveNext()
        {
@@ -1468,7 +1470,8 @@ class ADORecordset_oci8 extends ADORecordSet {
                $this->EOF = true;
 
                return false;
-       }       */
+       }
+*/
 
 
        function MoveNext()
@@ -1484,7 +1487,7 @@ class ADORecordset_oci8 extends ADORecordSet {
                return false;
        }
 
-       /*
+/*
        # does not work as first record is retrieved in _initrs(), so is not included in GetArray()
        function GetArray($nRows = -1)
        {
@@ -1516,9 +1519,10 @@ class ADORecordset_oci8 extends ADORecordSet {
                $results = ADORecordSet::GetArray($nRows);
                return $results;
 
-       } */
+       }
+*/
 
-       /* Optimize SelectLimit() by using oci_fetch() */
+       // Optimize SelectLimit() by using oci_fetch()
        function GetArrayLimit($nrows,$offset=-1)
        {
                if ($offset <= 0) {
@@ -1541,7 +1545,7 @@ class ADORecordset_oci8 extends ADORecordSet {
        }
 
 
-       /* Use associative array to get fields array */
+       // Use associative array to get fields array
        function Fields($colname)
        {
                if (!$this->bind) {
@@ -1552,7 +1556,7 @@ class ADORecordset_oci8 extends ADORecordSet {
                        }
                }
 
-                return $this->fields[$this->bind[strtoupper($colname)]];
+               return $this->fields[$this->bind[strtoupper($colname)]];
        }
 
 
@@ -1567,9 +1571,11 @@ class ADORecordset_oci8 extends ADORecordSet {
                return $this->fields = @oci_fetch_array($this->_queryID,$this->fetchMode);
        }
 
-       /*              close() only needs to be called if you are worried about using too much memory while your script
-                       is running. All associated result memory for the specified result identifier will automatically be freed.               */
-
+       /**
+        * close() only needs to be called if you are worried about using too much
+        * memory while your script is running. All associated result memory for the
+        * specified result identifier will automatically be freed.
+        */
        function _close()
        {
                if ($this->connection->_stmt === $this->_queryID) $this->connection->_stmt = false;
@@ -1578,27 +1584,36 @@ class ADORecordset_oci8 extends ADORecordSet {
                        $this->_refcursor = false;
                }
                @oci_free_statement($this->_queryID);
-               $this->_queryID = false;
-
+               $this->_queryID = false;
        }
 
-       function MetaType($t,$len=-1)
+       /**
+        * not the fastest implementation - quick and dirty - jlim
+        * for best performance, use the actual $rs->MetaType().
+        *
+        * @param       mixed   $t
+        * @param       int             $len            [optional] Length of blobsize
+        * @param       bool    $fieldobj       [optional][discarded]
+        * @return      str                                     The metatype of the field
+        */
+       function MetaType($t, $len=-1, $fieldobj=false)
        {
                if (is_object($t)) {
                        $fieldobj = $t;
                        $t = $fieldobj->type;
                        $len = $fieldobj->max_length;
                }
+
                switch (strtoupper($t)) {
-               case 'VARCHAR':
-               case 'VARCHAR2':
+               case 'VARCHAR':
+               case 'VARCHAR2':
                case 'CHAR':
                case 'VARBINARY':
                case 'BINARY':
                case 'NCHAR':
                case 'NVARCHAR':
                case 'NVARCHAR2':
-                                if ($len <= $this->blobSize) return 'C';
+                       if ($len <= $this->blobSize) return 'C';
 
                case 'NCLOB':
                case 'LONG':
@@ -1622,7 +1637,8 @@ class ADORecordset_oci8 extends ADORecordSet {
                case 'INTEGER':
                        return 'I';
 
-               default: return 'N';
+               default:
+                       return 'N';
                }
        }
 }
@@ -1651,4 +1667,3 @@ class ADORecordSet_ext_oci8 extends ADORecordSet_oci8 {
                return adodb_movenext($this);
        }
 }
-?>
\ No newline at end of file
index 03519ea..7dd5fa6 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ * @version V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
  * Released under both BSD license and Lesser GPL library license.
  * Whenever there is any discrepancy between the two licenses,
  * the BSD license will take precedence.
@@ -56,4 +56,3 @@ class ADORecordset_oci805 extends ADORecordset_oci8 {
                $this->ADORecordset_oci8($id,$mode);
        }
 }
-?>
\ No newline at end of file
index 4babe81..fc3aba5 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim. All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim. All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -218,6 +218,3 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
        }
 
 }
-
-
-?>
\ No newline at end of file
diff --git a/typo3/sysext/adodb/adodb/drivers/adodb-oci8quercus.inc.php b/typo3/sysext/adodb/adodb/drivers/adodb-oci8quercus.inc.php
new file mode 100644 (file)
index 0000000..3029bc7
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+/*
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim. All rights reserved.
+  Released under both BSD license and Lesser GPL library license.
+  Whenever there is any discrepancy between the two licenses,
+  the BSD license will take precedence.
+
+  Latest version is available at http://adodb.sourceforge.net
+
+  Portable version of oci8 driver, to make it more similar to other database drivers.
+  The main differences are
+
+   1. that the OCI_ASSOC names are in lowercase instead of uppercase.
+   2. bind variables are mapped using ? instead of :<bindvar>
+
+   Should some emulation of RecordCount() be implemented?
+
+*/
+
+// security - hide paths
+if (!defined('ADODB_DIR')) die();
+
+include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php');
+
+class ADODB_oci8quercus extends ADODB_oci8 {
+       var $databaseType = 'oci8quercus';
+       var $dataProvider = 'oci8';
+
+       function ADODB_oci8quercus()
+       {
+       }
+
+}
+
+/*--------------------------------------------------------------------------------------
+                Class Name: Recordset
+--------------------------------------------------------------------------------------*/
+
+class ADORecordset_oci8quercus extends ADORecordset_oci8 {
+
+       var $databaseType = 'oci8quercus';
+
+       function ADORecordset_oci8quercus($queryID,$mode=false)
+       {
+               $this->ADORecordset_oci8($queryID,$mode);
+       }
+
+       function _FetchField($fieldOffset = -1)
+       {
+       global $QUERCUS;
+               $fld = new ADOFieldObject;
+
+               if (!empty($QUERCUS)) {
+                       $fld->name = oci_field_name($this->_queryID, $fieldOffset);
+                       $fld->type = oci_field_type($this->_queryID, $fieldOffset);
+                       $fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
+
+                       //if ($fld->name == 'VAL6_NUM_12_4') $fld->type = 'NUMBER';
+                       switch($fld->type) {
+                               case 'string': $fld->type = 'VARCHAR'; break;
+                               case 'real': $fld->type = 'NUMBER'; break;
+                       }
+               } else {
+                       $fieldOffset += 1;
+                       $fld->name = oci_field_name($this->_queryID, $fieldOffset);
+                       $fld->type = oci_field_type($this->_queryID, $fieldOffset);
+                       $fld->max_length = oci_field_size($this->_queryID, $fieldOffset);
+               }
+               switch($fld->type) {
+               case 'NUMBER':
+                       $p = oci_field_precision($this->_queryID, $fieldOffset);
+                       $sc = oci_field_scale($this->_queryID, $fieldOffset);
+                       if ($p != 0 && $sc == 0) $fld->type = 'INT';
+                       $fld->scale = $p;
+                       break;
+
+               case 'CLOB':
+               case 'NCLOB':
+               case 'BLOB':
+                       $fld->max_length = -1;
+                       break;
+               }
+
+               return $fld;
+       }
+
+}
index affc65c..0b271a4 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -240,7 +240,7 @@ class ADODB_odbc extends ADOConnection {
                return $ret;
        }
 
-       function MetaPrimaryKeys($table)
+       function MetaPrimaryKeys($table,$owner=false)
        {
        global $ADODB_FETCH_MODE;
 
@@ -274,7 +274,7 @@ class ADODB_odbc extends ADOConnection {
 
 
 
-       function MetaTables($ttype=false)
+       function MetaTables($ttype=false,$showSchema=false,$mask=false)
        {
        global $ADODB_FETCH_MODE;
 
@@ -701,17 +701,7 @@ class ADORecordSet_odbc extends ADORecordSet {
        {
                if ($this->_numOfRows != 0 && !$this->EOF) {
                        $this->_currentRow++;
-
-                       if ($this->_has_stupid_odbc_fetch_api_change)
-                               $rez = @odbc_fetch_into($this->_queryID,$this->fields);
-                       else {
-                               $row = 0;
-                               $rez = @odbc_fetch_into($this->_queryID,$row,$this->fields);
-                       }
-                       if ($rez) {
-                               if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                                       $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
-                               }
+                       if( $this->_fetch() ) {
                                return true;
                        }
                }
@@ -722,7 +712,7 @@ class ADORecordSet_odbc extends ADORecordSet {
 
        function _fetch()
        {
-
+               $this->fields = false;
                if ($this->_has_stupid_odbc_fetch_api_change)
                        $rez = @odbc_fetch_into($this->_queryID,$this->fields);
                else {
@@ -735,7 +725,6 @@ class ADORecordSet_odbc extends ADORecordSet {
                        }
                        return true;
                }
-               $this->fields = false;
                return false;
        }
 
@@ -745,4 +734,3 @@ class ADORecordSet_odbc extends ADORecordSet {
        }
 
 }
-?>
\ No newline at end of file
index 75a5879..217ecb3 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -365,4 +365,3 @@ class  ADORecordSet_odbc_db2 extends ADORecordSet_odbc {
 }
 
 } //define
-?>
\ No newline at end of file
index f972b07..d6894cd 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -23,7 +23,7 @@ if (!defined('_ADODB_ODBC_LAYER')) {
 class  ADODB_odbc_mssql extends ADODB_odbc {
        var $databaseType = 'odbc_mssql';
        var $fmtDate = "'Y-m-d'";
-       var $fmtTimeStamp = "'Y-m-d H:i:s'";
+       var $fmtTimeStamp = "'Y-m-d\TH:i:s'";
        var $_bindInputArray = true;
        var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
        var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE'))";
@@ -359,4 +359,3 @@ class  ADORecordSet_odbc_mssql extends ADORecordSet_odbc {
                return $this->ADORecordSet_odbc($id,$mode);
        }
 }
-?>
\ No newline at end of file
index 4b6c98c..222e772 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -112,4 +112,3 @@ class  ADORecordSet_odbc_oracle extends ADORecordSet_odbc {
                return $this->ADORecordSet_odbc($id,$mode);
        }
 }
-?>
\ No newline at end of file
index fe88fd6..2209b6c 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-  V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+  V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -836,4 +836,3 @@ class ADORecordSet_odbtp_sybase extends ADORecordSet_odbtp {
                return $this->ADORecordSet_odbtp($id,$mode);
        }
 }
-?>
index 51128f0..0db4408 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-       V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+       V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -36,4 +36,3 @@ class ADODB_odbtp_unicode extends ADODB_odbtp {
                $this->ADODB_odbtp();
        }
 }
-?>
index 3cddedb..a92d84e 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -339,4 +339,3 @@ class ADORecordset_oracle extends ADORecordSet {
                }
        }
 }
-?>
\ No newline at end of file
index 65a18bb..4ac6164 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -181,6 +181,7 @@ class ADODB_pdo extends ADOConnection {
                if(method_exists($this->_driver, 'Concat'))
                        return call_user_func_array(array($this->_driver, 'Concat'), $args);
 
+               if (PHP_VERSION >= 5.3) return call_user_func_array('parent::Concat', $args);
                return call_user_func_array(array($this,'parent::Concat'), $args);
        }
 
@@ -622,5 +623,3 @@ class ADORecordSet_pdo extends ADORecordSet {
        }
 
 }
-
-?>
\ No newline at end of file
index 2ca1431..0b1ba8b 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -58,4 +58,3 @@ class ADODB_pdo_mssql extends ADODB_pdo {
        }
 
 }
-?>
\ No newline at end of file
index 27d6d98..524d149 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -179,4 +179,3 @@ class ADODB_pdo_mysql extends ADODB_pdo {
                return $rs;
        }
 }
-?>
\ No newline at end of file
index 32624ca..2ff56f5 100644 (file)
@@ -2,7 +2,7 @@
 
 
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -89,5 +89,3 @@ class ADODB_pdo_oci extends ADODB_pdo_base {
                        return $retarr;
        }
 }
-
-?>
\ No newline at end of file
index ad82776..671ceab 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -226,5 +226,3 @@ select viewname,'V' from pg_views where viewname like $mask";
        }
 
 }
-
-?>
index f999a56..05557e2 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /*
- V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence. See License.txt.
@@ -200,4 +200,3 @@ class ADODB_pdo_sqlite extends ADODB_pdo {
                return $ret;
    }
 }
-?>
\ No newline at end of file
index 7d36fee..d3831cd 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -10,5 +10,3 @@
   remapped to "postgres7". Maintaining multiple postgres drivers is no easy
   job, so hopefully this will ensure greater consistency and fewer bugs.
 */
-
-?>
\ No newline at end of file
index aa4b762..2a5bc40 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /*
- V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
+ V5.19  23-Apr-2014  (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license.
   Whenever there is any discrepancy between the two licenses,
   the BSD license will take precedence.
@@ -9,8 +9,8 @@
   Original version derived from Alberto Cerezal (acerezalp@dbnet.es) - DBNet Informatica & Comunicaciones.
   08 Nov 2000 jlim - Minor corrections, removing mysql stuff
   09 Nov 2000 jlim - added insertid support suggested by "Christopher Kings-Lynne" <chriskl@familyhealth.com.au>
-                                       jlim - changed concat operator to || and data types to MetaType to match documented pgsql types
-                       see http://www.postgresql.org/devel-corner/docs/postgres/datatype.htm
+                         jlim - changed concat operator to || and data types to MetaType to match documented pgsql types
+                                        see http://www.postgresql.org/devel-corner/docs/postgres/datatype.htm
   22 Nov 2000 jlim - added changes to FetchField() and MetaTables() contributed by "raser" <raser@mail.zen.com.tw>
   27 Nov 2000 jlim - added changes to _connect/_pconnect from ideas by "Lennie" <leen@wirehub.nl>
   15 Dec 2000 jlim - added changes suggested by Additional code changes by "Eric G. Werk" egw@netguide.dk.
@@ -59,13 +59,13 @@ class ADODB_postgres64 extends ADOConnection{
        var $dataProvider = 'postgres';
        var $hasInsertID = true;
        var $_resultid = false;
-       var $concat_operator='||';
+       var $concat_operator='||';
        var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
-    var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
-       and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
-        'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
+       var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
+               and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
+                       'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
        union
-        select viewname,'V' from pg_views where viewname not like 'pg\_%'";
+               select viewname,'V' from pg_views where viewname not like 'pg\_%'";
        //"select tablename from pg_tables where tablename not like 'pg_%' order by 1";
        var $isoDates = true; // accepts dates in ISO format
        var $sysDate = "CURRENT_DATE";
@@ -74,19 +74,22 @@ class ADODB_postgres64 extends ADOConnection{
        var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
                FROM pg_class c, pg_attribute a,pg_type t
                WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
-AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
+               AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
 
        // used when schema defined
        var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
-FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
-WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
- and c.relnamespace=n.oid and n.nspname='%s'
-       and a.attname not like '....%%' AND a.attnum > 0
-       AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
+               FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
+               WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
              and c.relnamespace=n.oid and n.nspname='%s'
+               and a.attname not like '....%%' AND a.attnum > 0
+               AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
 
        // get primary key etc -- from Freek Dijkstra
        var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
-       FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
+               FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a
+               WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid
+               AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum)
+               AND a.attrelid = bc.oid AND bc.relname = '%s'";
 
        var $hasAffectedRows = true;
        var $hasLimit = false;  // set to true for pgsql 7 only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
@@ -119,9 +122,9 @@ WHERE relkind in ('r','v') AND (c.relname='%s' or c.relname = lower('%s'))
        // to know what the concequences are. The other values are correct (wheren't in 0.94)
        // -- Freek Dijkstra
 
-       function ADODB_postgres64()
+       function __construct()
        {
-       // changes the metaColumnsSQL, adds columns: attnum[6]
+               // changes the metaColumnsSQL, adds columns: attnum[6]
        }
 
        function ServerInfo()
@@ -165,11 +168,11 @@ a different OID if a database must be reloaded. */
 
 // I get this error with PHP before 4.0.6 - jlim
 // Warning: This compilation does not support pg_cmdtuples() in adodb-postgres.inc.php on line 44
-   function _affectedrows()
-   {
-               if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
-               return pg_cmdtuples($this->_resultid);
-   }
+       function _affectedrows()
+       {
+               if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
+               return pg_cmdtuples($this->_resultid);
+       }
 
 
                // returns true/false
@@ -208,22 +211,24 @@ a different OID if a database must be reloaded. */
        {
                $info = $this->ServerInfo();
                if ($info['version'] >= 7.3) {
-               $this->metaTablesSQL = "select table_name,'T' from information_schema.tables where table_schema not in ( 'pg_catalog','information_schema')
+               $this->metaTablesSQL = "
+                       select table_name,'T' from information_schema.tables where table_schema not in ( 'pg_catalog','information_schema')
                        union
-                      select table_name,'V' from information_schema.views where table_schema not in ( 'pg_catalog','information_schema') ";
+                       select table_name,'V' from information_schema.views where table_schema not in ( 'pg_catalog','information_schema') ";
                }
                if ($mask) {
                        $save = $this->metaTablesSQL;
                        $mask = $this->qstr(strtolower($mask));
                        if ($info['version']>=7.3)
-                               $this->metaTablesSQL = "select table_name,'T' from information_schema.tables where table_name like $mask and table_schema not in ( 'pg_catalog','information_schema')
-                       union
-                      select table_name,'V' from information_schema.views where table_name like $mask and table_schema not in ( 'pg_catalog','information_schema') ";
+                               $this->metaTablesSQL = "
+                                       select table_name,'T' from information_schema.tables where table_name like $mask and table_schema not in ( 'pg_catalog','information_schema')
+                                       union
+                                       select table_name,'V' from information_schema.views where table_name like $mask and table_schema not in ( 'pg_catalog','information_schema') ";
                        else
                                $this->metaTablesSQL = "
-select tablename,'T' from pg_tables where tablename like $mask
- union
-select viewname,'V' from pg_views where viewname like $mask";
+                                       select tablename,'T' from pg_tables where tablename like $mask
                                      union
+                                       select viewname,'V' from pg_views where viewname like $mask";
                }
                $ret = ADOConnection::MetaTables($ttype,$showSchema);
 
@@ -319,7 +324,7 @@ select viewname,'V' from pg_views where viewname like $mask";
                                $s .= 'DAY';
                                break;
 
-                        case 'W':
+                       case 'W':
                                $s .= 'WW';
                                break;
 
@@ -445,7 +450,7 @@ select viewname,'V' from pg_views where viewname like $mask";
        function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
        {
                if ($blobtype == 'CLOB') {
-               return $this->Execute("UPDATE $table SET $column=" . $this->qstr($val) . " WHERE $where");
+                       return $this->Execute("UPDATE $table SET $column=" . $this->qstr($val) . " WHERE $where");
                }
                // do not use bind params which uses qstr(), as blobencode() already quotes data
                return $this->Execute("UPDATE $table SET $column='".$this->BlobEncode($val)."'::bytea WHERE $where");
@@ -585,72 +590,80 @@ select viewname,'V' from pg_views where viewname like $mask";
 
        function Param($name,$type='C')
        {
-               $this->_pnum += 1;
+               if ($name) {
+                       $this->_pnum += 1;
+               } else {
+                       // Reset param num if $name is false
+                       $this->_pnum = 1;
+               }
                return '$'.$this->_pnum;
        }
 
-         function MetaIndexes ($table, $primary = FALSE, $owner = false)
-      {
-         global $ADODB_FETCH_MODE;
-
-                               $schema = false;
-                               $this->_findschema($table,$schema);
-
-                               if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
-                                       $sql = '
-SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
-FROM pg_catalog.pg_class c
-JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
-JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
-       ,pg_namespace n
-WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\'';
-                               } else {
-                       $sql = '
-SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
-FROM pg_catalog.pg_class c
-JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
-JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
-WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
-                       }
-
-                if ($primary == FALSE) {
-                       $sql .= ' AND i.indisprimary=false;';
-                }
-
-                $save = $ADODB_FETCH_MODE;
-                $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-                if ($this->fetchMode !== FALSE) {
-                        $savem = $this->SetFetchMode(FALSE);
-                }
-
-                $rs = $this->Execute(sprintf($sql,$table,$table,$schema));
-                if (isset($savem)) {
-                        $this->SetFetchMode($savem);
-                }
-                $ADODB_FETCH_MODE = $save;
-
-                if (!is_object($rs)) {
-                       $false = false;
-                                       return $false;
-                }
-
-                $col_names = $this->MetaColumnNames($table,true,true);
-                               //3rd param is use attnum,
-                               // see http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976
-                $indexes = array();
-                while ($row = $rs->FetchRow()) {
-                        $columns = array();
-                        foreach (explode(' ', $row[2]) as $col) {
-                                $columns[] = $col_names[$col];
-                        }
-
-                        $indexes[$row[0]] = array(
-                                'unique' => ($row[1] == 't'),
-                                'columns' => $columns
-                        );
-                }
-                return $indexes;
-        }
+       function MetaIndexes ($table, $primary = FALSE, $owner = false)
+       {
+               global $ADODB_FETCH_MODE;
+
+               $schema = false;
+               $this->_findschema($table,$schema);
+
+               if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
+                       $sql = '
+                               SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
+                               FROM pg_catalog.pg_class c
+                               JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
+                               JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
+                                       ,pg_namespace n
+                               WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))
+                               and c.relnamespace=c2.relnamespace
+                               and c.relnamespace=n.oid
+                               and n.nspname=\'%s\'';
+               } else {
+                       $sql = '
+                               SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
+                               FROM pg_catalog.pg_class c
+                               JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
+                               JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
+                               WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\'))';
+               }
+
+               if ($primary == FALSE) {
+                       $sql .= ' AND i.indisprimary=false;';
+               }
+
+               $save = $ADODB_FETCH_MODE;
+               $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+               if ($this->fetchMode !== FALSE) {
+                       $savem = $this->SetFetchMode(FALSE);
+               }
+
+               $rs = $this->Execute(sprintf($sql,$table,$table,$schema));
+               if (isset($savem)) {
+                       $this->SetFetchMode($savem);
+               }
+               $ADODB_FETCH_MODE = $save;
+
+               if (!is_object($rs)) {
+                       $false = false;
+                       return $false;
+               }
+
+               $col_names = $this->MetaColumnNames($table,true,true);
+               //3rd param is use attnum,
+               // see http://sourceforge.net/tracker/index.php?func=detail&aid=1451245&group_id=42718&atid=433976
+               $indexes = array();
+               while ($row = $rs->FetchRow()) {
+                       $columns = array();
+                       foreach (explode(' ', $row[2]) as $col) {
+                               $columns[] = $col_names[$col];
+                       }
+
+                       $indexes[$row[0]] = array(
+                               'unique' => ($row[1] == 't'),
+                               'columns' => $columns
+                       );
+               }
+               return $indexes;
+       }
 
        // returns true or false
        //
@@ -659,7