fmsystem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fmsystem-commits] [17470] API: upgrade adodb from upstream


From: sigurdne
Subject: [Fmsystem-commits] [17470] API: upgrade adodb from upstream
Date: Tue, 26 Dec 2017 06:22:56 -0500 (EST)

Revision: 17470
          http://svn.sv.gnu.org/viewvc/?view=rev&root=fmsystem&revision=17470
Author:   sigurdne
Date:     2017-12-26 06:22:55 -0500 (Tue, 26 Dec 2017)
Log Message:
-----------
API: upgrade adodb from upstream

Modified Paths:
--------------
    trunk/phpgwapi/inc/adodb/adodb-active-record.inc.php
    trunk/phpgwapi/inc/adodb/adodb-active-recordx.inc.php
    trunk/phpgwapi/inc/adodb/adodb-csvlib.inc.php
    trunk/phpgwapi/inc/adodb/adodb-datadict.inc.php
    trunk/phpgwapi/inc/adodb/adodb-error.inc.php
    trunk/phpgwapi/inc/adodb/adodb-errorhandler.inc.php
    trunk/phpgwapi/inc/adodb/adodb-errorpear.inc.php
    trunk/phpgwapi/inc/adodb/adodb-exceptions.inc.php
    trunk/phpgwapi/inc/adodb/adodb-iterator.inc.php
    trunk/phpgwapi/inc/adodb/adodb-lib.inc.php
    trunk/phpgwapi/inc/adodb/adodb-memcache.lib.inc.php
    trunk/phpgwapi/inc/adodb/adodb-pager.inc.php
    trunk/phpgwapi/inc/adodb/adodb-pear.inc.php
    trunk/phpgwapi/inc/adodb/adodb-perf.inc.php
    trunk/phpgwapi/inc/adodb/adodb-php4.inc.php
    trunk/phpgwapi/inc/adodb/adodb-time.inc.php
    trunk/phpgwapi/inc/adodb/adodb-xmlschema03.inc.php
    trunk/phpgwapi/inc/adodb/adodb.inc.php
    trunk/phpgwapi/inc/adodb/composer.json
    trunk/phpgwapi/inc/adodb/datadict/datadict-access.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-db2.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-firebird.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-ibase.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-informix.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-mssqlnative.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-oci8.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-sqlite.inc.php
    trunk/phpgwapi/inc/adodb/datadict/datadict-sybase.inc.php
    trunk/phpgwapi/inc/adodb/docs/changelog.md
    trunk/phpgwapi/inc/adodb/drivers/adodb-access.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-ado.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-ado5.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-ado_access.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-ado_mssql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-borland_ibase.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-csv.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-db2.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-db2oci.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-db2ora.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-fbsql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-firebird.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-ibase.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-informix.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-informix72.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-ldap.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mssql_n.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlnative.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlpo.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mysql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mysqli.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlpo.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlt.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-netezza.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-oci8.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-oci805.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-oci8po.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-oci8quercus.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-odbc.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-odbc_db2.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-odbc_mssql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-odbc_oracle.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-odbtp.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-odbtp_unicode.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-oracle.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-pdo.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-pdo_mssql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-pdo_mysql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-pdo_oci.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-pdo_pgsql.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-pdo_sqlite.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-pdo_sqlsrv.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-postgres.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-postgres64.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-postgres7.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-postgres8.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-postgres9.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-proxy.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-sapdb.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-sqlanywhere.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-sqlite.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-sqlite3.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-sqlitepo.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-sybase.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-sybase_ase.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-vfp.inc.php
    trunk/phpgwapi/inc/adodb/pear/Auth/Container/ADOdb.php
    trunk/phpgwapi/inc/adodb/perf/perf-db2.inc.php
    trunk/phpgwapi/inc/adodb/perf/perf-informix.inc.php
    trunk/phpgwapi/inc/adodb/perf/perf-mssql.inc.php
    trunk/phpgwapi/inc/adodb/perf/perf-mssqlnative.inc.php
    trunk/phpgwapi/inc/adodb/perf/perf-mysql.inc.php
    trunk/phpgwapi/inc/adodb/perf/perf-oci8.inc.php
    trunk/phpgwapi/inc/adodb/perf/perf-postgres.inc.php
    trunk/phpgwapi/inc/adodb/pivottable.inc.php
    trunk/phpgwapi/inc/adodb/rsfilter.inc.php
    trunk/phpgwapi/inc/adodb/server.php
    trunk/phpgwapi/inc/adodb/session/adodb-compress-bzip2.php
    trunk/phpgwapi/inc/adodb/session/adodb-compress-gzip.php
    trunk/phpgwapi/inc/adodb/session/adodb-cryptsession.php
    trunk/phpgwapi/inc/adodb/session/adodb-cryptsession2.php
    trunk/phpgwapi/inc/adodb/session/adodb-encrypt-mcrypt.php
    trunk/phpgwapi/inc/adodb/session/adodb-encrypt-md5.php
    trunk/phpgwapi/inc/adodb/session/adodb-encrypt-secret.php
    trunk/phpgwapi/inc/adodb/session/adodb-session-clob.php
    trunk/phpgwapi/inc/adodb/session/adodb-session-clob2.php
    trunk/phpgwapi/inc/adodb/session/adodb-session.php
    trunk/phpgwapi/inc/adodb/session/adodb-session2.php
    trunk/phpgwapi/inc/adodb/session/old/adodb-cryptsession.php
    trunk/phpgwapi/inc/adodb/session/old/adodb-session-clob.php
    trunk/phpgwapi/inc/adodb/session/old/adodb-session.php
    trunk/phpgwapi/inc/adodb/toexport.inc.php
    trunk/phpgwapi/inc/adodb/tohtml.inc.php

Added Paths:
-----------
    trunk/phpgwapi/inc/adodb/drivers/adodb-odbc_mssql2012.inc.php
    trunk/phpgwapi/inc/adodb/drivers/adodb-text.inc.php
    trunk/phpgwapi/inc/adodb/lang/adodb-id.inc.php
    trunk/phpgwapi/inc/adodb/lang/adodb-oc.inc.php

Modified: trunk/phpgwapi/inc/adodb/adodb-active-record.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-active-record.inc.php        2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-active-record.inc.php        2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 /*
 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Latest version is available at http://adodb.sourceforge.net
@@ -522,7 +522,7 @@
                        $activetab->_created = time();
                        $s = serialize($activetab);
                        if (!function_exists('adodb_write_file')) {
-                               include(ADODB_DIR.'/adodb-csvlib.inc.php');
+                               include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
                        }
                        adodb_write_file($fname,$s);
                }

Modified: trunk/phpgwapi/inc/adodb/adodb-active-recordx.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-active-recordx.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-active-recordx.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 /*
 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Latest version is available at http://adodb.sourceforge.net
@@ -551,7 +551,7 @@
                        $activetab->_created = time();
                        $s = serialize($activetab);
                        if (!function_exists('adodb_write_file')) {
-                               include(ADODB_DIR.'/adodb-csvlib.inc.php');
+                               include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
                        }
                        adodb_write_file($fname,$s);
                }
@@ -1300,7 +1300,7 @@
                
                
                if (!isset($_ADODB_ACTIVE_DBS)) {
-                       include(ADODB_DIR.'/adodb-active-record.inc.php');
+                       include_once(ADODB_DIR.'/adodb-active-record.inc.php');
                }       
                if (!class_exists($class)) {
                        $db->outp_throw("Unknown class $class in 
GetActiveRecordsClass()",'GetActiveRecordsClass');

Modified: trunk/phpgwapi/inc/adodb/adodb-csvlib.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-csvlib.inc.php       2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-csvlib.inc.php       2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -8,7 +8,7 @@
 
 /* 
 
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/adodb-datadict.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-datadict.inc.php     2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-datadict.inc.php     2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -326,7 +326,7 @@
                if (!$this->connection->IsConnected()) {
                        $t = strtoupper($t);
                        if (isset($typeMap[$t])) return $typeMap[$t];
-                       return 'N';
+                       return ADODB_DEFAULT_METATYPE;
                }
                return $this->connection->MetaType($t,$len,$fieldobj);
        }
@@ -520,7 +520,7 @@
                        list($lines,$pkey,$idxs) = $this->_GenFields($flds);
                        // genfields can return FALSE at times
                        if ($lines == null) $lines = array();
-                       list(,$first) = each($lines);
+                       $first  = current($lines);
                        list(,$column_def) = preg_split("/[\t ]+/",$first,2);
                }
                return 
array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def));
@@ -660,12 +660,17 @@
                        $funsigned = false;
                        $findex = '';
                        $funiqueindex = false;
+                       $fOptions         = array();
                        
                        //-----------------
                        // Parse attributes
                        foreach($fld as $attr => $v) {
-                               if ($attr == 2 && is_numeric($v)) $attr = 
'SIZE';
-                               else if (is_numeric($attr) && $attr > 1 && 
!is_numeric($v)) $attr = strtoupper($v);
+                               if ($attr == 2 && is_numeric($v)) 
+                                       $attr = 'SIZE';
+                               elseif ($attr == 2 && strtoupper($ftype) == 
'ENUM') 
+                                       $attr = 'ENUM';
+                               else if (is_numeric($attr) && $attr > 1 && 
!is_numeric($v)) 
+                                       $attr = strtoupper($v);
                                
                                switch($attr) {
                                case '0':
@@ -697,6 +702,8 @@
                                // let INDEX keyword create a 'very standard' 
index on column
                                case 'INDEX': $findex = $v; break;
                                case 'UNIQUE': $funiqueindex = true; break;
+                               case 'ENUM':
+                                       $fOptions['ENUM'] = $v; break;
                                } //switch
                        } // foreach $fld
                        
@@ -717,7 +724,7 @@
                                $ftype = strtoupper($ftype);
                        }
                        
-                       $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec);
+                       $ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec, 
$fOptions);
                        
                        if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull 
= false; // some blob types do not accept nulls
                        
@@ -806,7 +813,7 @@
                        $ftype is the actual type
                        $ty is the type defined originally in the DDL
        */
-       function _GetSize($ftype, $ty, $fsize, $fprec)
+       function _GetSize($ftype, $ty, $fsize, $fprec, $options=false)
        {
                if (strlen($fsize) && $ty != 'X' && $ty != 'B' && 
strpos($ftype,'(') === false) {
                        $ftype .= "(".$fsize;
@@ -813,6 +820,25 @@
                        if (strlen($fprec)) $ftype .= ",".$fprec;
                        $ftype .= ')';
                }
+               
+               /*
+               * Handle additional options
+               */
+               if (is_array($options))
+               {
+                       foreach($options as $type=>$value)
+                       {
+                               switch ($type)
+                               {
+                                       case 'ENUM':
+                                       $ftype .= '(' . $value . ')';
+                                       break;
+                                       
+                                       default:
+                               }
+                       }
+               }
+               
                return $ftype;
        }
        

Modified: trunk/phpgwapi/inc/adodb/adodb-error.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-error.inc.php        2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-error.inc.php        2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version   v5.20.9  21-Dec-2016
+ * @version   v5.21.0-dev  ??-???-2016
  * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  * Released under both BSD license and Lesser GPL library license. 
@@ -70,6 +70,10 @@
        case 'oracle':
        case 'oci8': $map = adodb_error_oci8(); break;
        
+       // As discussed in 
https://github.com/ADOdb/ADOdb/issues/201#issuecomment-188154980
+       // firebird uses the ibase error handler for now. This may change if and
+       // when the PHP driver is updated to use the new SQLSTATE error codes
+       case 'firebird':
        case 'ibase': $map = adodb_error_ibase(); break;
        
        case 'odbc': $map = adodb_error_odbc(); break;
@@ -111,7 +115,7 @@
                        'could not serialize access due to'   => 
DB_ERROR_SERIALIZATION_FAILURE
         );
        reset($error_regexps);
-    while (list($regexp,$code) = each($error_regexps)) {
+       foreach ($error_regexps as $regexp => $code) {
                if (preg_match("/$regexp/mi", $errormsg)) {
             return $code;
         }

Modified: trunk/phpgwapi/inc/adodb/adodb-errorhandler.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-errorhandler.inc.php 2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-errorhandler.inc.php 2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @version   v5.20.9  21-Dec-2016
+ * @version   v5.21.0-dev  ??-???-2016
  * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  * Released under both BSD license and Lesser GPL library license.

Modified: trunk/phpgwapi/inc/adodb/adodb-errorpear.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-errorpear.inc.php    2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-errorpear.inc.php    2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version   v5.20.9  21-Dec-2016
+ * @version   v5.21.0-dev  ??-???-2016
  * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  * Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/adodb-exceptions.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-exceptions.inc.php   2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-exceptions.inc.php   2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * @version   v5.20.9  21-Dec-2016
+ * @version   v5.21.0-dev  ??-???-2016
  * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  * Released under both BSD license and Lesser GPL library license.

Modified: trunk/phpgwapi/inc/adodb/adodb-iterator.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-iterator.inc.php     2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-iterator.inc.php     2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/adodb-lib.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-lib.inc.php  2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/adodb-lib.inc.php  2017-12-26 11:22:55 UTC (rev 
17470)
@@ -6,7 +6,7 @@
 $ADODB_INCLUDED_LIB = 1;
 
 /* 
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -416,7 +416,10 @@
                        } else
                                $rewritesql = "SELECT COUNT(*) FROM 
(".$rewritesql.")"; 
                        
-               } else if (strncmp($zthis->databaseType,'postgres',8) == 0 || 
strncmp($zthis->databaseType,'mysql',5) == 0)  {
+               } else if (strncmp($zthis->databaseType,'postgres',8) == 0
+                       || strncmp($zthis->databaseType,'mysql',5) == 0
+                       || strncmp($zthis->databaseType,'mssql',5) == 0
+               ) {
                        $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) 
_ADODB_ALIAS_";
                } else {
                        $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
@@ -467,17 +470,10 @@
        if ($rstest) {
                        $qryRecs = $rstest->RecordCount();
                if ($qryRecs == -1) { 
-               global $ADODB_EXTENSION;
                // some databases will return -1 on MoveLast() - change to 
MoveNext()
-                       if ($ADODB_EXTENSION) {
                                while(!$rstest->EOF) {
-                                       adodb_movenext($rstest);
-                               }
-                       } else {
-                               while(!$rstest->EOF) {
                                        $rstest->MoveNext();
                                }
-                       }
                        $qryRecs = $rstest->_currentRow;
                }
                $rstest->Close();
@@ -882,15 +878,15 @@
                {
                     switch ($force) {
 
-                        case 0: // we must always set null if missing
+                        case ADODB_FORCE_IGNORE: // we must always set null if 
missing
                                                        $bad = true;
                                                        break;
                                                        
-                        case 1:
+                        case ADODB_FORCE_NULL:
                             $values  .= "null, ";
                         break;
                
-                        case 2:
+                        case ADODB_FORCE_EMPTY:
                             //Set empty
                             $arrFields[$upperfname] = "";
                             $values .= _adodb_column_sql($zthis, 'I', $type, 
$upperfname, $fnameq,$arrFields, $magicq);
@@ -897,7 +893,7 @@
                         break;
 
                                                default:
-                        case 3:
+                        case ADODB_FORCE_VALUE:
                             //Set the value that was given in array, so you 
can give both null and empty values
                                                        if 
(is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === 
$zthis->null2null) { 
                                                                $values  .= 
"null, ";
@@ -905,6 +901,21 @@
                                        $values .= _adodb_column_sql($zthis, 
'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
                                        }
                                break;
+
+                                               case ADODB_FORCE_NULL_AND_ZERO:
+                                                       switch ($type)
+                                                       {
+                                                               case 'N':
+                                                               case 'I':
+                                                               case 'L':
+                                                                       $values 
.= '0, ';
+                                                                       break;
+                                                               default:
+                                                                       $values 
.= "null, ";
+                                                                       break;
+                                                       }
+                                               break;
+
                        } // switch
 
             /*********************************************************/

Modified: trunk/phpgwapi/inc/adodb/adodb-memcache.lib.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-memcache.lib.inc.php 2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-memcache.lib.inc.php 2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -11,7 +11,7 @@
 
 /* 
 
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -28,11 +28,14 @@
 $db->memCacheHost = array($ip1, $ip2, $ip3);
 $db->memCachePort = 11211; /// this is default memCache port
 $db->memCacheCompress = false; /// Use 'true' to store the item compressed 
(uses zlib)
+                               /// Note; compression is not supported w/the 
memcached library
 
 $db->Connect(...);
 $db->CacheExecute($sql);
   
-  Note the memcache class is shared by all connections, is created during the 
first call to Connect/PConnect.
+  Notes; The memcache class is shared by all connections, is created during 
the first call to Connect/PConnect.
+         We'll look for both the memcache library 
(https://pecl.php.net/package/memcache) and the  memcached
+         library (https://pecl.php.net/package/memcached). If both exist, the 
memcache library will be used.
   
   Class instance is stored in $ADODB_CACHE
 */
@@ -40,6 +43,11 @@
        class ADODB_Cache_MemCache {
                var $createdir = false; // create caching directory structure?
                
+               // $library will be populated with the proper library on connect
+               // and is used later when there are differences in specific 
calls
+               // between memcache and memcached
+               var $library = false;
+
                //-----------------------------
                // memcache specific variables
                
@@ -60,18 +68,23 @@
                // implement as lazy connection. The connection only occurs on 
CacheExecute call
                function connect(&$err)
                {
-                       if (!function_exists('memcache_pconnect')) {
-                               $err = 'Memcache module PECL extension not 
found!';
+                       // do we have memcache or memcached?
+                       if (class_exists('Memcache')) {
+                               $this->library='Memcache';
+                               $memcache = new MemCache;
+                       } elseif (class_exists('Memcached')) {
+                               $this->library='Memcached';
+                               $memcache = new MemCached;
+                       } else {
+                               $err = 'Neither the Memcache nor Memcached PECL 
extensions were found!';
                                return false;
                        }
 
-                       $memcache = new MemCache;
-                       
                        if (!is_array($this->hosts)) $this->hosts = 
array($this->hosts);
                
                        $failcnt = 0;
                        foreach($this->hosts as $host) {
-                               if 
(address@hidden>addServer($host,$this->port,true)) {
+                               if 
(address@hidden>addServer($host,$this->port)) {
                                        $failcnt += 1;
                                }
                        }
@@ -93,8 +106,25 @@
                        }
                        if (!$this->_memcache) return false;
                        
+                       $failed=false;
+                       switch ($this->library) {
+                               case 'Memcache':
                        if (!$this->_memcache->set($filename, $contents, 
$this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) {
-                               if ($debug) ADOConnection::outp(" Failed to 
save data at the memcached server!<br>\n");
+                                               $failed=true;
+                                       }
+                                       break;
+                               case 'Memcached':
+                                       if (!$this->_memcache->set($filename, 
$contents, $secs2cache)) {
+                                               $failed=true;
+                                       }
+                                       break;
+                               default:
+                                       $failed=true;
+                                       break;
+                       }
+
+                       if($failed) {
+                               if ($debug) ADOConnection::outp(" Failed to 
save data at the memcache server!<br>\n");
                                return false;
                        }
                        
@@ -110,7 +140,7 @@
                        
                        $rs = $this->_memcache->get($filename);
                        if (!$rs) {
-                               $err = 'Item with such key doesn\'t exists on 
the memcached server.';
+                               $err = 'Item with such key doesn\'t exist on 
the memcache server.';
                                return $false;
                        }
                        
@@ -176,8 +206,8 @@
                        $del = $this->_memcache->delete($filename);
                        
                        if ($debug) 
-                               if (!$del) ADOConnection::outp("flushcache: 
$key entry doesn't exist on memcached server!<br>\n");
-                               else ADOConnection::outp("flushcache: $key 
entry flushed from memcached server!<br>\n");
+                               if (!$del) ADOConnection::outp("flushcache: 
$key entry doesn't exist on memcache server!<br>\n");
+                               else ADOConnection::outp("flushcache: $key 
entry flushed from memcache server!<br>\n");
                                
                        return $del;
                }

Modified: trunk/phpgwapi/inc/adodb/adodb-pager.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-pager.inc.php        2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-pager.inc.php        2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-       @version   v5.20.9  21-Dec-2016
+       @version   v5.21.0-dev  ??-???-2016
        @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights 
reserved.
        @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb 
community
          Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/adodb-pear.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-pear.inc.php 2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/adodb-pear.inc.php 2017-12-26 11:22:55 UTC (rev 
17470)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version   v5.20.9  21-Dec-2016
+ * @version   v5.21.0-dev  ??-???-2016
  * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  * Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/adodb-perf.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-perf.inc.php 2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/adodb-perf.inc.php 2017-12-26 11:22:55 UTC (rev 
17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -147,7 +147,7 @@
                if (empty($d)) $d = date("'Y-m-d H:i:s'");
                if ($conn->dataProvider == 'oci8' && $dbT != 'oci8po') {
                        $isql = "insert into $perf_table 
values($d,:b,:c,:d,:e,:f)";
-               } else if ($dbT == 'odbc_mssql' || $dbT == 'informix' || 
strncmp($dbT,'odbtp',4)==0) {
+               } else if ($dbT == 'mssqlnative' || $dbT == 'odbc_mssql' || 
$dbT == 'informix' || strncmp($dbT,'odbtp',4)==0) {
                        $timer = $arr['f'];
                        if ($dbT == 'informix') $sql2 = substr($sql2,0,230);
 

Modified: trunk/phpgwapi/inc/adodb/adodb-php4.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-php4.inc.php 2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/adodb-php4.inc.php 2017-12-26 11:22:55 UTC (rev 
17470)
@@ -1,7 +1,7 @@
 <?php
 
 /*
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/adodb-time.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-time.inc.php 2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/adodb-time.inc.php 2017-12-26 11:22:55 UTC (rev 
17470)
@@ -3,7 +3,7 @@
 ADOdb Date Library, part of the ADOdb abstraction library
 Download: http://adodb.sourceforge.net/#download
 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
 
@@ -816,7 +816,7 @@
        
        if ($marr[$m] < $d) return false;
        
-       if ($y < 1000 && $y > 3000) return false;
+       if ($y < 1000 || $y > 3000) return false;
        
        return true;
 }
@@ -1071,7 +1071,6 @@
 global $ADODB_DATETIME_CLASS;
 static $jan1_1971;
 
-
        if (!isset($daylight)) {
                $daylight = function_exists('adodb_daylight_sv');
                if (empty($jan1_1971)) $jan1_1971 = mktime(0,0,0,1,1,1971); // 
we only use date() when > 1970 as adodb_mktime() only uses mktime() when > 1970
@@ -1079,7 +1078,15 @@
        
        if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
        if (!defined('ADODB_TEST_DATES')) {
-               if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit 
signed range
+
+               /*
+               * Format 'Q' is an ADOdb custom format, not supported in PHP
+               * so if there is a 'Q' in the format, we force it to use our
+               * function. There is a trivial overhead in this
+               */
+
+               if ((abs($d) <= 0x7FFFFFFF) && strpos($fmt,'Q') === false)
+               { // check if number in 32-bit signed range
                
                        if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 
$jan1_1971) // if windows, must be +ve integer
                                return ($is_gmt)? @gmdate($fmt,$d): 
@date($fmt,$d);
@@ -1145,7 +1152,9 @@
                case 'y': $dates .= substr($year,strlen($year)-2,2); break;
                // MONTH
                case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= 
$month; break;
-               case 'Q': $dates .= ($month+3)>>2; break;
+               case 'Q':
+                       $dates .= ceil($month / 3);
+                       break;
                case 'n': $dates .= $month; break;
                case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); 
break;
                case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); 
break;
@@ -1153,6 +1162,9 @@
                case 't': $dates .= $arr['ndays']; break;
                case 'z': $dates .= $arr['yday']; break;
                case 'w': $dates .= adodb_dow($year,$month,$day); break;
+               case 'W':
+                       $dates .= sprintf('%02d',ceil( $arr['yday'] / 7) - 1);
+                       break;
                case 'l': $dates .= 
gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
                case 'D': $dates .= 
gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
                case 'j': $dates .= $day; break;

Modified: trunk/phpgwapi/inc/adodb/adodb-xmlschema03.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb-xmlschema03.inc.php  2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/adodb-xmlschema03.inc.php  2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -506,7 +506,7 @@
        */
        function addTableOpt( $opt ) {
                if(isset($this->currentPlatform)) {
-                       $this->opts[$this->parent->db->databaseType] = $opt;
+                       $this->opts[$this->parent->db->dataProvider] = $opt;
                }
                return $this->opts;
        }

Modified: trunk/phpgwapi/inc/adodb/adodb.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/adodb.inc.php      2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/adodb.inc.php      2017-12-26 11:22:55 UTC (rev 
17470)
@@ -14,7 +14,7 @@
 /**
        \mainpage
        
-       @version   v5.20.9  21-Dec-2016
+       @version   v5.21.0-dev  ??-???-2016
        @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights 
reserved.
        @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb 
community
 
@@ -75,7 +75,6 @@
                $ADODB_CACHE_DIR,       // directory to cache recordsets
                $ADODB_CACHE,
                $ADODB_CACHE_CLASS,
-               $ADODB_EXTENSION,   // ADODB extension installed
                $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, 
$rs->fields is available on EOF
                $ADODB_FETCH_MODE,      // DEFAULT, NUM, ASSOC or BOTH. Default 
follows native driver default...
                $ADODB_GETONE_EOF,
@@ -85,25 +84,42 @@
        // GLOBAL SETUP
        
//==============================================================================================
        
        
-       $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
-       //
-       // 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.
-
+       /*********************************************************
+       * Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
+       * Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, 
nuko#mbnet.fi
+       * @link 
http://adodb.org/dokuwiki/doku.php?id=v5:reference:adodb_force_type
+       *
+       * 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.
+       * 4 = force value. Like 1 but numeric empty fields are set to zero.
+    */
         define('ADODB_FORCE_IGNORE',0);
         define('ADODB_FORCE_NULL',1);
         define('ADODB_FORCE_EMPTY',2);
         define('ADODB_FORCE_VALUE',3);
+               define('ADODB_FORCE_NULL_AND_ZERO',4);
        // ********************************************************
 
 
-       if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) {
+       /**
+        * Constants for returned values from the charMax and textMax methods.
+        * If not specifically defined in the driver, methods return the NOTSET 
value.
+        */
+       define ('ADODB_STRINGMAX_NOTSET', -1);
+       define ('ADODB_STRINGMAX_NOLIMIT',-2);
+
+       /*
+       * Defines the the default meta type returned
+       * when ADOdb encounters a type that it is not
+       * defined in the metaTypes.
+       */
+       if (!defined('ADODB_DEFAULT_METATYPE'))
+               define ('ADODB_DEFAULT_METATYPE','N');
                
                define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL 
invalid. Try using $connection->debug=true;</p>');
        
@@ -175,8 +191,8 @@
                        die("PHP5 or later required. You are running 
".PHP_VERSION);
        }
                unset($_adodb_ver);
-       }
 
+
        
        /**
                Accepts $src and $dest arrays, replacing string $data
@@ -232,7 +248,7 @@
                /**
                 * ADODB version as a string.
                 */
-               $ADODB_vers = 'v5.20.9  21-Dec-2016';
+               $ADODB_vers = 'v5.21.0-dev  ??-???-2016';
        
                /**
                 * Determines whether recordset->RecordCount() is used. 
@@ -472,7 +488,7 @@
        var $memCache = false; /// should we use memCache instead of caching in 
files
        var $memCacheHost; /// memCache host
        var $memCachePort = 11211; /// memCache port
-       var $memCacheCompress = false; /// Use 'true' to store the item 
compressed (uses zlib)
+       var $memCacheCompress = false; /// Use 'true' to store the item 
compressed (uses zlib, not supported w/memcached library)
 
        var $sysDate = false; /// name of function that returns the current date
        var $sysTimeStamp = false; /// name of function that returns the 
current timestamp
@@ -521,6 +537,17 @@
        var $_logsql = false;
        var $_transmode = ''; // transaction mode
        
+
+       /**
+        * Default Constructor.
+        * We define it even though it does not actually do anything. This 
avoids
+        * getting a PHP Fatal error:  Cannot call constructor if a subclass 
tries
+        * to call its parent constructor.
+        */
+       public function __construct()
+       {
+       }
+
        /*
         * Additional parameters that may be passed to drivers in the connect 
string
         * Driver must be coded to accept the parameters
@@ -543,7 +570,7 @@
        final public function setConnectionParameter($parameter,$value)
        {
 
-               $this->connectionParameters[$parameter] = $value;
+               $this->connectionParameters[] = array($parameter=>$value);
 
        }
 
@@ -601,8 +628,7 @@
                        $fn($msg,$newline);
                        return;
                } else if (isset($ADODB_OUTP)) {
-                       $fn = $ADODB_OUTP;
-                       $fn($msg,$newline);
+                       call_user_func($ADODB_OUTP,$msg,$newline);
                        return;
                }
                
@@ -1102,11 +1128,11 @@
        /**
         * Execute SQL 
         *
-        * @param sql           SQL statement to execute, or possibly an array 
holding prepared statement ($sql[0] will hold sql text)
-        * @param [inputarr]    holds the input data to bind to. Null elements 
will be set to null.
-        * @return              RecordSet or false
+        * @param string $sql SQL statement to execute, or possibly an array 
holding prepared statement ($sql[0] will hold sql text)
+        * @param false|array $inputarr holds the input data to bind to. Null 
elements will be set to null.
+        * @return false|ADORecordSet
         */
-       function Execute($sql,$inputarr=false) {
+       public function Execute($sql, $inputarr = false) {
                if ($this->fnExecute) {
                        $fn = $this->fnExecute;
                        $ret = $fn($this,$sql,$inputarr);
@@ -1163,8 +1189,7 @@
        
                                foreach($inputarr as $arr) {
                                        $sql = ''; $i = 0;
-                                       //Use each() instead of foreach to 
reduce memory usage -mikefedyk
-                                       while(list(, $v) = each($arr)) {
+                                       foreach ($arr as $v) {
                                                $sql .= $sqlarr[$i];
                                                // from Ron Baldwin 
<ron.baldwin#sourceprose.com>
                                                // Only quote string types      
@@ -1244,7 +1269,7 @@
                if ($this->debug) {
                        global $ADODB_INCLUDED_LIB;
                        if (empty($ADODB_INCLUDED_LIB)) {
-                               include(ADODB_DIR.'/adodb-lib.inc.php');
+                               include_once(ADODB_DIR.'/adodb-lib.inc.php');
                        }
                        $this->_queryID = _adodb_debug_execute($this, 
$sql,$inputarr);
                } else {
@@ -1275,8 +1300,17 @@
                        return $rs;
                }
                
+               if ($this->dataProvider == 'pdo' && $this->databaseType != 
'pdo') {
+                       // PDO uses a slightly different naming convention for 
the
+                       // recordset class if the database type is changed, so 
we must
+                       // treat it specifically. The mysql driver leaves the
+                       // databaseType as pdo
+                       $rsclass = $this->rsPrefix . 'pdo_' . 
$this->databaseType;
+               } else {
+                       $rsclass = $this->rsPrefix . $this->databaseType;
+               }
+
                // return real recordset from select statement
-               $rsclass = $this->rsPrefix.$this->databaseType;
                $rs = new $rsclass($this->_queryID,$this->fetchMode);
                $rs->connection = $this; // Pablo suggestion
                $rs->Init();
@@ -1471,8 +1505,8 @@
        /**
         * Choose a database to connect to. Many databases do not support this.
         *
-        * @param dbName        is the name of the database to select
-        * @return              true or false
+        * @param string $dbName the name of the database to select
+        * @return bool
         */
        function SelectDB($dbName) {return false;}
        
@@ -1497,6 +1531,9 @@
        * @return               the recordset ($rs->databaseType == 'array')
        */
        function SelectLimit($sql,$nrows=-1,$offset=-1, 
$inputarr=false,$secs2cache=0) {
+               $nrows = (int)$nrows;
+               $offset = (int)$offset;
+
                if ($this->hasTop && $nrows > 0) {
                // suggested by Reinhard Balling. Access requires top after 
distinct 
                 // Informix requires first before distinct - F Riosa
@@ -1511,7 +1548,10 @@
                                        // access includes ties in result
                                        if ($isaccess) {
                                                $sql = preg_replace(
-                                               
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' 
'.((integer)$nrows).' ',$sql);
+                                               
'/(^\s*select\s+(distinctrow|distinct)?)/i',
+                                               '\\1 '.$this->hasTop.' 
'.$nrows.' ',
+                                               $sql
+                                       );
 
                                                if ($secs2cache != 0) {
                                                        $ret = 
$this->CacheExecute($secs2cache, $sql,$inputarr);
@@ -1521,19 +1561,31 @@
                                                return $ret; // PHP5 fix
                                        } else if ($ismssql){
                                                $sql = preg_replace(
-                                               
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' 
'.((integer)$nrows).' ',$sql);
+                                               
'/(^\s*select\s+(distinctrow|distinct)?)/i',
+                                               '\\1 '.$this->hasTop.' 
'.$nrows.' ',
+                                               $sql
+                                       );
                                        } else {
                                                $sql = preg_replace(
-                                               '/(^\s*select\s)/i','\\1 
'.$this->hasTop.' '.((integer)$nrows).' ',$sql);
+                                               '/(^\s*select\s)/i',
+                                               '\\1 '.$this->hasTop.' 
'.$nrows.' ',
+                                               $sql
+                                       );
                                        }
                        } else {
                                $nn = $nrows + $offset;
                                if ($isaccess || $ismssql) {
                                        $sql = preg_replace(
-                                       
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.$nn.' 
',$sql);
+                                               
'/(^\s*select\s+(distinctrow|distinct)?)/i',
+                                               '\\1 '.$this->hasTop.' '.$nn.' 
',
+                                               $sql
+                                       );
                                } else {
                                        $sql = preg_replace(
-                                       '/(^\s*select\s)/i','\\1 
'.$this->hasTop.' '.$nn.' ',$sql);
+                                               '/(^\s*select\s)/i',
+                                               '\\1 '.$this->hasTop.' '.$nn.' 
',
+                                               $sql
+                                       );
                                }
                        }
                }
@@ -1627,16 +1679,36 @@
                return $arr;
        }
        
-       function GetAssoc($sql, $inputarr=false,$force_array = false, 
$first2cols = false) {
+       /**
+        * @param string $sql
+        * @param false|array $inputarr
+        * @param bool $force_array
+        * @param bool $first2cols
+        * @return false|array
+        */
+       public function GetAssoc($sql, $inputarr = false, $force_array = false, 
$first2cols = false) {
+               global $ADODB_FETCH_MODE;
+
                $rs = $this->Execute($sql, $inputarr);
+
                if (!$rs) {
+                       /*
+                       * Execution failure
+                       */
                        return false;
                }
-               $arr = $rs->GetAssoc($force_array,$first2cols);
-               return $arr;
+               return $rs->GetAssoc($force_array, $first2cols);
        }
        
-       function CacheGetAssoc($secs2cache, $sql=false, 
$inputarr=false,$force_array = false, $first2cols = false) {
+       /**
+        * @param int $secs2cache
+        * @param false|string $sql
+        * @param false|array $inputarr
+        * @param bool $force_array
+        * @param bool $first2cols
+        * @return false|array
+        */
+       public function CacheGetAssoc($secs2cache, $sql = false, $inputarr = 
false,$force_array = false, $first2cols = false) {
                if (!is_numeric($secs2cache)) {
                        $first2cols = $force_array;
                        $force_array = $inputarr;
@@ -1645,8 +1717,7 @@
                if (!$rs) {
                        return false;
                }
-               $arr = $rs->GetAssoc($force_array,$first2cols);
-               return $arr;
+               return $rs->GetAssoc($force_array, $first2cols);
        }
        
        /**
@@ -1653,10 +1724,11 @@
        * Return first element of first row of sql statement. Recordset is 
disposed
        * for you.
        *
-       * @param sql                    SQL statement
-       * @param [inputarr]             input bind array
+        * @param string                $sql            SQL statement
+        * @param array|bool    $inputarr       input bind array
+        * @return mixed
        */
-       function GetOne($sql,$inputarr=false) {
+       public function GetOne($sql, $inputarr=false) {
        global $ADODB_COUNTRECS,$ADODB_GETONE_EOF;
 
                $crecs = $ADODB_COUNTRECS;
@@ -1902,7 +1974,7 @@
        function Replace($table, $fieldArray, $keyCol, $autoQuote=false, 
$has_autoinc=false) {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) {
-                       include(ADODB_DIR.'/adodb-lib.inc.php');
+                       include_once(ADODB_DIR.'/adodb-lib.inc.php');
                }
                
                return _adodb_replace($this, $table, $fieldArray, $keyCol, 
$autoQuote, $has_autoinc);
@@ -2129,6 +2201,10 @@
                $forceUpdate means that even if the data has not changed, 
perform update.
         */
        function AutoExecute($table, $fields_values, $mode = 'INSERT', $where = 
false, $forceUpdate = true, $magicq = false) {
+               if (empty($fields_values)) {
+                       $this->outp_throw('AutoExecute: Empty fields array', 
'AutoExecute');
+                       return false;
+               }
                if ($where === false && ($mode == 'UPDATE' || $mode == 2 /* 
DB_AUTOQUERY_UPDATE */) ) {
                        $this->outp_throw('AutoExecute: Illegal mode=UPDATE 
with empty WHERE clause', 'AutoExecute');
                        return false;
@@ -2187,7 +2263,7 @@
                // ********************************************************
 
                if (empty($ADODB_INCLUDED_LIB)) {
-                       include(ADODB_DIR.'/adodb-lib.inc.php');
+                       include_once(ADODB_DIR.'/adodb-lib.inc.php');
                }
                return 
_adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force);
        }
@@ -2207,7 +2283,7 @@
                        $force = $ADODB_FORCE_TYPE;
                }
                if (empty($ADODB_INCLUDED_LIB)) {
-                       include(ADODB_DIR.'/adodb-lib.inc.php');
+                       include_once(ADODB_DIR.'/adodb-lib.inc.php');
                }
                return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$force);
        }
@@ -2392,6 +2468,7 @@
         */
        function Close() {
                $rez = $this->_close();
+               $this->_queryID = false;
                $this->_connectionID = false;
                return $rez;
        }
@@ -3005,7 +3082,7 @@
        function PageExecute($sql, $nrows, $page, $inputarr=false, 
$secs2cache=0) {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) {
-                       include(ADODB_DIR.'/adodb-lib.inc.php');
+                       include_once(ADODB_DIR.'/adodb-lib.inc.php');
                }
                if ($this->pageExecuteCountRows) {
                        $rs = _adodb_pageexecute_all_rows($this, $sql, $nrows, 
$page, $inputarr, $secs2cache);
@@ -3039,6 +3116,85 @@
                return $rs;
        }
 
+       /**
+       * Returns the maximum size of a MetaType C field. If the method
+       * is not defined in the driver returns ADODB_STRINGMAX_NOTSET
+       *
+       * @return int
+       */
+       function charMax()
+       {
+               return ADODB_STRINGMAX_NOTSET;
+       }
+
+       /**
+       * Returns the maximum size of a MetaType X field. If the method
+       * is not defined in the driver returns ADODB_STRINGMAX_NOTSET
+       *
+       * @return int
+       */
+       function textMax()
+       {
+               return ADODB_STRINGMAX_NOTSET;
+       }
+
+       /**
+       * Returns a substring of a varchar type field
+       *
+       * Some databases have variations of the parameters, which is why
+       * we have an ADOdb function for it
+       *
+       * @param        string  $fld    The field to sub-string
+       * @param        int             $start  The start point
+       * @param        int             $length An optional length
+       *
+       * @return       The SQL text
+       */
+       function substr($fld,$start,$length=0) {
+               $text = "{$this->substr}($fld,$start";
+               if ($length > 0)
+                       $text .= ",$length";
+               $text .= ')';
+               return $text;
+       }
+
+       /*
+        * Formats the date into Month only format MM with leading zeroes
+        *
+        * @param       string          $fld    The name of the date to format
+        *
+        * @return      string                          The SQL text
+        */
+       function month($fld) {
+               $x = $this->sqlDate('m',$fld);
+
+               return $x;
+       }
+
+       /*
+        * Formats the date into Day only format DD with leading zeroes
+        *
+        * @param       string          $fld    The name of the date to format
+        * @return      string          The SQL text
+        */
+       function day($fld) {
+               $x = $this->sqlDate('d',$fld);
+               return $x;
+       }
+
+       /*
+        * Formats the date into year only format YYYY
+        *
+        * @param       string          $fld The name of the date to format
+        *
+        * @return      string          The SQL text
+        */
+       function year($fld) {
+               $x = $this->sqlDate('Y',$fld);
+               return $x;
+       }
+
+
 } // end class ADOConnection
        
        
@@ -3175,7 +3331,7 @@
        // DATE AND TIME FUNCTIONS
        
//==============================================================================================
        
        if (!defined('ADODB_DATE_VERSION')) {
-               include(ADODB_DIR.'/adodb-time.inc.php');
+               include_once(ADODB_DIR.'/adodb-time.inc.php');
        }
        
        
//==============================================================================================
        
@@ -3339,7 +3495,7 @@
        {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) {
-                       include(ADODB_DIR.'/adodb-lib.inc.php');
+                       include_once(ADODB_DIR.'/adodb-lib.inc.php');
                }
                return _adodb_getmenu($this, 
$name,$defstr,$blank1stItem,$multiple,
                        $size, $selectAttr,$compareFields0);
@@ -3367,7 +3523,7 @@
        {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) {
-                       include(ADODB_DIR.'/adodb-lib.inc.php');
+                       include_once(ADODB_DIR.'/adodb-lib.inc.php');
                }
                return _adodb_getmenu_gp($this, 
$name,$defstr,$blank1stItem,$multiple,
                        $size, $selectAttr,false);
@@ -3381,10 +3537,6 @@
         * @return an array indexed by the rows (0-based) from the recordset
         */
        function GetArray($nRows = -1) {
-       global $ADODB_EXTENSION; if ($ADODB_EXTENSION) {
-               $results = adodb_getall($this,$nRows);
-               return $results;
-       }
                $results = array();
                $cnt = 0;
                while (!$this->EOF && $nRows != $cnt) {
@@ -3449,123 +3601,149 @@
        }
        
        /**
-        * return whole recordset as a 2-dimensional associative array if there 
are more than 2 columns. 
-        * The first column is treated as the key and is not included in the 
array. 
-        * If there is only 2 columns, it will return a 1 dimensional array of 
key-value pairs unless
-        * $force_array == true.
+        * return whole recordset as a 2-dimensional associative array if
+        * there are more than 2 columns. The first column is treated as the
+        * key and is not included in the array. If there is only 2 columns,
+        * it will return a 1 dimensional array of key-value pairs unless
+        * $force_array == true. This recordset method is currently part of
+        * the API, but may not be in later versions of ADOdb. By preference, 
use
+        * ADOconnnection::getAssoc()
         *
-        * @param [force_array] has only meaning if we have 2 data columns. If 
false, a 1 dimensional
-        *      array is returned, otherwise a 2 dimensional array is returned. 
If this sounds confusing,
+        * @param bool  $force_array    (optional) Has only meaning if we have 
2 data
+        *                                                              
columns. If false, a 1 dimensional
+        *                                                              array 
is returned, otherwise a 2 dimensional
+        *                                                              array 
is returned. If this sounds confusing,
         *      read the source.
         *
-        * @param [first2cols] means if there are more than 2 cols, ignore the 
remaining cols and 
-        * instead of returning array[col0] => array(remaining cols), return 
array[col0] => col1
+        * @param bool  $first2cols     (optional) Means if there are more than
+        *                                                              2 cols, 
ignore the remaining cols and
+        *                                                              instead 
of returning
+        *                                                              
array[col0] => array(remaining cols),
+        *                                                              return 
array[col0] => col1
         *
-        * @return an associative array indexed by the first column of the 
array, 
-        *      or false if the  data has less than 2 cols.
+        * @return mixed
+        *
         */
-       function GetAssoc($force_array = false, $first2cols = false) {
-       global $ADODB_EXTENSION;
+       function getAssoc($force_array = false, $first2cols = false)
+       {
        
-               $cols = $this->_numOfFields;
-               if ($cols < 2) {
-                       return false;
-               }
+               global $ADODB_FETCH_MODE;
+               /*
+               * Insufficient rows to show data
+               */
+               if ($this->_numOfFields < 2)
+                         return;
 
-               // Empty recordset
+               /*
+               * Empty recordset
+               */
                if (!$this->fields) {
                        return array();
                }
 
-               // Determine whether the array is associative or 0-based numeric
-               $numIndex = array_keys($this->fields) == range(0, 
count($this->fields) - 1);
+               $numberOfFields = $this->_numOfFields;
+               $fetchMode      = $ADODB_FETCH_MODE;
 
-               $results = array();
+               if ($fetchMode == ADODB_FETCH_BOTH)
+               {
+                       /*
+                       * build a template of numeric keys. you could improve 
the
+                       * speed by caching this, indexed by number of keys
+                       */
+                       $testKeys = array_fill(0,$numberOfFields,0);
                
-               if (!$first2cols && ($cols > 2 || $force_array)) {
-                       if ($ADODB_EXTENSION) {
-                               if ($numIndex) {
-                                       while (!$this->EOF) {
-                                               
$results[trim($this->fields[0])] = array_slice($this->fields, 1);
-                                               adodb_movenext($this);
+                       /*
+                       * We use the associative method if ADODB_FETCH_BOTH
+                       */
+                       $fetchMode = ADODB_FETCH_ASSOC;
                                        }
-                               } else {
-                                       while (!$this->EOF) {
-                                       // Fix for array_slice re-numbering 
numeric associative keys
-                                               $keys = 
array_slice(array_keys($this->fields), 1);
-                                               $sliced_array = array();
 
-                                               foreach($keys as $key) {
-                                                       $sliced_array[$key] = 
$this->fields[$key];
-                                               }
+               $showArrayMethod = 0;
                                                
-                                               
$results[trim(reset($this->fields))] = $sliced_array;
-                                               adodb_movenext($this);
-                                       }
-                               }
-                       } else {
-                               if ($numIndex) {
-                                       while (!$this->EOF) {
-                                               
$results[trim($this->fields[0])] = array_slice($this->fields, 1);
-                                               $this->MoveNext();
-                                       }
-                               } else {
-                                       while (!$this->EOF) {
-                                       // Fix for array_slice re-numbering 
numeric associative keys
-                                               $keys = 
array_slice(array_keys($this->fields), 1);
-                                               $sliced_array = array();
+               if ($numberOfFields == 2)
+                       /*
+                       * Key is always value of first element
+                       * Value is alway value of second element
+                       */
+                       $showArrayMethod = 1;
 
-                                               foreach($keys as $key) {
-                                                       $sliced_array[$key] = 
$this->fields[$key];
-                                               }
+               if ($force_array)
+                       $showArrayMethod = 0;
                                                
-                                               
$results[trim(reset($this->fields))] = $sliced_array;
-                                               $this->MoveNext();
+               if ($first2cols)
+                       $showArrayMethod = 1;
+
+               $results  = array();
+
+               while (!$this->EOF){
+
+                       $myFields = $this->fields;
+
+                       if ($fetchMode == ADODB_FETCH_BOTH)
+                       {
+                               /*
+                               * extract the associative keys
+                               */
+                               $myFields = array_diff_key($myFields,$testKeys);
                                        }
+
+                       /*
+                       * key is value of first element, rest is data,
+                       * The key is not case processed
+                       */
+                       $key = array_shift($myFields);
+                       
+                       switch ($showArrayMethod)
+                       {
+                       case 0:
+
+                               if ($fetchMode == ADODB_FETCH_ASSOC)
+                               {
+                                       /*
+                                       * The driver should have already 
handled the key
+                                       * casing, but in case it did not. We 
will check and force
+                                       * this in later versions of ADOdb
+                                       */
+                                       if (ADODB_ASSOC_CASE == 
ADODB_ASSOC_CASE_UPPER)
+                                               $myFields = 
array_change_key_case($myFields,CASE_UPPER);
+
+                                       elseif (ADODB_ASSOC_CASE == 
ADODB_ASSOC_CASE_LOWER)
+                                               $myFields = 
array_change_key_case($myFields,CASE_LOWER);
+
+                                       /*
+                                       * We have already shifted the key off
+                                       * the front, so the rest is the value
+                                       */
+                                       $results[$key] = $myFields;
+
                                }
-                       }
-               } else {
-                       if ($ADODB_EXTENSION) {
-                               // return scalar values
-                               if ($numIndex) {
-                                       while (!$this->EOF) {
-                                       // some bug in mssql PHP 4.02 -- 
doesn't handle references properly so we FORCE creating a new string
-                                               
$results[trim(($this->fields[0]))] = $this->fields[1];
-                                               adodb_movenext($this);
+                               else
+                                       /*
+                                        * I want the values in a numeric array,
+                                        * nicely re-indexed from zero
+                                        */
+                                       $results[$key] = 
array_values($myFields);
+                               break;
+
+                       case 1:
+
+                               /*
+                                * Don't care how long the array is,
+                                * I just want value of second column, and it 
doesn't
+                                * matter whether the array is associative or 
numeric
+                                */
+                               $results[$key] = array_shift($myFields);
+                               break;
                                        }
-                               } else {
-                                       while (!$this->EOF) {
-                                       // some bug in mssql PHP 4.02 -- 
doesn't handle references properly so we FORCE creating a new string
-                                               $v1 = 
trim(reset($this->fields));
-                                               $v2 = ''.next($this->fields); 
-                                               $results[$v1] = $v2;
-                                               adodb_movenext($this);
-                                       }
-                               }
-                       } else {
-                               if ($numIndex) {
-                                       while (!$this->EOF) {
-                                       // some bug in mssql PHP 4.02 -- 
doesn't handle references properly so we FORCE creating a new string
-                                               
$results[trim(($this->fields[0]))] = $this->fields[1];
+
                                                $this->MoveNext();
                                        }
-                               } else {
-                                       while (!$this->EOF) {
-                                       // some bug in mssql PHP 4.02 -- 
doesn't handle references properly so we FORCE creating a new string
-                                               $v1 = 
trim(reset($this->fields));
-                                               $v2 = ''.next($this->fields); 
-                                               $results[$v1] = $v2;
-                                               $this->MoveNext();
-                                       }
-                               }
-                       }
-               }
-               
-               $ref = $results; # workaround accelerator incompat with PHP 4.4 
:(
-               return $ref; 
+               /*
+                * Done
+                */
+               return $results;
        }
        
-       
        /**
         *
         * @param v     is the character timestamp in YYYY-MM-DD hh:mm:ss format
@@ -3784,12 +3962,6 @@
                        if ($rowNumber < $this->_currentRow) {
                                return false;
                        }
-                       global $ADODB_EXTENSION;
-                       if ($ADODB_EXTENSION) {
-                               while (!$this->EOF && $this->_currentRow < 
$rowNumber) {
-                                       adodb_movenext($this);
-                               }
-                       } else {
                                while (! $this->EOF && $this->_currentRow < 
$rowNumber) {
                                        $this->_currentRow++;
                                        
@@ -3797,7 +3969,6 @@
                                                $this->EOF = true;
                                        }
                                }
-                       }
                        return !($this->EOF);
                }
                
@@ -4010,9 +4181,12 @@
         *
         */
        function FieldTypesArray() {
-               $arr = array();
-               for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) 
+               static $arr = array();
+               if (empty($arr)) {
+                       for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) {
                        $arr[] = $this->FetchField($i);
+                       }
+               }
                return $arr;
        }
        
@@ -4134,6 +4308,7 @@
                        $len = $fieldobj->max_length;
                }
 
+
        // changed in 2.32 to hashing instead of switch stmt for speed...
        static $typeMap = array(
                'VARCHAR' => 'C',
@@ -4240,9 +4415,10 @@
                "SQLBOOL" => 'L'
                );
                
+
                $tmap = false;
                $t = strtoupper($t);
-               $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N';
+               $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 
ADODB_DEFAULT_METATYPE;
                switch ($tmap) {
                case 'C':
                        // is the char field is too long, return as text 
field... 
@@ -4395,7 +4571,7 @@
                global $ADODB_INCLUDED_LIB;
                        
                        if (empty($ADODB_INCLUDED_LIB)) {
-                               include(ADODB_DIR.'/adodb-lib.inc.php');
+                               include_once(ADODB_DIR.'/adodb-lib.inc.php');
                        }
                        $hdr = true;
                        
@@ -4615,7 +4791,13 @@
                                break;
 
                        default:
-                               $class = $db; break;
+                               if (substr($db, 0, 4) === 'pdo_') {
+                                       ADOConnection::outp("Invalid database 
type: $db");
+                                       return false;
+                               }
+
+                               $class = $db;
+                               break;
                }
                
                $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php";
@@ -4967,7 +5149,7 @@
        function adodb_backtrace($printOrArr=true,$levels=9999,$ishtml=null) {
                global $ADODB_INCLUDED_LIB;
                if (empty($ADODB_INCLUDED_LIB)) {
-                       include(ADODB_DIR.'/adodb-lib.inc.php');
+                       include_once(ADODB_DIR.'/adodb-lib.inc.php');
                }
                return _adodb_backtrace($printOrArr,$levels,0,$ishtml);
        }

Modified: trunk/phpgwapi/inc/adodb/composer.json
===================================================================
--- trunk/phpgwapi/inc/adodb/composer.json      2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/composer.json      2017-12-26 11:22:55 UTC (rev 
17470)
@@ -27,7 +27,7 @@
        },
 
        "require" : {
-               "php" : ">=5.3.2"
+               "php" : "^5.3.2 || ^7.0"
        },
 
        "autoload" : {

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-access.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-access.inc.php   2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-access.inc.php   2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-db2.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-db2.inc.php      2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-db2.inc.php      2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -73,8 +73,7 @@
                return array();
        }
        
-       
-       function ChangeTableSQL($tablename, $flds, $tableoptions = false)
+       function ChangeTableSQL($tablename, $flds, $tableoptions = false, 
$dropOldFlds=false)
        {
                
                /**

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-firebird.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-firebird.inc.php 2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-firebird.inc.php 2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -12,22 +12,31 @@
  
 */
 
+// security - hide paths
+if (!defined('ADODB_DIR')) die();
+
 class ADODB2_firebird extends ADODB_DataDict {
        
        var $databaseType = 'firebird';
        var $seqField = false;
-       var $seqPrefix = 'gen_';
+       var $seqPrefix = 's_';
        var $blobSize = 40000;  
+       var $renameColumn = 'ALTER TABLE %s ALTER %s TO %s';
+       var $alterCol = ' ALTER';
+       var $dropCol = ' DROP';
        
        function ActualType($meta)
        {
                switch($meta) {
                case 'C': return 'VARCHAR';
-               case 'XL': return 'VARCHAR(32000)'; 
-               case 'X': return 'VARCHAR(4000)'; 
+               case 'XL':
+               case 'X': return 'BLOB SUB_TYPE TEXT';
+
+               case 'C2': return 'VARCHAR(32765)'; // up to 32K
+               case 'X2': return 'VARCHAR(4096)';
                
-               case 'C2': return 'VARCHAR'; // up to 32K
-               case 'X2': return 'VARCHAR(4000)';
+               case 'V': return 'CHAR';
+               case 'C1': return 'CHAR(1)';
                
                case 'B': return 'BLOB';
                        
@@ -40,7 +49,7 @@
                case 'I1': return 'SMALLINT';
                case 'I2': return 'SMALLINT';
                case 'I4': return 'INTEGER';
-               case 'I8': return 'INTEGER';
+               case 'I8': return 'BIGINT';
                
                case 'F': return 'DOUBLE PRECISION';
                case 'N': return 'DECIMAL';
@@ -49,7 +58,7 @@
                }
        }
        
-       function NameQuote($name = NULL)
+       function NameQuote($name = NULL,$allowBrackets=false)
        {
                if (!is_string($name)) {
                        return FALSE;
@@ -90,9 +99,9 @@
        {
                if (strpos($t,'.') !== false) {
                        $tarr = explode('.',$t);
-                       return 'DROP GENERATOR '.$tarr[0].'."gen_'.$tarr[1].'"';
+                       return 'DROP GENERATOR '.$tarr[0].'."s_'.$tarr[1].'"';
                }
-               return 'DROP GENERATOR "GEN_'.$t;
+               return 'DROP GENERATOR s_'.$t;
        }
        
 
@@ -103,11 +112,41 @@
                if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
                if ($fnotnull) $suffix .= ' NOT NULL';
                if ($fautoinc) $this->seqField = $fname;
+               $fconstraint = preg_replace("/``/", "\"", $fconstraint);
                if ($fconstraint) $suffix .= ' '.$fconstraint;
                
                return $suffix;
        }
        
+       /**
+        Generate the SQL to create table. Returns an array of sql strings.
+       */
+       function CreateTableSQL($tabname, $flds, $tableoptions=array())
+       {
+               list($lines,$pkey,$idxs) = $this->_GenFields($flds, true);
+               // genfields can return FALSE at times
+               if ($lines == null) $lines = array();
+
+               $taboptions = $this->_Options($tableoptions);
+               $tabname = $this->TableName ($tabname);
+               $sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
+
+               if ($this->autoIncrement && !isset($taboptions['DROP']))
+               { $tsql = $this->_Triggers($tabname,$taboptions);
+                       foreach($tsql as $s) $sql[] = $s;
+               }
+
+               if (is_array($idxs)) {
+                       foreach($idxs as $idx => $idxdef) {
+                               $sql_idxs = $this->CreateIndexSql($idx, 
$tabname,  $idxdef['cols'], $idxdef['opts']);
+                               $sql = array_merge($sql, $sql_idxs);
+                       }
+               }
+
+               return $sql;
+       }
+
+
 /*
 CREATE or replace TRIGGER jaddress_insert
 before insert on jaddress
@@ -128,20 +167,24 @@
                        else $tab = $tab1;
                        $seqField = $this->seqField;
                        $seqname = $this->schema.'.'.$this->seqPrefix.$tab;
-                       $trigname = 
$this->schema.'.trig_'.$this->seqPrefix.$tab;
+                       $trigname = $this->schema.'.t_'.$this->seqPrefix.$tab;
                } else {
                        $seqField = $this->seqField;
                        $seqname = $this->seqPrefix.$tab1;
-                       $trigname = 'trig_'.$seqname;
+                       $trigname = 't_'.$seqname;
                }
-               if (isset($tableoptions['REPLACE']))
+
+               if (isset($tableoptions['DROP']))
+               { $sql[] = "DROP GENERATOR $seqname";
+               }
+               elseif (isset($tableoptions['REPLACE']))
                { $sql[] = "DROP GENERATOR \"$seqname\"";
                  $sql[] = "CREATE GENERATOR \"$seqname\"";
                  $sql[] = "ALTER TRIGGER \"$trigname\" BEFORE INSERT OR UPDATE 
AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = 
GEN_ID(\"$seqname\", 1); END";
                }
                else
-               { $sql[] = "CREATE GENERATOR \"$seqname\"";
-                 $sql[] = "CREATE TRIGGER \"$trigname\" FOR $tabname BEFORE 
INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) 
THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END";
+               { $sql[] = "CREATE GENERATOR $seqname";
+                 $sql[] = "CREATE TRIGGER $trigname FOR $tabname BEFORE INSERT 
OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN 
NEW.$seqField = GEN_ID($seqname, 1); END";
                }
                
                $this->seqField = false;
@@ -148,4 +191,36 @@
                return $sql;
        }
 
+       /**
+        * Change the definition of one column
+        *
+        * As some DBM's can't do that on there own, you need to supply the 
complete defintion of the new table,
+        * to allow, recreating the table and copying the content over to the 
new table
+        * @param string $tabname table-name
+        * @param string $flds column-name and type for the changed column
+        * @param string $tableflds='' complete defintion of the new table, eg. 
for postgres, default ''
+        * @param array/string $tableoptions='' options for the new table see 
CreateTableSQL, default ''
+        * @return array with SQL strings
+        */
+       function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
+       {
+               $tabname = $this->TableName ($tabname);
+               $sql = array();
+               list($lines,$pkey,$idxs) = $this->_GenFields($flds);
+               // genfields can return FALSE at times
+               if ($lines == null) $lines = array();
+               $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
+               foreach($lines as $v) {
+                       $sql[] = $alter . $v;
+               }
+               if (is_array($idxs)) {
+                       foreach($idxs as $idx => $idxdef) {
+                               $sql_idxs = $this->CreateIndexSql($idx, 
$tabname, $idxdef['cols'], $idxdef['opts']);
+                               $sql = array_merge($sql, $sql_idxs);
+                       }
+
+               }
+               return $sql;
+       }
+
 }

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php  2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php  2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-ibase.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-ibase.inc.php    2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-ibase.inc.php    2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-informix.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-informix.inc.php 2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-informix.inc.php 2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php    2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php    2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -269,7 +269,7 @@
        }
        
        
-       function _GetSize($ftype, $ty, $fsize, $fprec)
+       function _GetSize($ftype, $ty, $fsize, $fprec, $options=false)
        {
                switch ($ftype) {
                case 'INT':
@@ -279,7 +279,7 @@
                        return $ftype;
                }
        if ($ty == 'T') return $ftype;
-       return parent::_GetSize($ftype, $ty, $fsize, $fprec);    
+       return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options);
 
        }
 }

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-mssqlnative.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-mssqlnative.inc.php      
2017-12-25 21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-mssqlnative.inc.php      
2017-12-26 11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -94,7 +94,10 @@
                          -3 => 'X'
                        );
 
-               return $_typeConversion($t);
+               if (isset($_typeConversion[$t]))
+               return $_typeConversion[$t];
+               
+               return ADODB_DEFAULT_METATYPE;
 
        }
        
@@ -126,7 +129,6 @@
                case 'F': return 'REAL';
                case 'N': return 'NUMERIC';
                default:
-                       print "RETURN $meta";
                        return $meta;
                }
        }
@@ -353,7 +355,7 @@
        }
        
        
-       function _GetSize($ftype, $ty, $fsize, $fprec)
+       function _GetSize($ftype, $ty, $fsize, $fprec,$options=false)
        {
                switch ($ftype) {
                case 'INT':
@@ -363,7 +365,7 @@
                        return $ftype;
                }
        if ($ty == 'T') return $ftype;
-       return parent::_GetSize($ftype, $ty, $fsize, $fprec);    
+       return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options);
 
        }
 }

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php    2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php    2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -26,6 +26,7 @@
        
        function MetaType($t,$len=-1,$fieldobj=false)
        {
+               
                if (is_object($t)) {
                        $fieldobj = $t;
                        $t = $fieldobj->type;
@@ -74,7 +75,7 @@
                case 'SMALLINT': return $is_serial ? 'R' : 'I2';
                case 'MEDIUMINT': return $is_serial ? 'R' : 'I4';
                case 'BIGINT':  return $is_serial ? 'R' : 'I8';
-               default: return 'N';
+               default: return ADODB_DEFAULT_METATYPE;
                }
        }
 

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-oci8.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-oci8.inc.php     2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-oci8.inc.php     2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -69,7 +69,7 @@
                        return 'I';
                        
                default:
-                       return 'N';
+                       return ADODB_DEFAULT_METATYPE;
                }
        }
        

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php 2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php 2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -85,7 +85,7 @@
                                return 'F';
                                
                         default:
-                               return 'N';
+                               return ADODB_DEFAULT_METATYPE;
                }
        }
        
@@ -472,7 +472,7 @@
                return $sql;
        }
        
-       function _GetSize($ftype, $ty, $fsize, $fprec)
+       function _GetSize($ftype, $ty, $fsize, $fprec, $options=false)
        {
                if (strlen($fsize) && $ty != 'X' && $ty != 'B' && $ty  != 'I' 
&& strpos($ftype,'(') === false) {
                        $ftype .= "(".$fsize;
@@ -479,6 +479,24 @@
                        if (strlen($fprec)) $ftype .= ",".$fprec;
                        $ftype .= ')';
                }
+               
+               /*
+               * Handle additional options
+               */
+               if (is_array($options))
+               {
+                       foreach($options as $type=>$value)
+                       {
+                               switch ($type)
+                               {
+                                       case 'ENUM':
+                                       $ftype .= '(' . $value . ')';
+                                       break;
+                                       
+                                       default:
+                               }
+                       }
+               }
                return $ftype;
        }
 }

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php    2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-sapdb.inc.php    2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -71,7 +71,7 @@
                        'FLOAT'         => 'F',
                        'FIXED'         => 'N',
                );
-               $type = isset($maxdb_type2adodb[$t]) ? $maxdb_type2adodb[$t] : 
'C';
+               $type = isset($maxdb_type2adodb[$t]) ? $maxdb_type2adodb[$t] : 
ADODB_DEFAULT_METATYPE;
 
                // convert integer-types simulated with fixed back to integer
                if ($t == 'FIXED' && !$fieldobj->scale && ($len == 20 || $len 
== 3)) {

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-sqlite.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-sqlite.inc.php   2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-sqlite.inc.php   2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -58,7 +58,7 @@
        }
        
        // return string must begin with space
-       function 
_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
+       function 
_CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
        {       
                $suffix = '';
                if ($funsigned) $suffix .= ' UNSIGNED';

Modified: trunk/phpgwapi/inc/adodb/datadict/datadict-sybase.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/datadict/datadict-sybase.inc.php   2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/datadict/datadict-sybase.inc.php   2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 

Modified: trunk/phpgwapi/inc/adodb/docs/changelog.md
===================================================================
--- trunk/phpgwapi/inc/adodb/docs/changelog.md  2017-12-25 21:03:52 UTC (rev 
17469)
+++ trunk/phpgwapi/inc/adodb/docs/changelog.md  2017-12-26 11:22:55 UTC (rev 
17470)
@@ -5,6 +5,50 @@
 [v3.x](changelog_v3.x.md),
 [v2.x](changelog_v2.x.md).
 
+## 5.21.0 - ??-???-2016
+
+- adodb: Remove useless constructors. #171
+- adodb: Define default constructor in ADOConnection base class. #172
+- adodb: Reimplement base methods charMax() and textMax(). #183
+- adodb: fix potential SQL injection vector in SelectLimit(). #190
+- adodb: addColumnSQL datadict function now supports ENUM data types. See #26
+- adodb: introduce user-defined default Metatype. #165
+- adodb: AutoExecute validates empty fields array. #154
+- adodb: fix getAssoc(). #189, #198, #204
+- adodb: Improve array identification in ADOrecordset::getAssoc(). #101
+- adodb: MetaColumns() consistently returns Actual Type by default in all 
drivers. #184, #133
+- adodb: Add new value defaulting mode for getInsertSQL(). #214
+- adodb: Added portable substring method. #219
+- adodb: New helper methods: day(), month(), year(). #225
+- adodb: Remove references to obsolete ADOdb Extension. #270
+- adodb: add Occitan translation. #285
+- adodb-time: Fix 'Q' (quarter of year) format in adodb_date(). #222
+- adodb-time: Add 'W' (week of year) format support in adodb_date(). #223
+- firebird: updated driver, thanks to Lester Caine. #201
+- mssql: Add charMax() and textMax() methods. #220
+- mssqlnative: Query not returning id. #185
+- mssqlnative: support SQL Server 2014 databases. #186
+- mssqlnative: add support for 'l' (day of week) format in sqlDate(). #232
+- mysql: setConnectionParameter() now allows multiple parameters with the same 
key value. #187
+- mysqli: Deprecate $optionFlags property in favor of standard 
setConnectionParameter() method. #188
+- mysqli: Insert_ID() did not return correct value after executing stored 
procedure. #166
+- mysqli: method failed if $associative set true. #181
+- mysqli: return fields as ADOFieldObject objects. #175
+- odbc/mssql: fix null strings concatenation issue with SQL server 2012. #148
+- odbc: MetaColumns() can optionally be set to return MetaType for backwards 
compatibility. #184
+- pdo: allow loading of subclassed recordset. #245
+- pdo: add setConnectionParameter support. #247
+- pdo: fix PHP notice. #248
+- pdo: ADORecordSet class loading. #250
+- pdo/sqlsrv: fix fetchField() method. #251, #234
+- pgsql: add CIDR data type to MetaType(). #281
+- sqlite: _createSuffix is now compatible with parent. #178
+- sqlite: metaIndexes could not locate indexes on uppercase table name. #176
+- sqlite: Fix Metataypes mapping. #177
+- sqlite: driver did not support metaForeignKeys. #179
+- session: add 'httponly' flag to cookie. #190
+- xml: support table 'opt' attribute with mysqli. #267
+
 ## 5.20.9 - 21-Dec-2016
 
 - mssql: fix syntax error in version matching regex #305

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-access.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-access.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-access.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -15,9 +15,10 @@
 if (!defined('_ADODB_ODBC_LAYER')) {
        if (!defined('ADODB_DIR')) die();
        
-       include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
+       include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php");
 }
- if (!defined('_ADODB_ACCESS')) {
+
+if (!defined('_ADODB_ACCESS')) {
        define('_ADODB_ACCESS',1);
 
 class  ADODB_access extends ADODB_odbc {       
@@ -31,14 +32,6 @@
        var $hasTransactions = false;
        var $upperCase = 'ucase';
        
-       function __construct()
-       {
-       global $ADODB_EXTENSION;
-       
-               $ADODB_EXTENSION = false;
-               parent::__construct();
-       }
-       
        function Time()
        {
                return time();
@@ -80,9 +73,6 @@
        
        var $databaseType = "access";           
        
-       function __construct($id,$mode=false)
-       {
-               return parent::__construct($id,$mode);
-       }
-}// class
+} // class
+
 } 

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-ado.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-ado.inc.php  2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-ado.inc.php  2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -225,7 +225,7 @@
 
       // Map by 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmthcreateparam.asp
       // Check issue http://bugs.php.net/bug.php?id=40664 !!!
-                       while(list(, $val) = each($inputarr)) {
+                       foreach ($inputarr as $val) {
                                $type = gettype($val);
                                $len=strlen($val);
                                if ($type == 'boolean')
@@ -350,7 +350,7 @@
                        $mode = $ADODB_FETCH_MODE;
                }
                $this->fetchMode = $mode;
-               return parent::__construct($id,$mode);
+               return parent::__construct($id);
        }
 
 
@@ -538,7 +538,7 @@
                case 19://adUnsignedInt = 19,
                case 20://adUnsignedBigInt      = 21,
                        return 'I';
-               default: return 'N';
+               default: return ADODB_DEFAULT_METATYPE;
                }
        }
        

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-ado5.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-ado5.inc.php 2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-ado5.inc.php 2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -248,7 +248,7 @@
                        $oCmd->CommandText = $sql;
                        $oCmd->CommandType = 1;
 
-                       while(list(, $val) = each($inputarr)) {
+                       foreach ($inputarr as $val) {
                                $type = gettype($val);
                                $len=strlen($val);
                                if ($type == 'boolean')
@@ -384,7 +384,7 @@
                        $mode = $ADODB_FETCH_MODE;
                }
                $this->fetchMode = $mode;
-               return parent::__construct($id,$mode);
+               return parent::__construct($id);
        }
 
 
@@ -579,7 +579,7 @@
                case 19://adUnsignedInt = 19,
                case 20://adUnsignedBigInt      = 21,
                        return 'I';
-               default: return 'N';
+               default: return ADODB_DEFAULT_METATYPE;
                }
        }
        

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-ado_access.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-ado_access.inc.php   2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-ado_access.inc.php   2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
 Released under both BSD license and Lesser GPL library license. 
@@ -17,8 +17,8 @@
 if (!defined('ADODB_DIR')) die();
 
 if (!defined('_ADODB_ADO_LAYER')) {
-       if (PHP_VERSION >= 5) include(ADODB_DIR."/drivers/adodb-ado5.inc.php");
-       else include(ADODB_DIR."/drivers/adodb-ado.inc.php");
+       if (PHP_VERSION >= 5) 
include_once(ADODB_DIR."/drivers/adodb-ado5.inc.php");
+       else include_once(ADODB_DIR."/drivers/adodb-ado.inc.php");
 }
 
 class  ADODB_ado_access extends ADODB_ado {    
@@ -43,8 +43,4 @@
        
        var $databaseType = "ado_access";               
        
-       function __construct($id,$mode=false)
-       {
-               return parent::__construct($id,$mode);
-       }
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-ado_mssql.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-ado_mssql.inc.php    2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-ado_mssql.inc.php    2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -21,8 +21,8 @@
 if (!defined('ADODB_DIR')) die();
 
 if (!defined('_ADODB_ADO_LAYER')) {
-       if (PHP_VERSION >= 5) include(ADODB_DIR."/drivers/adodb-ado5.inc.php");
-       else include(ADODB_DIR."/drivers/adodb-ado.inc.php");
+       if (PHP_VERSION >= 5) 
include_once(ADODB_DIR."/drivers/adodb-ado5.inc.php");
+       else include_once(ADODB_DIR."/drivers/adodb-ado.inc.php");
 }
 
 
@@ -137,14 +137,10 @@
                //return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) 
AS 'Char'");
        }
        
-       } // end class 
+} // end class
        
-       class  ADORecordSet_ado_mssql extends ADORecordSet_ado {        
+class ADORecordSet_ado_mssql extends ADORecordSet_ado {
        
        var $databaseType = 'ado_mssql';
        
-       function __construct($id,$mode=false)
-       {
-               return parent::__construct($id,$mode);
-       }
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-borland_ibase.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-borland_ibase.inc.php        
2017-12-25 21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-borland_ibase.inc.php        
2017-12-26 11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -80,8 +80,4 @@
        
        var $databaseType = "borland_ibase";            
        
-       function __construct($id,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-csv.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-csv.inc.php  2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-csv.inc.php  2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -38,10 +38,6 @@
        var $hasTransactions = false;
        var $_errorNo = false;
        
-       function __construct()
-       {               
-       }
-       
        function _insertid()
        {
                        return $this->_insertid;
@@ -193,10 +189,6 @@
 } // class
 
 class ADORecordset_csv extends ADORecordset {
-       function __construct($id,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
        
        function _close()
        {

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-db2.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-db2.inc.php  2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-db2.inc.php  2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /**
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
 

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-db2oci.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-db2oci.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-db2oci.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -15,49 +15,19 @@
 
 // security - hide paths
 if (!defined('ADODB_DIR')) die();
-include(ADODB_DIR."/drivers/adodb-db2.inc.php");
+include_once(ADODB_DIR."/drivers/adodb-db2.inc.php");
 
 
 if (!defined('ADODB_DB2OCI')){
 define('ADODB_DB2OCI',1);
 
-/*
-// regex code for smart remapping of :0, :1 bind vars to ? ?
-function _colontrack($p)
-{
-global $_COLONARR,$_COLONSZ;
-       $v = (integer) substr($p,1);
-       if ($v > $_COLONSZ) return $p;
-       $_COLONARR[] = $v;
-       return '?';
-}
-
-// smart remapping of :0, :1 bind vars to ? ?
-function _colonscope($sql,$arr)
-{
-global $_COLONARR,$_COLONSZ;
-
-       $_COLONARR = array();
-       $_COLONSZ = sizeof($arr);
-       
-       $sql2 = preg_replace("/(:[0-9]+)/e","_colontrack('\\1')",$sql);
-       
-       if (empty($_COLONARR)) return array($sql,$arr);
-       
-       foreach($_COLONARR as $k => $v) {
-               $arr2[] = $arr[$v]; 
-       }
-       
-       return array($sql2,$arr2);
-}
-*/
-
-/*
-       Smart remapping of :0, :1 bind vars to ? ?
-       
-       Handles colons in comments -- and / * * / and in quoted strings.
-*/
-
+/**
+ * Smart remapping of :0, :1 bind vars to ? ?
+ * Handles colons in comments -- and / * * / and in quoted strings.
+ * @param string $sql SQL statement
+ * @param array  $arr parameters
+ * @return array
+ */
 function _colonparser($sql,$arr)
 {
        $lensql = strlen($sql);
@@ -217,10 +187,6 @@
        
        var $databaseType = "db2oci";           
        
-       function __construct($id,$mode=false)
-       {
-               return parent::__construct($id,$mode);
-       }
 }
 
 } //define

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-db2ora.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-db2ora.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-db2ora.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -15,7 +15,7 @@
 
 // security - hide paths
 if (!defined('ADODB_DIR')) die();
-include(ADODB_DIR."/drivers/adodb-db2.inc.php");
+include_once(ADODB_DIR."/drivers/adodb-db2.inc.php");
 
 
 if (!defined('ADODB_DB2OCI')){
@@ -77,10 +77,6 @@
        
        var $databaseType = "db2oci";           
        
-       function __construct($id,$mode=false)
-       {
-               return parent::__construct($id,$mode);
-       }
 }
 
 } //define

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-fbsql.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-fbsql.inc.php        2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-fbsql.inc.php        2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
- @version   v5.20.9  21-Dec-2016
+ @version   v5.21.0-dev  ??-???-2016
  @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  Released under both BSD license and Lesser GPL library license. 
@@ -25,10 +25,6 @@
        var $fmtTimeStamp = "'Y-m-d H:i:s'";
        var $hasLimit = false;
        
-       function __construct()
-       {                       
-       }
-       
        function _insertid()
        {
                        return fbsql_insert_id($this->_connectionID);
@@ -259,7 +255,7 @@
                        if (!empty($fieldobj->primary_key)) return 'R';
                        else return 'I';
                
-               default: return 'N';
+               default: return ADODB_DEFAULT_METATYPE;
                }
        }
 

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-firebird.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-firebird.inc.php     2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-firebird.inc.php     2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -10,18 +10,114 @@
   
   Latest version is available at http://adodb.sourceforge.net
 
+  firebird data driver. Requires firebird client. Works on Windows and Unix.
+
 */
 
 // security - hide paths
 if (!defined('ADODB_DIR')) die();
 
-include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
-
-class ADODB_firebird extends ADODB_ibase {
+class ADODB_firebird extends ADOConnection {
        var $databaseType = "firebird"; 
+       var $dataProvider = "firebird";
+       var $replaceQuote = "''"; // string to use to replace quotes
+       var $fbird_datefmt = '%Y-%m-%d'; // For hours,mins,secs change to 
'%Y-%m-%d %H:%M:%S';
+       var $fmtDate = "'Y-m-d'";
+       var $fbird_timestampfmt = "%Y-%m-%d %H:%M:%S";
+       var $fbird_timefmt = "%H:%M:%S";
+       var $fmtTimeStamp = "'Y-m-d, H:i:s'";
+       var $concat_operator='||';
+       var $_transactionID;
+       var $metaTablesSQL = "select lower(rdb\$relation_name) from 
rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
+       //OPN STUFF start
+       var $metaColumnsSQL = "select lower(a.rdb\$field_name), 
a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, 
b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, 
b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where 
a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order 
by a.rdb\$field_position asc";
+       //OPN STUFF end
+       var $ibasetrans;
+       var $hasGenID = true;
+       var $_bindInputArray = true;
+       var $buffers = 0;
        var $dialect = 3;
-       
+       var $sysDate = "cast('TODAY' as timestamp)";
        var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
+       var $ansiOuter = true;
+       var $hasAffectedRows = true;
+       var $poorAffectedRows = false;
+       var $blobEncodeType = 'C';
+       var $role = false;
+       var $nameQuote = '';            /// string to use to quote identifiers 
and names
+
+       function __construct()
+       {
+       // Ignore IBASE_DEFAULT we want a more practical transaction!
+       //      if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
+       //      else
+               $this->ibasetrans = IBASE_WAIT | IBASE_REC_VERSION | 
IBASE_COMMITTED;
+       }
+
+
+       // returns true or false
+       function _connect($argHostname, $argUsername, $argPassword, 
$argDatabasename,$persist=false)
+       {
+               if (!function_exists('fbird_pconnect')) return null;
+               if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
+               $fn = ($persist) ? 'fbird_pconnect':'fbird_connect';
+               if ($this->role)
+                       $this->_connectionID = 
$fn($argHostname,$argUsername,$argPassword,
+                                       
$this->charSet,$this->buffers,$this->dialect,$this->role);
+               else
+                       $this->_connectionID = 
$fn($argHostname,$argUsername,$argPassword,
+                                       
$this->charSet,$this->buffers,$this->dialect);
+
+               if ($this->dialect != 1) { // 
http://www.ibphoenix.com/ibp_60_del_id_ds.html
+                       $this->replaceQuote = "''";
+               }
+               if ($this->_connectionID === false) {
+                       $this->_handleerror();
+                       return false;
+               }
+
+               // PHP5 change.
+               if (function_exists('fbird_timefmt')) {
+                       fbird_timefmt($this->fbird_datefmt,fbird_DATE );
+                       if ($this->dialect == 1) {
+                               
fbird_timefmt($this->fbird_datefmt,fbird_TIMESTAMP );
+                       } else {
+                               
fbird_timefmt($this->fbird_timestampfmt,fbird_TIMESTAMP );
+                       }
+                       fbird_timefmt($this->fbird_timefmt,fbird_TIME );
+
+               } else {
+                       ini_set("ibase.timestampformat", 
$this->fbird_timestampfmt);
+                       ini_set("ibase.dateformat", $this->fbird_datefmt);
+                       ini_set("ibase.timeformat", $this->fbird_timefmt);
+               }
+               return true;
+       }
+
+       // returns true or false
+       function _pconnect($argHostname, $argUsername, $argPassword, 
$argDatabasename)
+       {
+               return $this->_connect($argHostname, $argUsername, 
$argPassword, $argDatabasename,true);
+       }
+
+
+       function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
+       {
+               if ($internalKey) {
+                       return array('RDB$DB_KEY');
+               }
+
+               $table = strtoupper($table);
+
+               $sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
+       FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON 
I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
+       WHERE I.RDB$RELATION_NAME=\''.$table.'\' and I.RDB$INDEX_NAME like 
\'RDB$PRIMARY%\'
+       ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
+
+               $a = $this->GetCol($sql,false,true);
+               if ($a && sizeof($a)>0) return $a;
+               return false;
+       }
        
        function ServerInfo()
        {
@@ -38,10 +134,621 @@
                return $arr;
        }
        
+       function BeginTrans()
+       {
+               if ($this->transOff) return true;
+               $this->transCnt += 1;
+               $this->autoCommit = false;
+               $this->_transactionID = fbird_trans( $this->ibasetrans, 
$this->_connectionID );
+               return $this->_transactionID;
+       }
+
+       function CommitTrans($ok=true)
+       {
+               if (!$ok) {
+                       return $this->RollbackTrans();
+               }
+               if ($this->transOff) {
+                       return true;
+               }
+               if ($this->transCnt) {
+                       $this->transCnt -= 1;
+               }
+               $ret = false;
+               $this->autoCommit = true;
+               if ($this->_transactionID) {
+                       //print ' commit ';
+                       $ret = fbird_commit($this->_transactionID);
+               }
+               $this->_transactionID = false;
+               return $ret;
+       }
+
+       function _affectedrows()
+       {
+                       return fbird_affected_rows( $this->_transactionID ? 
$this->_transactionID : $this->_connectionID );
+       }
+
+       // there are some compat problems with ADODB_COUNTRECS=false and 
$this->_logsql currently.
+       // it appears that ibase extension cannot support multiple concurrent 
queryid's
+       function _Execute($sql,$inputarr=false) {
+       global $ADODB_COUNTRECS;
+
+               if ($this->_logsql) {
+                       $savecrecs = $ADODB_COUNTRECS;
+                       $ADODB_COUNTRECS = true; // force countrecs
+                       $ret =& ADOConnection::_Execute($sql,$inputarr);
+                       $ADODB_COUNTRECS = $savecrecs;
+               } else {
+                       $ret = ADOConnection::_Execute($sql,$inputarr);
+               }
+               return $ret;
+       }
+
+       function RollbackTrans()
+       {
+               if ($this->transOff) return true;
+               if ($this->transCnt) $this->transCnt -= 1;
+               $ret = false;
+               $this->autoCommit = true;
+               if ($this->_transactionID) {
+                       $ret = fbird_rollback($this->_transactionID);
+               }
+               $this->_transactionID = false;
+
+               return $ret;
+       }
+
+       function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+       {
+               // save old fetch mode
+               global $ADODB_FETCH_MODE;
+               $false = false;
+               $save = $ADODB_FETCH_MODE;
+               $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+               if ($this->fetchMode !== FALSE) {
+                               $savem = $this->SetFetchMode(FALSE);
+               }
+               $table = strtoupper($table);
+               $sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = 
'".$table."'";
+               if (!$primary) {
+                       $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
+               } else {
+                       $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
+               }
+               // get index details
+               $rs = $this->Execute($sql);
+               if (!is_object($rs)) {
+                       // restore fetchmode
+                       if (isset($savem)) {
+                               $this->SetFetchMode($savem);
+                       }
+                       $ADODB_FETCH_MODE = $save;
+                       return $false;
+               }
+
+               $indexes = array();
+               while ($row = $rs->FetchRow()) {
+                       $index = $row[0];
+                       if (!isset($indexes[$index])) {
+                               if (is_null($row[3])) {
+                                       $row[3] = 0;
+                               }
+                               $indexes[$index] = array(
+                                       'unique' => ($row[3] == 1),
+                                       'columns' => array()
+                               );
+                       }
+                       $sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE 
RDB\$INDEX_NAME = '".$index."' ORDER BY RDB\$FIELD_POSITION ASC";
+                       $rs1 = $this->Execute($sql);
+                       while ($row1 = $rs1->FetchRow()) {
+                               $indexes[$index]['columns'][$row1[2]] = 
$row1[1];
+                       }
+               }
+               // restore fetchmode
+               if (isset($savem)) {
+                       $this->SetFetchMode($savem);
+               }
+               $ADODB_FETCH_MODE = $save;
+
+               return $indexes;
+       }
+
+
+       // See http://community.borland.com/article/0,1410,25844,00.html
+       function RowLock($tables,$where,$col=false)
+       {
+               if ($this->autoCommit) {
+                       $this->BeginTrans();
+               }
+               $this->Execute("UPDATE $table SET $col=$col WHERE $where "); // 
is this correct - jlim?
+               return 1;
+       }
+
+
+       function CreateSequence($seqname = 'adodbseq', $startID = 1)
+       {
+               $ok = $this->Execute(("CREATE GENERATOR $seqname" ));
+               if (!$ok) return false;
+               return $this->Execute("SET GENERATOR $seqname TO 
".($startID-1));
+       }
+
+       function DropSequence($seqname = 'adodbseq')
+       {
+               $seqname = strtoupper($seqname);
+               return $this->Execute("DROP GENERATOR $seqname");
+       }
+
+       function GenID($seqname='adodbseq',$startID=1)
+       {
+               $getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
+               $rs = @$this->Execute($getnext);
+               if (!$rs) {
+                       $this->Execute(("CREATE GENERATOR $seqname" ));
+                       $this->Execute("SET GENERATOR $seqname TO 
".($startID-1).';');
+                       $rs = $this->Execute($getnext);
+               }
+               if ($rs && !$rs->EOF) {
+                       $this->genID = (integer) reset($rs->fields);
+               }
+               else {
+                       $this->genID = 0; // false
+               }
+
+               if ($rs) {
+                       $rs->Close();
+               }
+
+               return $this->genID;
+       }
+
+       function SelectDB($dbName)
+       {
+               return false;
+       }
+
+       function _handleerror()
+       {
+               $this->_errorMsg = fbird_errmsg();
+       }
+
+       function ErrorNo()
+       {
+               if (preg_match('/error code = ([\-0-9]*)/i', 
$this->_errorMsg,$arr)) return (integer) $arr[1];
+               else return 0;
+       }
+
+       function ErrorMsg()
+       {
+                       return $this->_errorMsg;
+       }
+
+       function Prepare($sql)
+       {
+               $stmt = fbird_prepare($this->_connectionID,$sql);
+               if (!$stmt) return false;
+               return array($sql,$stmt);
+       }
+
+          // returns query ID if successful, otherwise false
+          // there have been reports of problems with nested queries - the 
code is probably not re-entrant?
+       function _query($sql,$iarr=false)
+       {
+               if ( !$this->isConnected() ) return false;
+               if (!$this->autoCommit && $this->_transactionID) {
+                       $conn = $this->_transactionID;
+                       $docommit = false;
+               } else {
+                       $conn = $this->_connectionID;
+                       $docommit = true;
+               }
+               if (is_array($sql)) {
+                       $fn = 'fbird_execute';
+                       $sql = $sql[1];
+                       if (is_array($iarr)) {
+                               if  (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
+                                       if ( !isset($iarr[0]) ) $iarr[0] = ''; 
// PHP5 compat hack
+                                       $fnarr = array_merge( array($sql) , 
$iarr);
+                                       $ret = call_user_func_array($fn,$fnarr);
+                               } else {
+                                       switch(sizeof($iarr)) {
+                                       case 1: $ret = $fn($sql,$iarr[0]); 
break;
+                                       case 2: $ret = 
$fn($sql,$iarr[0],$iarr[1]); break;
+                                       case 3: $ret = 
$fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;
+                                       case 4: $ret = 
$fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
+                                       case 5: $ret = 
$fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
+                                       case 6: $ret = 
$fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
+                                       case 7: $ret = 
$fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
+                                       default: ADOConnection::outp( "Too many 
parameters to ibase query $sql");
+                                       case 8: $ret = 
$fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]);
 break;
+                                       }
+                               }
+                       } else $ret = $fn($sql);
+               } else {
+                       $fn = 'fbird_query';
+                       if (is_array($iarr)) {
+                               if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
+                                       if (sizeof($iarr) == 0) $iarr[0] = ''; 
// PHP5 compat hack
+                                       $fnarr = array_merge( array($conn,$sql) 
, $iarr);
+                                       $ret = call_user_func_array($fn,$fnarr);
+                               } else {
+                                       switch(sizeof($iarr)) {
+                                       case 1: $ret = 
$fn($conn,$sql,$iarr[0]); break;
+                                       case 2: $ret = 
$fn($conn,$sql,$iarr[0],$iarr[1]); break;
+                                       case 3: $ret = 
$fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;
+                                       case 4: $ret = 
$fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
+                                       case 5: $ret = 
$fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
+                                       case 6: $ret = 
$fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
+                                       case 7: $ret = 
$fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); 
break;
+                                       default: ADOConnection::outp( "Too many 
parameters to ibase query $sql");
+                                       case 8: $ret = 
$fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]);
 break;
+                                       }
+                               }
+                       } else $ret = $fn($conn,$sql);
+               }
+               if ($docommit && $ret === true) {
+                       fbird_commit($this->_connectionID);
+               }
+
+               $this->_handleerror();
+               return $ret;
+       }
+
+       // returns true or false
+       function _close()
+       {
+               if (!$this->autoCommit) {
+                       @fbird_rollback($this->_connectionID);
+               }
+               return @fbird_close($this->_connectionID);
+       }
+
+       //OPN STUFF start
+       function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, 
$fprecision, $dialect3)
+       {
+               $fscale = abs($fscale);
+               $fld->max_length = $flen;
+               $fld->scale = null;
+               switch($ftype){
+                       case 7:
+                       case 8:
+                               if ($dialect3) {
+                                       switch($fsubtype){
+                                               case 0:
+                                                       $fld->type = ($ftype == 
7 ? 'smallint' : 'integer');
+                                                       break;
+                                               case 1:
+                                                       $fld->type = 'numeric';
+                                                       $fld->max_length = 
$fprecision;
+                                                       $fld->scale = $fscale;
+                                                       break;
+                                               case 2:
+                                                       $fld->type = 'decimal';
+                                                       $fld->max_length = 
$fprecision;
+                                                       $fld->scale = $fscale;
+                                                       break;
+                                       } // switch
+                               } else {
+                                       if ($fscale !=0) {
+                                               $fld->type = 'decimal';
+                                               $fld->scale = $fscale;
+                                               $fld->max_length = ($ftype == 7 
? 4 : 9);
+                                       } else {
+                                               $fld->type = ($ftype == 7 ? 
'smallint' : 'integer');
+                                       }
+                               }
+                               break;
+                       case 16:
+                               if ($dialect3) {
+                                       switch($fsubtype){
+                                               case 0:
+                                                       $fld->type = 'decimal';
+                                                       $fld->max_length = 18;
+                                                       $fld->scale = 0;
+                                                       break;
+                                               case 1:
+                                                       $fld->type = 'numeric';
+                                                       $fld->max_length = 
$fprecision;
+                                                       $fld->scale = $fscale;
+                                                       break;
+                                               case 2:
+                                                       $fld->type = 'decimal';
+                                                       $fld->max_length = 
$fprecision;
+                                                       $fld->scale = $fscale;
+                                                       break;
+                                       } // switch
+                               }
+                               break;
+                       case 10:
+                               $fld->type = 'float';
+                               break;
+                       case 14:
+                               $fld->type = 'char';
+                               break;
+                       case 27:
+                               if ($fscale !=0) {
+                                       $fld->type = 'decimal';
+                                       $fld->max_length = 15;
+                                       $fld->scale = 5;
+                               } else {
+                                       $fld->type = 'double';
+                               }
+                               break;
+                       case 35:
+                               if ($dialect3) {
+                                       $fld->type = 'timestamp';
+                               } else {
+                                       $fld->type = 'date';
+                               }
+                               break;
+                       case 12:
+                               $fld->type = 'date';
+                               break;
+                       case 13:
+                               $fld->type = 'time';
+                               break;
+                       case 37:
+                               $fld->type = 'varchar';
+                               break;
+                       case 40:
+                               $fld->type = 'cstring';
+                               break;
+                       case 261:
+                               $fld->type = 'blob';
+                               $fld->max_length = -1;
+                               break;
+               } // switch
+       }
+       //OPN STUFF end
+
+       // returns array of ADOFieldObjects for current table
+       function MetaColumns($table, $normalize=true)
+       {
+       global $ADODB_FETCH_MODE;
+
+               $save = $ADODB_FETCH_MODE;
+               $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+
+               $rs = 
$this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
+
+               $ADODB_FETCH_MODE = $save;
+               $false = false;
+               if ($rs === false) {
+                       return $false;
+               }
+
+               $retarr = array();
+               //OPN STUFF start
+               $dialect3 = ($this->dialect==3 ? true : false);
+               //OPN STUFF end
+               while (!$rs->EOF) { //print_r($rs->fields);
+                       $fld = new ADOFieldObject();
+                       $fld->name = trim($rs->fields[0]);
+                       //OPN STUFF start
+                       $this->_ConvertFieldType($fld, $rs->fields[7], 
$rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
+                       if (isset($rs->fields[1]) && $rs->fields[1]) {
+                               $fld->not_null = true;
+                       }
+                       if (isset($rs->fields[2])) {
+
+                               $fld->has_default = true;
+                               $d = substr($rs->fields[2],strlen('default '));
+                               switch ($fld->type)
+                               {
+                               case 'smallint':
+                               case 'integer': $fld->default_value = (int) $d; 
break;
+                               case 'char':
+                               case 'blob':
+                               case 'text':
+                               case 'varchar': $fld->default_value = (string) 
substr($d,1,strlen($d)-2); break;
+                               case 'double':
+                               case 'float': $fld->default_value = (float) $d; 
break;
+                               default: $fld->default_value = $d; break;
+                               }
+               //      case 35:$tt = 'TIMESTAMP'; break;
+                       }
+                       if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
+                               $fld->sub_type = $rs->fields[5];
+                       } else {
+                               $fld->sub_type = null;
+                       }
+                       //OPN STUFF end
+                       if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = 
$fld;
+                       else $retarr[strtoupper($fld->name)] = $fld;
+
+                       $rs->MoveNext();
+               }
+               $rs->Close();
+               if ( empty($retarr)) return $false;
+               else return $retarr;
+       }
+
+       function BlobEncode( $blob )
+       {
+               $blobid = fbird_blob_create( $this->_connectionID);
+               fbird_blob_add( $blobid, $blob );
+               return fbird_blob_close( $blobid );
+       }
+
+       // since we auto-decode all blob's since 2.42,
+       // BlobDecode should not do any transforms
+       function BlobDecode($blob)
+       {
+               return $blob;
+       }
+
+       // old blobdecode function
+       // still used to auto-decode all blob's
+       function _BlobDecode_old( $blob )
+       {
+               $blobid = fbird_blob_open($this->_connectionID, $blob );
+               $realblob = fbird_blob_get( $blobid,$this->maxblobsize); // 2nd 
param is max size of blob -- Kevin Boillet <address@hidden>
+               while($string = fbird_blob_get($blobid, 8192)){
+                       $realblob .= $string;
+               }
+               fbird_blob_close( $blobid );
+
+               return( $realblob );
+       }
+
+       function _BlobDecode( $blob )
+       {
+               if  (ADODB_PHPVER >= 0x5000) {
+                       $blob_data = fbird_blob_info($this->_connectionID, 
$blob );
+                       $blobid = fbird_blob_open($this->_connectionID, $blob );
+               } else {
+                       $blob_data = fbird_blob_info( $blob );
+                       $blobid = fbird_blob_open( $blob );
+               }
+
+               if( $blob_data[0] > $this->maxblobsize ) {
+                       $realblob = fbird_blob_get($blobid, $this->maxblobsize);
+
+                       while($string = fbird_blob_get($blobid, 8192)) {
+                               $realblob .= $string;
+                       }
+               } else {
+                       $realblob = fbird_blob_get($blobid, $blob_data[0]);
+               }
+
+               fbird_blob_close( $blobid );
+               return( $realblob );
+       }
+
+       function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
+       {
+               $fd = fopen($path,'rb');
+               if ($fd === false) return false;
+               $blob_id = fbird_blob_create($this->_connectionID);
+
+               /* fill with data */
+
+               while ($val = fread($fd,32768)){
+                       fbird_blob_add($blob_id, $val);
+               }
+
+               /* close and get $blob_id_str for inserting into table */
+               $blob_id_str = fbird_blob_close($blob_id);
+
+               fclose($fd);
+               return $this->Execute("UPDATE $table SET $column=(?) WHERE 
$where",array($blob_id_str)) != false;
+       }
+
+       /*
+               Insert a null into the blob field of the table first.
+               Then use UpdateBlob to store the blob.
+
+               Usage:
+
+               $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, 
null)');
+               $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
+       */
+       function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
+       {
+       $blob_id = fbird_blob_create($this->_connectionID);
+
+       // fbird_blob_add($blob_id, $val);
+
+       // replacement that solves the problem by which only the first modulus 
64K /
+       // of $val are stored at the blob field 
////////////////////////////////////
+       // Thx Abel Berenstein  aberenstein#afip.gov.ar
+       $len = strlen($val);
+       $chunk_size = 32768;
+       $tail_size = $len % $chunk_size;
+       $n_chunks = ($len - $tail_size) / $chunk_size;
+
+       for ($n = 0; $n < $n_chunks; $n++) {
+               $start = $n * $chunk_size;
+               $data = substr($val, $start, $chunk_size);
+               fbird_blob_add($blob_id, $data);
+       }
+
+       if ($tail_size) {
+               $start = $n_chunks * $chunk_size;
+               $data = substr($val, $start, $tail_size);
+               fbird_blob_add($blob_id, $data);
+       }
+       // end replacement 
/////////////////////////////////////////////////////////
+
+       $blob_id_str = fbird_blob_close($blob_id);
+
+       return $this->Execute("UPDATE $table SET $column=(?) WHERE 
$where",array($blob_id_str)) != false;
+
+       }
+
+
+       function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
+       {
+               $blob_id = fbird_blob_create($this->_connectionID);
+               fbird_blob_add($blob_id, $val);
+               $blob_id_str = fbird_blob_close($blob_id);
+               return $this->Execute("UPDATE $table SET $column=(?) WHERE 
$where",array($blob_id_str)) != false;
+       }
+
+       // Format date column in sql string given an input format that 
understands Y M D
+       // Only since Interbase 6.0 - uses EXTRACT
+       // problem - does not zero-fill the day and month yet
+       function SQLDate($fmt, $col=false)
+       {
+               if (!$col) $col = $this->sysDate;
+               $s = '';
+
+               $len = strlen($fmt);
+               for ($i=0; $i < $len; $i++) {
+                       if ($s) $s .= '||';
+                       $ch = $fmt[$i];
+                       switch($ch) {
+                       case 'Y':
+                       case 'y':
+                               $s .= "extract(year from $col)";
+                               break;
+                       case 'M':
+                       case 'm':
+                               $s .= "extract(month from $col)";
+                               break;
+                       case 'W':
+                       case 'w':
+                               // The more accurate way of doing this is with 
a stored procedure
+                               // See 
http://wiki.firebirdsql.org/wiki/index.php?page=DATE+Handling+Functions for 
details
+                               $s .= "((extract(yearday from $col) - 
extract(weekday from $col - 1) + 7) / 7)";
+                               break;
+                       case 'Q':
+                       case 'q':
+                               $s .= "cast(((extract(month from $col)+2) / 3) 
as integer)";
+                               break;
+                       case 'D':
+                       case 'd':
+                               $s .= "(extract(day from $col))";
+                               break;
+                       case 'H':
+                       case 'h':
+                               $s .= "(extract(hour from $col))";
+                               break;
+                       case 'I':
+                       case 'i':
+                               $s .= "(extract(minute from $col))";
+                               break;
+                       case 'S':
+                       case 's':
+                               $s .= "CAST((extract(second from $col)) AS 
INTEGER)";
+                               break;
+
+                       default:
+                               if ($ch == '\\') {
+                                       $i++;
+                                       $ch = substr($fmt,$i,1);
+                               }
+                               $s .= $this->qstr($ch);
+                               break;
+                       }
+               }
+               return $s;
+       }
+
        // Note that Interbase 6.5 uses this ROWS instead - don't you love 
forking wars!
        //              SELECT col1, col2 FROM table ROWS 5 -- get 5 rows 
        //              SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 
-- first 5 skip 2
-       function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
+       function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, 
$secs=0)
        {
                $nrows = (integer) $nrows;
                $offset = (integer) $offset;
@@ -58,16 +765,173 @@
                return $rs;
        }
        
+}
        
-};
- 
+/*--------------------------------------------------------------------------------------
+                Class Name: Recordset
+--------------------------------------------------------------------------------------*/
 
-class  ADORecordSet_firebird extends ADORecordSet_ibase {      
+class  ADORecordset_firebird extends ADORecordSet
+{
        
        var $databaseType = "firebird";         
+       var $bind=false;
+       var $_cacheType;
        
        function __construct($id,$mode=false)
        {
-               parent::__construct($id,$mode);
+       global $ADODB_FETCH_MODE;
+
+                       $this->fetchMode = ($mode === false) ? 
$ADODB_FETCH_MODE : $mode;
+                       parent::__construct($id);
        }
+
+       /**
+        * 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;
+                        $ibf = fbird_field_info($this->_queryID,$fieldOffset);
+
+                       $name = empty($ibf['alias']) ? $ibf['name'] : 
$ibf['alias'];
+
+                       switch (ADODB_ASSOC_CASE) {
+                               case ADODB_ASSOC_CASE_UPPER:
+                                       $fld->name = strtoupper($name);
+                                       break;
+                               case ADODB_ASSOC_CASE_LOWER:
+                                       $fld->name = strtolower($name);
+                                       break;
+                               case ADODB_ASSOC_CASE_NATIVE:
+                               default:
+                                       $fld->name = $name;
+                                       break;
+                       }
+
+                       $fld->type = $ibf['type'];
+                       $fld->max_length = $ibf['length'];
+
+                       /*       This needs to be populated from the metadata */
+                       $fld->not_null = false;
+                       $fld->has_default = false;
+                       $fld->default_value = 'null';
+                       return $fld;
+       }
+
+       function _initrs()
+       {
+               $this->_numOfRows = -1;
+               $this->_numOfFields = @fbird_num_fields($this->_queryID);
+
+               // cache types for blob decode check
+               for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
+                       $f1 = $this->FetchField($i);
+                       $this->_cacheType[] = $f1->type;
+               }
+       }
+
+       function _seek($row)
+       {
+               return false;
+       }
+
+       function _fetch()
+       {
+               $f = @fbird_fetch_row($this->_queryID);
+               if ($f === false) {
+                       $this->fields = false;
+                       return false;
+               }
+               // OPN stuff start - optimized
+               // fix missing nulls and decode blobs automatically
+
+               global $ADODB_ANSI_PADDING_OFF;
+               //$ADODB_ANSI_PADDING_OFF=1;
+               $rtrim = !empty($ADODB_ANSI_PADDING_OFF);
+
+               for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
+                       if ($this->_cacheType[$i]=="BLOB") {
+                               if (isset($f[$i])) {
+                                       $f[$i] = 
$this->connection->_BlobDecode($f[$i]);
+                               } else {
+                                       $f[$i] = null;
+                               }
+                       } else {
+                               if (!isset($f[$i])) {
+                                       $f[$i] = null;
+                               } else if ($rtrim && is_string($f[$i])) {
+                                       $f[$i] = rtrim($f[$i]);
+                               }
+                       }
+               }
+               // OPN stuff end
+
+               $this->fields = $f;
+               if ($this->fetchMode == ADODB_FETCH_ASSOC) {
+                       $this->fields = $this->GetRowAssoc();
+               } else if ($this->fetchMode == ADODB_FETCH_BOTH) {
+                       $this->fields = 
array_merge($this->fields,$this->GetRowAssoc());
+               }
+               return true;
+       }
+
+       /* Use associative array to get fields array */
+       function Fields($colname)
+       {
+               if ($this->fetchMode & ADODB_FETCH_ASSOC) return 
$this->fields[$colname];
+               if (!$this->bind) {
+                       $this->bind = array();
+                       for ($i=0; $i < $this->_numOfFields; $i++) {
+                               $o = $this->FetchField($i);
+                               $this->bind[strtoupper($o->name)] = $i;
+                       }
+               }
+
+               return $this->fields[$this->bind[strtoupper($colname)]];
+
+       }
+
+
+       function _close()
+       {
+                       return @fbird_free_result($this->_queryID);
+       }
+
+       function MetaType($t,$len=-1,$fieldobj=false)
+       {
+               if (is_object($t)) {
+                       $fieldobj = $t;
+                       $t = $fieldobj->type;
+                       $len = $fieldobj->max_length;
+               }
+               switch (strtoupper($t)) {
+               case 'CHAR':
+                       return 'C';
+
+               case 'TEXT':
+               case 'VARCHAR':
+               case 'VARYING':
+               if ($len <= $this->blobSize) return 'C';
+                       return 'X';
+               case 'BLOB':
+                       return 'B';
+
+               case 'TIMESTAMP':
+               case 'DATE': return 'D';
+               case 'TIME': return 'T';
+                               //case 'T': return 'T';
+
+                               //case 'L': return 'L';
+               case 'INT':
+               case 'SHORT':
+               case 'INTEGER': return 'I';
+               default: return ADODB_DEFAULT_METATYPE;
+               }
+       }
+
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-ibase.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-ibase.inc.php        2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-ibase.inc.php        2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -911,7 +911,7 @@
                case 'INT': 
                case 'SHORT':
                case 'INTEGER': return 'I';
-               default: return 'N';
+               default: return ADODB_DEFAULT_METATYPE;
                }
        }
 

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-informix.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-informix.inc.php     2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-informix.inc.php     2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version   v5.20.9  21-Dec-2016
+* @version   v5.21.0-dev  ??-???-2016
 * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
 * Released under both BSD license and Lesser GPL library license.
@@ -33,9 +33,4 @@
 
 class ADORecordset_informix extends ADORecordset_informix72 {
        var $databaseType = "informix";
-       
-       function __construct($id,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-informix72.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-informix72.inc.php   2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-informix72.inc.php   2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim. All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license.

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-ldap.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-ldap.inc.php 2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-ldap.inc.php 2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
    Released under both BSD license and Lesser GPL library license. 
@@ -45,10 +45,6 @@
        # error on binding, eg. "Binding: invalid credentials"
        var $_bind_errmsg = "Binding: %s";
        
-       function __construct()
-       {               
-       }
-               
        // returns true or false
        
        function _connect( $host, $username, $password, $ldapbase)
@@ -331,7 +327,7 @@
     /*
     Return whole recordset as a multi-dimensional associative array
        */
-       function GetAssoc($force_array = false, $first2cols = false) 
+       function GetAssoc($force_array = false, $first2cols = false, $fetchMode 
= -1)
        {
                $records = $this->_numOfRows;
         $results = array();

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php        2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php        2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -307,7 +307,9 @@
                        case 'A':
                                $s .= 
"substring(convert(char(19),$col,0),18,2)";
                                break;
-                               
+                       case 'l':
+                               $s .= "datename(dw,$col)";
+                               break;
                        default:
                                if ($ch == '\\') {
                                        $i++;
@@ -517,16 +519,18 @@
        function MetaDatabases() 
        { 
                if(@mssql_select_db("master")) { 
-                                $qry=$this->metaDatabasesSQL; 
-                                if(address@hidden($qry,$this->_connectionID)){ 
-                                                $tmpAr=$ar=array(); 
-                                                while(address@hidden($rs)) 
+                       $qry = $this->metaDatabasesSQL;
+                       if($rs = @mssql_query($qry,$this->_connectionID)) {
+                               $tmpAr = $ar = array();
+                               while($tmpAr = @mssql_fetch_row($rs)) {
                                                                 
$ar[]=$tmpAr[0]; 
+                               }
                                                
@mssql_select_db($this->database); 
-                                                if(sizeof($ar)) 
+                               if(sizeof($ar)) {
                                                                 return($ar); 
-                                                else 
+                               } else {
                                                                 return(false); 
+                               }
                                 } else { 
                                                 
@mssql_select_db($this->database); 
                                                 return(false); 
@@ -605,8 +609,11 @@
                if (!$id) return false;
                $arr = mssql_fetch_array($id);
                @mssql_free_result($id);
-               if (is_array($arr)) return $arr[0];
-          else return -1;
+               if (is_array($arr)) {
+                       return $arr[0];
+               } else {
+                       return -1;
+               }
        }
        
        // returns true or false, newconnect supported since php 5.1.0.
@@ -613,6 +620,7 @@
        function _connect($argHostname, $argUsername, $argPassword, 
$argDatabasename,$newconnect=false)
        {
                if (!function_exists('mssql_pconnect')) return null;
+               if (!empty($this->port)) $argHostname .= ":".$this->port;
                $this->_connectionID = 
mssql_connect($argHostname,$argUsername,$argPassword,$newconnect);
                if ($this->_connectionID === false) return false;
                if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -624,6 +632,7 @@
        function _pconnect($argHostname, $argUsername, $argPassword, 
$argDatabasename)
        {
                if (!function_exists('mssql_pconnect')) return null;
+               if (!empty($this->port)) $argHostname .= ":".$this->port;
                $this->_connectionID = 
mssql_pconnect($argHostname,$argUsername,$argPassword);
                if ($this->_connectionID === false) return false;
                
@@ -838,8 +847,12 @@
        // returns true or false
        function _close()
        { 
-               if ($this->transCnt) $this->RollbackTrans();
-               $rez = @mssql_close($this->_connectionID);
+               if ($this->transCnt) {
+                       $this->RollbackTrans();
+               }
+               if($this->_connectionID) {
+                       $rez = mssql_close($this->_connectionID);
+               }
                $this->_connectionID = false;
                return $rez;
        }
@@ -854,6 +867,32 @@
        {
                return ADORecordSet_array_mssql::UnixTimeStamp($v);
        }       
+
+       /**
+       * Returns a substring of a varchar type field
+       *
+       * The SQL server version varies because the length is mandatory, so
+       * we append a reasonable string length
+       *
+       * @param        string  $fld    The field to sub-string
+       * @param        int             $start  The start point
+       * @param        int             $length An optional length
+       *
+       * @return       The SQL text
+       */
+       function substr($fld,$start,$length=0)
+       {
+               if ($length == 0)
+                       /*
+                    * The length available to varchar is 2GB, but that makes no
+                        * sense in a substring, so I'm going to arbitrarily 
limit
+                        * the length to 1K, but you could change it if you want
+                        */
+                       $length = 1024;
+
+               $text = "SUBSTRING($fld,$start,$length)";
+               return $text;
+       }
 }
        
 
/*--------------------------------------------------------------------------------------
@@ -878,7 +917,7 @@
 
                }
                $this->fetchMode = $mode;
-               return parent::__construct($id,$mode);
+               return parent::__construct($id);
        }
        
        
@@ -1070,14 +1109,34 @@
                return ADORecordSet_array_mssql::UnixTimeStamp($v);
        }
        
+       /**
+       * Returns the maximum size of a MetaType C field. Because of the
+       * database design, SQL Server places no limits on the size of data 
inserted
+       * Although the actual limit is 2^31-1 bytes.
+       *
+       * @return int
+       */
+       function charMax()
+       {
+               return ADODB_STRINGMAX_NOLIMIT;
+       }
+
+       /**
+       * Returns the maximum size of a MetaType X field. Because of the
+       * database design, SQL Server places no limits on the size of data 
inserted
+       * Although the actual limit is 2^31-1 bytes.
+       *
+       * @return int
+       */
+       function textMax()
+       {
+               return ADODB_STRINGMAX_NOLIMIT;
+       }
+
 }
 
 
 class ADORecordSet_array_mssql extends ADORecordSet_array {
-       function __construct($id=-1,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
        
                // mssql uses a default date like Dec 30 2000 12:00AM
        static function UnixDate($v)

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mssql_n.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mssql_n.inc.php      2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mssql_n.inc.php      2017-12-26 
11:22:55 UTC (rev 17470)
@@ -242,8 +242,4 @@
 
 class ADORecordset_mssql_n extends ADORecordset_mssql {
        var $databaseType = "mssql_n";
-       function __construct($id,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlnative.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlnative.inc.php  2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlnative.inc.php  2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -124,8 +124,10 @@
        var $uniqueOrderBy = true;
        var $_bindInputArray = true;
        var $_dropSeqSQL = "drop table %s";
-       var $connectionInfo = array();
+
+       var $connectionInfo    = array('ReturnDatesAsStrings'=>true);
        var $cachedSchemaFlush = false;
+
        var $sequences = false;
        var $mssql_version = '';
        
@@ -189,11 +191,9 @@
        
        function _insertid()
        {
-       // SCOPE_IDENTITY()
-       // Returns the last IDENTITY value inserted into an IDENTITY column in 
-       // 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.
+               $rez = sqlsrv_query($this->_connectionID,$this->identitySQL);
+               sqlsrv_fetch($rez);
+               $this->lastInsertID = sqlsrv_get_field($rez, 0);
                return $this->lastInsertID;
        }
 
@@ -204,8 +204,6 @@
        }
        
        function GenID($seq='adodbseq',$start=1) {
-               if (!$this->mssql_version)
-                       $this->ServerVersion();
                switch($this->mssql_version){
                case 9:
                case 10:
@@ -219,9 +217,6 @@
 
        function CreateSequence($seq='adodbseq',$start=1)
        {
-               if (!$this->mssql_version)
-                       $this->ServerVersion();
-
                switch($this->mssql_version){
                case 9:
                case 10:
@@ -231,7 +226,6 @@
                        return $this->CreateSequence2012($seq, $start);
                        break;
                }
-
        }
 
        /**
@@ -365,7 +359,9 @@
                        case 'A':
                                $s .= 
"substring(convert(char(19),$col,0),18,2)";
                                break;
-                               
+                       case 'l':
+                               $s .= "datename(dw,$col)";
+                               break;
                        default:
                                if ($ch == '\\') {
                                        $i++;
@@ -397,6 +393,7 @@
                sqlsrv_commit($this->_connectionID);
                return true;
        }
+
        function RollbackTrans()
        {
                if ($this->transOff) return true; 
@@ -458,8 +455,6 @@
                                $this->_errorMsg .= "Error Code: ".$arrError[ 
'code']."\n";
                                $this->_errorMsg .= "Message: ".$arrError[ 
'message']."\n";
                        }
-               } else {
-                       $this->_errorMsg = "No errors found";
                }
                return $this->_errorMsg;
        }
@@ -475,22 +470,30 @@
        function _connect($argHostname, $argUsername, $argPassword, 
$argDatabasename)
        {
                if (!function_exists('sqlsrv_connect')) return null;
+
                $connectionInfo = $this->connectionInfo;
-               $connectionInfo["Database"]=$argDatabasename;
-               $connectionInfo["UID"]=$argUsername;
-               $connectionInfo["PWD"]=$argPassword;
+               $connectionInfo["Database"]     = $argDatabasename;
+               $connectionInfo["UID"]          = $argUsername;
+               $connectionInfo["PWD"]          = $argPassword;
                
-               foreach ($this->connectionParameters as $parameter=>$value)
+               /*
+               * Now merge in the passed connection parameters setting
+               */
+               foreach ($this->connectionParameters as $options)
+               {
+                       foreach($options as $parameter=>$value)
                    $connectionInfo[$parameter] = $value;
+               }
                
                if ($this->debug) ADOConnection::outp("<hr>connecting... 
hostname: $argHostname params: ".var_export($connectionInfo,true));
-               //if ($this->debug) ADOConnection::outp("<hr>_connectionID 
before: ".serialize($this->_connectionID));
-        if(!($this->_connectionID = 
sqlsrv_connect($argHostname,$connectionInfo))) { 
+               if(!($this->_connectionID = 
sqlsrv_connect($argHostname,$connectionInfo)))
+               {
                        if ($this->debug) ADOConnection::outp( 
"<hr><b>errors</b>: ".print_r( sqlsrv_errors(), true));
             return false;
         }
-               //if ($this->debug) ADOConnection::outp(" _connectionID after: 
".serialize($this->_connectionID));
-               //if ($this->debug) ADOConnection::outp("<hr>defined functions: 
<pre>".var_export(get_defined_functions(),true)."</pre>");
+
+               $this->ServerVersion();
+
                return true;    
        }
        
@@ -504,10 +507,6 @@
        function Prepare($sql)
        {
                return $sql; // prepare does not work properly with bind 
parameters as bind parameters are managed by sqlsrv_prepare!
-               
-               $stmt = sqlsrv_prepare( $this->_connectionID, $sql);
-               if (!$stmt)  return $sql;
-               return array($sql,$stmt);
        }
        
        // returns concatenated string
@@ -562,7 +561,8 @@
        {
                $this->_errorMsg = false;
                
-               if (is_array($sql)) $sql = $sql[1];
+               if (is_array($sql))
+                       $sql = $sql[1];
                
                $insert = false;
                // handle native driver flaw for retrieving the last insert ID
@@ -570,7 +570,14 @@
                        $insert = true;
                        $sql .= '; '.$this->identitySQL; // select 
scope_identity()
                }
-               if($inputarr) {
+               if($inputarr)
+               {
+                       /*
+                       * Ensure that the input array is numeric, as required by
+                       * sqlsrv_query. If param() was used to create portable 
binds
+                       * then the array might be associative
+                       */
+                       $inputarr = array_values($inputarr);
                        $rez = sqlsrv_query($this->_connectionID, $sql, 
$inputarr);
                } else {
                        $rez = sqlsrv_query($this->_connectionID,$sql);
@@ -578,15 +585,9 @@
 
                if ($this->debug) ADOConnection::outp("<hr>running query: 
".var_export($sql,true)."<hr>input array: 
".var_export($inputarr,true)."<hr>result: ".var_export($rez,true));
 
-               if(!$rez) {
+               if(!$rez)
                        $rez = false;
-               } else if ($insert) {
-                       // retrieve the last insert ID (where applicable)
-                       while ( sqlsrv_next_result($rez) ) {
-                       sqlsrv_fetch($rez);
-                       $this->lastInsertID = sqlsrv_get_field($rez, 0);
-               }
-               }
+
                return $rez;
        }
        
@@ -593,8 +594,12 @@
        // returns true or false
        function _close()
        { 
-               if ($this->transCnt) $this->RollbackTrans();
-               $rez = @sqlsrv_close($this->_connectionID);
+               if ($this->transCnt) {
+                       $this->RollbackTrans();
+               }
+               if($this->_connectionID) {
+                       $rez = sqlsrv_close($this->_connectionID);
+               }
                $this->_connectionID = false;
                return $rez;
        }
@@ -667,7 +672,7 @@
             where upper(object_name(fkeyid)) = $table
             order by constraint_name, referenced_table_name, keyno";
                
-               $constraints =& $this->GetArray($sql);
+               $constraints = $this->GetArray($sql);
                
                $ADODB_FETCH_MODE = $save;
                
@@ -749,7 +754,9 @@
        }
        function MetaColumns($table, $upper=true, $schema=false){
 
-               # start adg
+               /*
+               * A simple caching mechanism, to be replaced in ADOdb V6
+               */
                static $cached_columns = array();
                if ($this->cachedSchemaFlush)
                        $cached_columns = array();
@@ -757,10 +764,7 @@
                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) {
@@ -822,12 +826,60 @@
 
                }
                $rs->Close();
-               # start adg
                $cached_columns[$table] = $retarr;
-               # end adg
+
                return $retarr;
        }
 
+       /**
+       * Returns a substring of a varchar type field
+       *
+       * The SQL server version varies because the length is mandatory, so
+       * we append a reasonable string length
+       *
+       * @param        string  $fld    The field to sub-string
+       * @param        int             $start  The start point
+       * @param        int             $length An optional length
+       *
+       * @return       The SQL text
+       */
+       function substr($fld,$start,$length=0)
+       {
+               if ($length == 0)
+                       /*
+                    * The length available to varchar is 2GB, but that makes no
+                        * sense in a substring, so I'm going to arbitrarily 
limit
+                        * the length to 1K, but you could change it if you want
+                        */
+                       $length = 1024;
+
+               $text = "SUBSTRING($fld,$start,$length)";
+               return $text;
+       }
+
+       /**
+       * Returns the maximum size of a MetaType C field. Because of the
+       * database design, SQL Server places no limits on the size of data 
inserted
+       * Although the actual limit is 2^31-1 bytes.
+       *
+       * @return int
+       */
+       function charMax()
+       {
+               return ADODB_STRINGMAX_NOLIMIT;
+       }
+
+       /**
+       * Returns the maximum size of a MetaType X field. Because of the
+       * database design, SQL Server places no limits on the size of data 
inserted
+       * Although the actual limit is 2^31-1 bytes.
+       *
+       * @return int
+       */
+       function textMax()
+       {
+               return ADODB_STRINGMAX_NOLIMIT;
+       }
 }
        
 
/*--------------------------------------------------------------------------------------
@@ -841,6 +893,67 @@
        var $fieldOffset = 0;
        // _mths works only in non-localised system
        
+       /*
+        * Holds a cached version of the metadata
+        */
+       private $fieldObjects = false;
+
+       /*
+        * Flags if we have retrieved the metadata
+        */
+       private $fieldObjectsRetrieved = false;
+
+       /*
+       * Cross-reference the objects by name for easy access
+       */
+       private $fieldObjectsIndex = array();
+
+
+       /*
+        * Cross references the dateTime objects for faster decoding
+        */
+       private $dateTimeObjects = array();
+
+       /*
+        * flags that we have dateTimeObjects to handle
+        */
+       private $hasDateTimeObjects = false;
+
+       /*
+        * This is cross reference between how the types are stored
+        * in SQL Server and their english-language description
+        */
+       private $_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'
+                       );
+
+
+
+
        function __construct($id,$mode=false)
        {
                if ($mode === false) { 
@@ -849,29 +962,19 @@
 
                }
                $this->fetchMode = $mode;
-               return parent::__construct($id,$mode);
+               return parent::__construct($id);
        }
        
        
        function _initrs()
        {
-           global $ADODB_COUNTRECS;    
-               # KMN # if ($this->connection->debug) 
ADOConnection::outp("(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."
-               ADOConnection::outp("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;
-               # KMN # if ($this->connection->debug) 
ADOConnection::outp("(after) _numOfRows: {$this->_numOfRows} _numOfFields: 
{$this->_numOfFields}");
                /*
-                * Copy the oracle method and cache the metadata at init time
+               * Cache the metadata right now
                 */
-               if ($this->_numOfFields>0) {
-                       $this->_fieldobjs = array();
-                       $max = $this->_numOfFields;
-                       for ($i=0;$i<$max; $i++) $this->_fieldobjs[] = 
$this->_FetchField($i);
-               }
+               $this->_fetchField();
 
        }
        
@@ -903,79 +1006,74 @@
                return $this->fields[$this->bind[strtoupper($colname)]];
        }
        
-       /*      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.
-               Designed By jcortinap#jc.com.mx
+       /**
+       * 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.
+       *
+       * $param int $fieldOffset (optional default=-1 for all
+       * @return mixed an ADOFieldObject, or array of objects
        */
-       function _FetchField($fieldOffset = -1)
+       private function _fetchField($fieldOffset = -1)
        {
-               $_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
-               }
+               if ($this->fieldObjectsRetrieved){
+                       if ($this->fieldObjects) {
+                               /*
+                                * Already got the information
+                                */
+                               if ($fieldOffset == -1)
+                                       return $this->fieldObjects;
                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']]
-                                       );
+                                       return 
$this->fieldObjects[$fieldOffset];
                        }
                        else
-                       {
-                               foreach ($fa as $key => $value)
-                               {
-                                       $fb[] = array(
-                                               'name' => $value['name'],
-                                               'max_length' => $value['size'],
-                                               'column_source' => 
$value['name'],
-                                               'type' => 
$_typeConversion[$value['type']]
-                                               );
-                               }
+                               /*
+                            * No metadata available
+                                */
+                               return false;
                        }
-                       $f = (object) $fb;
+
+               $this->fieldObjectsRetrieved = true;
+               /*
+                * Retrieve all metadata in one go. This is always returned as a
+                * numeric array.
+                */
+               $fieldMetaData = sqlsrv_field_metadata($this->_queryID);
+
+               if (!$fieldMetaData)
+                       /*
+                    * Not a statement that gives us metaData
+                        */
+                       return false;
+
+               $this->_numOfFields = count($fieldMetaData);
+               foreach ($fieldMetaData as $key=>$value)
+               {
+
+                       $fld = new ADOFieldObject;
+                       /*
+                        * Caution - keys are case-sensitive, must respect
+                        * casing of values
+                        */
+
+                       $fld->name          = $value['Name'];
+                       $fld->max_length    = $value['Size'];
+                       $fld->column_source = $value['Name'];
+                       $fld->type          = 
$this->_typeConversion[$value['Type']];
+
+                       $this->fieldObjects[$key] = $fld;
+
+                       $this->fieldObjectsIndex[$fld->name] = $key;
+
                }
-               return $f;
+               if ($fieldOffset == -1)
+                       return $this->fieldObjects;
+
+               return $this->fieldObjects[$fieldOffset];
        }
        
        /*
@@ -983,12 +1081,16 @@
         * into the _fieldobjs array once, to save multiple calls to the
         * sqlsrv_field_metadata function
         *
+        * @param int $fieldOffset      (optional)
+        *
+        * @return adoFieldObject
+        *
         * @author      KM Newnham
         * @date        02/20/2013
         */
-       function FetchField($fieldOffset = -1)
+       function fetchField($fieldOffset = -1)
        {
-               return $this->_fieldobjs[$fieldOffset];
+               return $this->fieldObjects[$fieldOffset];
        }
 
        function _seek($row) 
@@ -999,76 +1101,50 @@
        // speedup
        function MoveNext() 
        {
-               //# KMN # if ($this->connection->debug) 
ADOConnection::outp("movenext()");
-               //# KMN # if ($this->connection->debug) 
ADOConnection::outp("eof (beginning): ".$this->EOF);
-               if ($this->EOF) return false;
+               if ($this->EOF)
+                       return false;
                
                $this->_currentRow++;
-               // # KMN # if ($this->connection->debug) 
ADOConnection::outp("_currentRow: ".$this->_currentRow);
                
-               if ($this->_fetch()) return true;
+               if ($this->_fetch())
+                       return true;
                $this->EOF = true;
-               //# KMN # if ($this->connection->debug) 
ADOConnection::outp("eof (end): ".$this->EOF);
                
                return false;
        }
 
-       
-       // INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
-       // 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) 
        {
-               # KMN # if ($this->connection->debug) 
ADOConnection::outp("_fetch()");
                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
-                       if ($this->fetchMode & ADODB_FETCH_NUM) {
-                               //# KMN # if ($this->connection->debug) 
ADOConnection::outp("fetch mode: both");
+                       if ($this->fetchMode & ADODB_FETCH_NUM)
                                $this->fields = 
@sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_BOTH);
-                       } else {
-                               //# KMN # if ($this->connection->debug) 
ADOConnection::outp("fetch mode: assoc");
+                       else
                                $this->fields = 
@sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_ASSOC);
-                       }
                        
-                       if (is_array($this->fields)) {
-                               if (ADODB_ASSOC_CASE == 0) {
-                                       foreach($this->fields as $k=>$v) {
-                                               $this->fields[strtolower($k)] = 
$v;
-                                       }
-                               } else if (ADODB_ASSOC_CASE == 1) {
-                                       foreach($this->fields as $k=>$v) {
-                                               $this->fields[strtoupper($k)] = 
$v;
-                                       }
+                       if (is_array($this->fields))
+                       {
+
+                               if (ADODB_ASSOC_CASE == ADODB_ASSOC_CASE_LOWER)
+                                       $this->fields = 
array_change_key_case($this->fields,CASE_LOWER);
+                               else if (ADODB_ASSOC_CASE == 
ADODB_ASSOC_CASE_UPPER)
+                                       $this->fields = 
array_change_key_case($this->fields,CASE_UPPER);
+
                                }
                        }
-               } else {
-                       //# KMN # if ($this->connection->debug) 
ADOConnection::outp("fetch mode: num");
+               else
                        $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) 
ADOConnection::outp("<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
-                                       $this->fields[$key] = 
$value->format("Y-m-d\TH:i:s\Z");
-                               }
-                       }
-               }
-        if($this->fields === null) $this->fields = false;
-               # KMN # if ($this->connection->debug) 
ADOConnection::outp("<hr>after _fetch, fields: 
<pre>".print_r($this->fields,true)." backtrace: ".adodb_backtrace(false));
+
+               if (!$this->fields)
+                       return false;
+
                return $this->fields;
        }
        
-    /* 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(is_object($this->_queryID)) {
@@ -1093,10 +1169,6 @@
 
 
 class ADORecordSet_array_mssqlnative extends ADORecordSet_array {
-       function __construct($id=-1,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
        
                // mssql uses a default date like Dec 30 2000 12:00AM
        static function UnixDate($v)

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlpo.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlpo.inc.php      2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mssqlpo.inc.php      2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /**
-* @version   v5.20.9  21-Dec-2016
+* @version   v5.21.0-dev  ??-???-2016
 * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
 * Released under both BSD license and Lesser GPL library license.
@@ -51,8 +51,4 @@
 
 class ADORecordset_mssqlpo extends ADORecordset_mssql {
        var $databaseType = "mssqlpo";
-       function __construct($id,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mysql.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mysql.inc.php        2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mysql.inc.php        2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -51,12 +51,7 @@
        var $nameQuote = '`';           /// string to use to quote identifiers 
and names
        var $compat323 = false;                 // true if compat with mysql 
3.23
        
-       function __construct()
-       {                       
-               if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
-       }
 
-
   // SetCharSet - switch the client encoding
   function SetCharSet($charset_name)
   {
@@ -794,8 +789,6 @@
        
        function MoveNext()
        {
-               //return adodb_movenext($this);
-               //if (defined('ADODB_EXTENSION')) return adodb_movenext($this);
                if (@$this->fields = 
mysql_fetch_array($this->_queryID,$this->fetchMode)) {
                        $this->_updatefields();
                        $this->_currentRow += 1;
@@ -870,7 +863,7 @@
                        if (!empty($fieldobj->primary_key)) return 'R';
                        else return 'I';
                
-               default: return 'N';
+               default: return ADODB_DEFAULT_METATYPE;
                }
        }
 
@@ -877,10 +870,6 @@
 }
 
 class ADORecordSet_ext_mysql extends ADORecordSet_mysql {      
-       function __construct($queryID,$mode=false)
-               {
-               parent::__construct($queryID,$mode);
-       }
        
        function MoveNext()
        {

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mysqli.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mysqli.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mysqli.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -29,9 +29,6 @@
  if (! defined("MYSQLI_BINARY_FLAG"))  define("MYSQLI_BINARY_FLAG", 128); 
  if (!defined('MYSQLI_READ_DEFAULT_GROUP')) 
define('MYSQLI_READ_DEFAULT_GROUP',1);
 
- // disable adodb extension - currently incompatible.
- global $ADODB_EXTENSION; $ADODB_EXTENSION = false;
-
 class ADODB_mysqli extends ADOConnection {
        var $databaseType = 'mysqli';
        var $dataProvider = 'mysql';
@@ -63,11 +60,12 @@
        var $arrayClass = 'ADORecordSet_array_mysqli';
        var $multiQuery = false;
        
-       function __construct()
-       {                       
-        // if(!extension_loaded("mysqli"))
-               //trigger_error("You must have the mysqli extension 
installed.", E_USER_ERROR);
-       }
+       /*
+       * Tells the insert_id method how to obtain the last value, depending on 
whether
+       * we are using a stored procedure or not
+       */
+       private $usePreparedStatement    = false;
+       private $useLastInsertStatement  = false;
        
        function SetTransactionMode( $transaction_mode ) 
        {
@@ -105,15 +103,25 @@
                read connection options from the standard mysql configuration 
file
                /etc/my.cnf - "Bastien Duclaux" <bduclaux#yahoo.com>
                */
+               $this->optionFlags = array();
                foreach($this->optionFlags as $arr) {   
                        mysqli_options($this->_connectionID,$arr[0],$arr[1]);
                }
 
+               /*
+               * Now merge in the standard connection parameters setting
+               */
+               foreach ($this->connectionParameters as $options)
+               {
+                       foreach($options as $k=>$v)
+                               $ok = 
mysqli_options($this->_connectionID,$k,$v);
+               }
+
                //http ://php.net/manual/en/mysqli.persistconns.php
                if ($persist && PHP_VERSION > 5.2 && 
strncmp($argHostname,'p:',2) != 0) $argHostname = 'p:'.$argHostname;
 
                #if (!empty($this->port)) $argHostname .= ":".$this->port;
-               $ok = mysqli_real_connect($this->_connectionID,
+               $ok = @mysqli_real_connect($this->_connectionID,
                                    $argHostname,
                                    $argUsername,
                                    $argPassword,
@@ -128,7 +136,7 @@
                        return true;
           } else {
                        if ($this->debug) {
-                               ADOConnection::outp("Could't connect : "  . 
$this->ErrorMsg());
+                               ADOConnection::outp("Could not connect : "  . 
$this->ErrorMsg());
                        }
                        $this->_connectionID = null;
                        return false;
@@ -254,10 +262,26 @@
        
        function _insertid()
        {
+               /*
+               * mysqli_insert_id does not return the last_insert_id
+               * if called after execution of a stored procedure
+               * so we execute this instead.
+               */
+               $result = false;
+               if ($this->useLastInsertStatement)
+                       $result = ADOConnection::GetOne('SELECT 
LAST_INSERT_ID()');
+        else
          $result = @mysqli_insert_id($this->_connectionID);
+
                if ($result == -1) {
-             if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed 
: "  . $this->ErrorMsg());
+                       if ($this->debug)
+                               ADOConnection::outp("mysqli_insert_id() failed 
: "  . $this->ErrorMsg());
          }
+               /*
+               * reset prepared statement flags
+               */
+               $this->usePreparedStatement   = false;
+               $this->useLastInsertStatement = false;
          return $result;
        }
        
@@ -575,17 +599,25 @@
        // "Innox - Juan Carlos Gonzalez" <jgonzalez#innox.com.mx>
        function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, 
$associative = FALSE )
        {
+
         global $ADODB_FETCH_MODE;
                
-               if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC || $this->fetchMode 
== ADODB_FETCH_ASSOC) $associative = true;
+               if ($ADODB_FETCH_MODE == ADODB_FETCH_ASSOC
+               || $this->fetchMode == ADODB_FETCH_ASSOC)
+                       $associative = true;
+
+               $savem = $ADODB_FETCH_MODE;
+               $this->setFetchMode(ADODB_FETCH_ASSOC);
                
            if ( !empty($owner) ) {
               $table = "$owner.$table";
            }
+
            $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', 
$table));
-               if ($associative) {
+
+               $this->setFetchMode($savem);
+
                        $create_sql = isset($a_create_table["Create Table"]) ? 
$a_create_table["Create Table"] : $a_create_table["Create View"];
-           } else $create_sql  = $a_create_table[1];
        
            $matches = array();
        
@@ -727,6 +759,14 @@
        
        function Prepare($sql)
        {
+               /*
+               * Flag the insert_id method to use the correct retrieval method
+               */
+               $this->usePreparedStatement = true;
+
+               /*
+               * Prepared statements are not yet handled correctly
+               */
                return $sql;
                $stmt = $this->_connectionID->prepare($sql);
                if (!$stmt) {
@@ -761,11 +801,26 @@
                                else $a .= 'd';
                        }
                        
+                       /*
+                    * set prepared statement flags
+                    */
+                   if ($this->usePreparedStatement)
+                       $this->useLastInsertStatement = true;
+
                        $fnarr = array_merge( array($stmt,$a) , $inputarr);
                        $ret = 
call_user_func_array('mysqli_stmt_bind_param',$fnarr);
                        $ret = mysqli_stmt_execute($stmt);
                        return $ret;
                }
+               else
+               {
+                       /*
+                       * reset prepared statement flags, in case we set them
+                       * previously and didn't use them
+                       */
+                       $this->usePreparedStatement   = false;
+                       $this->useLastInsertStatement = false;
+               }
                
                /*
                if (!$mysql_res =  mysqli_query($this->_connectionID, $sql, 
($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
@@ -817,7 +872,9 @@
        // returns true or false
        function _close()
          {
-           @mysqli_close($this->_connectionID);
+               if($this->_connectionID) {
+                       mysqli_close($this->_connectionID);
+               }
            $this->_connectionID = false;
          }
 
@@ -958,7 +1015,13 @@
                // $o->blob = $o->flags & MYSQLI_BLOB_FLAG; /* not returned by 
MetaColumns */
                $o->unsigned = $o->flags & MYSQLI_UNSIGNED_FLAG;
 
-               return $o;
+               /*
+               * Trivial method to cast class to ADOfieldObject
+               */
+               $a = new ADOFieldObject;
+               foreach (get_object_vars($o) as $key => $name)
+                       $a->$key = $name;
+               return $a;
        }
 
        function GetRowAssoc($upper = ADODB_ASSOC_CASE)
@@ -1191,11 +1254,6 @@
 
 class ADORecordSet_array_mysqli extends ADORecordSet_array {
   
-       function __construct($id=-1,$mode=false)
-  {
-               parent::__construct($id,$mode);
-  }
-  
        function MetaType($t, $len = -1, $fieldobj = false)
        {
                if (is_object($t)) {

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlpo.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlpo.inc.php      2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlpo.inc.php      2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -32,11 +32,6 @@
        var $hasTransactions = true;
        var $autoRollback = true; // apparently mysql does not autorollback 
properly 
        
-       function __construct()
-       {                       
-       global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 
'ext_';
-       }
-       
        function BeginTrans()
        {         
                if ($this->transOff) return true;
@@ -116,11 +111,6 @@
 
 class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {    
 
-       function __construct($queryID,$mode=false)
-               {
-               parent::__construct($queryID,$mode);
-       }
-       
        function MoveNext()
        {
                return adodb_movenext($this);

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlt.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlt.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-mysqlt.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,7 +1,7 @@
 <?php
 
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -29,11 +29,6 @@
        var $hasTransactions = true;
        var $autoRollback = true; // apparently mysql does not autorollback 
properly 
        
-       function __construct()
-       {                       
-       global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 
'ext_';
-       }
-       
        /* set transaction mode
        
        SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-netezza.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-netezza.inc.php      2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-netezza.inc.php      2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  
@@ -50,11 +50,6 @@
                                                        // 
http://bugs.php.net/bug.php?id=25404
 
                                                        
-       function __construct()
-       {
-       
-       }
-       
        function MetaColumns($table,$upper=true) 
        {
        
@@ -141,11 +136,6 @@
        var $databaseType = "netezza";
        var $canSeek = true;
        
-       function __construct($queryID,$mode=false)
-       {
-               parent::__construct($queryID,$mode);
-       }
-       
        // _initrs modified to disable blob handling
        function _initrs()
        {

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-oci8.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-oci8.inc.php 2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-oci8.inc.php 2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,7 +1,7 @@
 <?php
 /*
 
-  @version   v5.20.9  21-Dec-2016
+  @version   v5.21.0-dev  ??-???-2016
   @copyright (c) 2000-2013 John Lim. All rights reserved.
   @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
 
@@ -106,9 +106,6 @@
        function __construct()
        {
                $this->_hasOciFetchStatement = ADODB_PHPVER >= 0x4200;
-               if (defined('ADODB_EXTENSION')) {
-                       $this->rsPrefix .= 'ext_';
-               }
        }
        
        /*  function MetaColumns($table, $normalize=true) added by 
address@hidden/
@@ -1743,6 +1740,7 @@
                        oci_free_cursor($this->_refcursor);
                        $this->_refcursor = false;
                }
+               if (is_resource($this->_queryID))
                @oci_free_statement($this->_queryID);
                $this->_queryID = false;
        }
@@ -1800,16 +1798,12 @@
                        return 'I';
                        
                default:
-                       return 'N';
+                       return ADODB_DEFAULT_METATYPE;
                }
        }
 }
 
 class ADORecordSet_ext_oci8 extends ADORecordSet_oci8 {        
-       function __construct($queryID,$mode=false)
-               {
-               parent::__construct($queryID, $mode);
-       }
        
        function MoveNext()
        {

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-oci805.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-oci805.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-oci805.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /** 
- * @version   v5.20.9  21-Dec-2016
+ * @version   v5.21.0-dev  ??-???-2016
  * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
  * @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
  * Released under both BSD license and Lesser GPL library license. 
@@ -48,8 +48,4 @@
 
 class ADORecordset_oci805 extends ADORecordset_oci8 {  
        var $databaseType = "oci805";
-       function __construct($id,$mode=false)
-       {
-               parent::__construct($id,$mode);
-       }
 }

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-oci8po.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-oci8po.inc.php       2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-oci8po.inc.php       2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim. All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -33,7 +33,6 @@
        function __construct()
        {
                $this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
-               # oci8po does not support adodb extension: adodb_movenext()
        }
        
        function Param($name,$type='C')
@@ -114,11 +113,6 @@
 
        var $databaseType = 'oci8po';
        
-       function __construct($queryID,$mode=false)
-       {
-               parent::__construct($queryID,$mode);
-       }
-
        function Fields($colname)
        {
                if ($this->fetchMode & OCI_ASSOC) return 
$this->fields[$colname];

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-oci8quercus.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-oci8quercus.inc.php  2017-12-25 
21:03:52 UTC (rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-oci8quercus.inc.php  2017-12-26 
11:22:55 UTC (rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /*
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim. All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license.
@@ -28,10 +28,6 @@
        var $databaseType = 'oci8quercus';
        var $dataProvider = 'oci8';
 
-       function __construct()
-       {
-       }
-
 }
 
 
/*--------------------------------------------------------------------------------------
@@ -42,11 +38,6 @@
 
        var $databaseType = 'oci8quercus';
 
-       function __construct($queryID,$mode=false)
-       {
-               parent::__construct($queryID,$mode);
-       }
-
        function _FetchField($fieldOffset = -1)
        {
        global $QUERCUS;

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-odbc.inc.php
===================================================================
--- trunk/phpgwapi/inc/adodb/drivers/adodb-odbc.inc.php 2017-12-25 21:03:52 UTC 
(rev 17469)
+++ trunk/phpgwapi/inc/adodb/drivers/adodb-odbc.inc.php 2017-12-26 11:22:55 UTC 
(rev 17470)
@@ -1,6 +1,6 @@
 <?php
 /* 
address@hidden   v5.20.9  21-Dec-2016
address@hidden   v5.21.0-dev  ??-???-2016
 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
 @copyright (c) 2014      Damien Regad, Mark Newnham and the ADOdb community
   Released under both BSD license and Lesser GPL library license. 
@@ -17,6 +17,18 @@
 
   define("_ADODB_ODBC_LAYER", 2 );
         
+/*
+ * These constants are used to set define MetaColumns() method's behavior.
+ * - METACOLUMNS_RETURNS_ACTUAL makes the driver return the actual type, 
+ *   like all other drivers do (default)
+ * - METACOLUMNS_RETURNS_META is provided for legacy compatibility (makes
+ *   driver behave as it did prior to v5.21)
+ *
+ * @see $metaColumnsReturnType
+ */
+DEFINE('METACOLUMNS_RETURNS_ACTUAL', 0);
+DEFINE('METACOLUMNS_RETURNS_META', 1);
+       
 
/*--------------------------------------------------------------------------------------
 
--------------------------------------------------------------------------------------*/
 
@@ -41,6 +53,11 @@
        var $_lastAffectedRows = 0;
        var $uCaseTables = true; // for meta* functions, uppercase table names
        
+       /*
+        * Tells the metaColumns feature whether to return actual or meta type
+        */
+       public $metaColumnsReturnType = METACOLUMNS_RETURNS_ACTUAL;
+
        function __construct()
        {       
                $this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
@@ -463,7 +480,16 @@
                        if (strtoupper(trim($rs->fields[2])) == $table && 
(!$schema || strtoupper($rs->fields[1]) == $schema)) {
                                $fld = new ADOFieldObject();
                                $fld->name = $rs->fields[3];
+                               if ($this->metaColumnsReturnType == 
METACOLUMNS_RETURNS_META)
+                                       /* 
+                                   * This is the broken, original value
+                                       */
                                $fld->type = $this->ODBCTypes($rs->fields[4]);
+                               else
+                                       /*
+                                   * This is the correct new value
+                                       */
+                                   $fld->type = $rs->fields[4];
                                
                                // ref: 
http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
                                // access uses precision to store length for 
char/varchar

Modified: trunk/phpgwapi/inc/adodb/drivers/adodb-odbc_db2.inc.php
===================================================================

@@ Diff output truncated at 153600 characters. @@



reply via email to

[Prev in Thread] Current Thread [Next in Thread]