diff options
143 files changed, 3361 insertions, 1227 deletions
diff --git a/adodb-active-record.inc.php b/adodb-active-record.inc.php index a7f0adf7..64c73c48 100644 --- a/adodb-active-record.inc.php +++ b/adodb-active-record.inc.php @@ -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 Latest version is available at http://adodb.sourceforge.net @@ -522,7 +522,7 @@ class ADODB_Active_Record { $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); } diff --git a/adodb-active-recordx.inc.php b/adodb-active-recordx.inc.php index 7f553f1e..986cbf96 100644 --- a/adodb-active-recordx.inc.php +++ b/adodb-active-recordx.inc.php @@ -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 Latest version is available at http://adodb.sourceforge.net @@ -551,7 +551,7 @@ class ADODB_Active_Record { $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 @@ function adodb_GetActiveRecordsClass(&$db, $class, $tableObj,$whereOrderBy,$bind 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'); diff --git a/adodb-csvlib.inc.php b/adodb-csvlib.inc.php index bfd8d9b8..2400396a 100644 --- a/adodb-csvlib.inc.php +++ b/adodb-csvlib.inc.php @@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 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. diff --git a/adodb-datadict.inc.php b/adodb-datadict.inc.php index b15a80e6..1c80135e 100644 --- a/adodb-datadict.inc.php +++ b/adodb-datadict.inc.php @@ -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 @@ class ADODB_DataDict { 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 @@ class ADODB_DataDict { 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 @@ class ADODB_DataDict { $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 @@ class ADODB_DataDict { // 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 @@ class ADODB_DataDict { $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,13 +813,32 @@ class ADODB_DataDict { $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; 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; } diff --git a/adodb-error.inc.php b/adodb-error.inc.php index d42a06a8..020f65d0 100644 --- a/adodb-error.inc.php +++ b/adodb-error.inc.php @@ -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 @@ function adodb_error($provider,$dbType,$errno) 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 @@ function adodb_error_pg($errormsg) '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; } diff --git a/adodb-errorhandler.inc.php b/adodb-errorhandler.inc.php index 7f36ba1e..f1b571fb 100644 --- a/adodb-errorhandler.inc.php +++ b/adodb-errorhandler.inc.php @@ -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. diff --git a/adodb-errorpear.inc.php b/adodb-errorpear.inc.php index 474d6d5b..50a94783 100644 --- a/adodb-errorpear.inc.php +++ b/adodb-errorpear.inc.php @@ -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. diff --git a/adodb-exceptions.inc.php b/adodb-exceptions.inc.php index 9c66ac39..fcf792f4 100644 --- a/adodb-exceptions.inc.php +++ b/adodb-exceptions.inc.php @@ -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. diff --git a/adodb-iterator.inc.php b/adodb-iterator.inc.php index cfc067bc..4aab7a6a 100644 --- a/adodb-iterator.inc.php +++ b/adodb-iterator.inc.php @@ -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. diff --git a/adodb-lib.inc.php b/adodb-lib.inc.php index eb89adba..bc6d5d44 100644 --- a/adodb-lib.inc.php +++ b/adodb-lib.inc.php @@ -6,7 +6,7 @@ global $ADODB_INCLUDED_LIB; $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. @@ -468,18 +468,11 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr); } if ($rstest) { - $qryRecs = $rstest->RecordCount(); + $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(); - } + // some databases will return -1 on MoveLast() - change to MoveNext() + while(!$rstest->EOF) { + $rstest->MoveNext(); } $qryRecs = $rstest->_currentRow; } @@ -885,22 +878,22 @@ static $cacheCols; { 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); 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, "; @@ -908,6 +901,21 @@ static $cacheCols; $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 /*********************************************************/ diff --git a/adodb-memcache.lib.inc.php b/adodb-memcache.lib.inc.php index 42d2be62..97f78c9e 100644 --- a/adodb-memcache.lib.inc.php +++ b/adodb-memcache.lib.inc.php @@ -11,7 +11,7 @@ if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.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. @@ -28,11 +28,14 @@ $db->memCache = true; /// should we use memCache instead of caching in files $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 @@ $db->CacheExecute($sql); 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 @@ $db->CacheExecute($sql); // 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 (!@$memcache->addServer($host,$this->port,true)) { + if (!@$memcache->addServer($host,$this->port)) { $failcnt += 1; } } @@ -93,8 +106,25 @@ $db->CacheExecute($sql); } if (!$this->_memcache) return false; - 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=false; + switch ($this->library) { + case 'Memcache': + if (!$this->_memcache->set($filename, $contents, $this->compress ? MEMCACHE_COMPRESSED : 0, $secs2cache)) { + $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 @@ $db->CacheExecute($sql); $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 @@ $db->CacheExecute($sql); $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; } diff --git a/adodb-pager.inc.php b/adodb-pager.inc.php index fa77d55c..b1b05f0f 100644 --- a/adodb-pager.inc.php +++ b/adodb-pager.inc.php @@ -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. diff --git a/adodb-pear.inc.php b/adodb-pear.inc.php index c8f09331..888f18f7 100644 --- a/adodb-pear.inc.php +++ b/adodb-pear.inc.php @@ -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. diff --git a/adodb-perf.inc.php b/adodb-perf.inc.php index 42ccfa19..4678baba 100644 --- a/adodb-perf.inc.php +++ b/adodb-perf.inc.php @@ -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. diff --git a/adodb-php4.inc.php b/adodb-php4.inc.php index 132f25d0..a51cb8e0 100644 --- a/adodb-php4.inc.php +++ b/adodb-php4.inc.php @@ -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. diff --git a/adodb-time.inc.php b/adodb-time.inc.php index 54e29693..810b7630 100644 --- a/adodb-time.inc.php +++ b/adodb-time.inc.php @@ -3,7 +3,7 @@ ADOdb Date Library, part of the ADOdb abstraction library Download: http://adodb.sourceforge.net/#download -@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 @@ -1071,7 +1071,6 @@ static $daylight; 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 @@ static $jan1_1971; 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 @@ static $jan1_1971; 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 @@ static $jan1_1971; 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; diff --git a/adodb-xmlschema03.inc.php b/adodb-xmlschema03.inc.php index c1ecb885..d8349683 100644 --- a/adodb-xmlschema03.inc.php +++ b/adodb-xmlschema03.inc.php @@ -506,7 +506,7 @@ class dbTable extends dbObject { */ function addTableOpt( $opt ) { if(isset($this->currentPlatform)) { - $this->opts[$this->parent->db->databaseType] = $opt; + $this->opts[$this->parent->db->dataProvider] = $opt; } return $this->opts; } diff --git a/adodb.inc.php b/adodb.inc.php index 105b1125..0e2fe860 100644 --- a/adodb.inc.php +++ b/adodb.inc.php @@ -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 @@ if (!defined('_ADODB_LAYER')) { $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,35 +84,52 @@ if (!defined('_ADODB_LAYER')) { // 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); - define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>'); + /* + * 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>'); // allow [ ] @ ` " and . in table names - define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)'); + define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)'); // prefetching used by oracle - if (!defined('ADODB_PREFETCH_ROWS')) { - define('ADODB_PREFETCH_ROWS',10); - } + if (!defined('ADODB_PREFETCH_ROWS')) { + define('ADODB_PREFETCH_ROWS',10); + } /** @@ -128,10 +144,10 @@ if (!defined('_ADODB_LAYER')) { * - BOTH: array(0 => 456, 'id' => 456, 1 => 'john', 'name' => 'john') * - DEFAULT: driver-dependent */ - define('ADODB_FETCH_DEFAULT', 0); - define('ADODB_FETCH_NUM', 1); - define('ADODB_FETCH_ASSOC', 2); - define('ADODB_FETCH_BOTH', 3); + define('ADODB_FETCH_DEFAULT', 0); + define('ADODB_FETCH_NUM', 1); + define('ADODB_FETCH_ASSOC', 2); + define('ADODB_FETCH_BOTH', 3); /** * Associative array case constants @@ -148,34 +164,34 @@ if (!defined('_ADODB_LAYER')) { * NOTE: This functionality is not implemented everywhere, it currently * works only with: mssql, odbc, oci8 and ibase derived drivers */ - define('ADODB_ASSOC_CASE_LOWER', 0); - define('ADODB_ASSOC_CASE_UPPER', 1); - define('ADODB_ASSOC_CASE_NATIVE', 2); + define('ADODB_ASSOC_CASE_LOWER', 0); + define('ADODB_ASSOC_CASE_UPPER', 1); + define('ADODB_ASSOC_CASE_NATIVE', 2); - if (!defined('TIMESTAMP_FIRST_YEAR')) { - define('TIMESTAMP_FIRST_YEAR',100); - } + if (!defined('TIMESTAMP_FIRST_YEAR')) { + define('TIMESTAMP_FIRST_YEAR',100); + } - /** - * AutoExecute constants - * (moved from adodb-pear.inc.php since they are only used in here) - */ - define('DB_AUTOQUERY_INSERT', 1); - define('DB_AUTOQUERY_UPDATE', 2); + /** + * AutoExecute constants + * (moved from adodb-pear.inc.php since they are only used in here) + */ + define('DB_AUTOQUERY_INSERT', 1); + define('DB_AUTOQUERY_UPDATE', 2); - // PHP's version scheme makes converting to numbers difficult - workaround - $_adodb_ver = (float) PHP_VERSION; - if ($_adodb_ver >= 5.2) { - define('ADODB_PHPVER',0x5200); - } else if ($_adodb_ver >= 5.0) { - define('ADODB_PHPVER',0x5000); - } else { - die("PHP5 or later required. You are running ".PHP_VERSION); - } - unset($_adodb_ver); + // PHP's version scheme makes converting to numbers difficult - workaround + $_adodb_ver = (float) PHP_VERSION; + if ($_adodb_ver >= 5.2) { + define('ADODB_PHPVER',0x5200); + } else if ($_adodb_ver >= 5.0) { + define('ADODB_PHPVER',0x5000); + } else { + die("PHP5 or later required. You are running ".PHP_VERSION); } + unset($_adodb_ver); + /** @@ -232,7 +248,7 @@ if (!defined('_ADODB_LAYER')) { /** * 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 @@ if (!defined('_ADODB_LAYER')) { 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 @@ if (!defined('_ADODB_LAYER')) { 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 @@ if (!defined('_ADODB_LAYER')) { final public function setConnectionParameter($parameter,$value) { - $this->connectionParameters[$parameter] = $value; + $this->connectionParameters[] = array($parameter=>$value); } @@ -601,8 +628,7 @@ if (!defined('_ADODB_LAYER')) { $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 @@ if (!defined('_ADODB_LAYER')) { /** * 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 @@ if (!defined('_ADODB_LAYER')) { 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 (!defined('_ADODB_LAYER')) { 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 @@ if (!defined('_ADODB_LAYER')) { 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 @@ if (!defined('_ADODB_LAYER')) { /** * 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 @@ if (!defined('_ADODB_LAYER')) { * @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 @@ -1508,32 +1545,47 @@ if (!defined('_ADODB_LAYER')) { } if ($offset <= 0) { - // access includes ties in result - if ($isaccess) { - $sql = preg_replace( - '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); + // access includes ties in result + if ($isaccess) { + $sql = preg_replace( + '/(^\s*select\s+(distinctrow|distinct)?)/i', + '\\1 '.$this->hasTop.' '.$nrows.' ', + $sql + ); - if ($secs2cache != 0) { - $ret = $this->CacheExecute($secs2cache, $sql,$inputarr); - } else { - $ret = $this->Execute($sql,$inputarr); - } - return $ret; // PHP5 fix - } else if ($ismssql){ - $sql = preg_replace( - '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); + if ($secs2cache != 0) { + $ret = $this->CacheExecute($secs2cache, $sql,$inputarr); } else { - $sql = preg_replace( - '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql); + $ret = $this->Execute($sql,$inputarr); } + return $ret; // PHP5 fix + } else if ($ismssql){ + $sql = preg_replace( + '/(^\s*select\s+(distinctrow|distinct)?)/i', + '\\1 '.$this->hasTop.' '.$nrows.' ', + $sql + ); + } else { + $sql = preg_replace( + '/(^\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 @@ if (!defined('_ADODB_LAYER')) { 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,18 +1717,18 @@ if (!defined('_ADODB_LAYER')) { if (!$rs) { return false; } - $arr = $rs->GetAssoc($force_array,$first2cols); - return $arr; + return $rs->GetAssoc($force_array, $first2cols); } /** - * Return first element of first row of sql statement. Recordset is disposed - * for you. - * - * @param sql SQL statement - * @param [inputarr] input bind array - */ - function GetOne($sql,$inputarr=false) { + * Return first element of first row of sql statement. Recordset is disposed + * for you. + * + * @param string $sql SQL statement + * @param array|bool $inputarr input bind array + * @return mixed + */ + public function GetOne($sql, $inputarr=false) { global $ADODB_COUNTRECS,$ADODB_GETONE_EOF; $crecs = $ADODB_COUNTRECS; @@ -1902,7 +1974,7 @@ if (!defined('_ADODB_LAYER')) { 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 @@ if (!defined('_ADODB_LAYER')) { $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 (!defined('_ADODB_LAYER')) { // ******************************************************** 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 @@ if (!defined('_ADODB_LAYER')) { $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); } @@ -3006,7 +3082,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 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); @@ -3040,6 +3116,85 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 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 @@ -3176,7 +3331,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 // DATE AND TIME FUNCTIONS //============================================================================================== if (!defined('ADODB_DATE_VERSION')) { - include(ADODB_DIR.'/adodb-time.inc.php'); + include_once(ADODB_DIR.'/adodb-time.inc.php'); } //============================================================================================== @@ -3340,7 +3495,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 { 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); @@ -3368,7 +3523,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 { 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); @@ -3382,10 +3537,6 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * @return an array indexed by the rows (0-based) from the recordset */ function GetArray($nRows = -1) { - global $ADODB_EXTENSION; if ($ADODB_EXTENSION) { - $results = adodb_getall($this,$nRows); - return $results; - } $results = array(); $cnt = 0; while (!$this->EOF && $nRows != $cnt) { @@ -3450,123 +3601,149 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 } /** - * 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, - * read the source. + * @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 mixed * - * @return an associative array indexed by the first column of the array, - * or false if the data has less than 2 cols. */ - function GetAssoc($force_array = false, $first2cols = false) { - global $ADODB_EXTENSION; - - $cols = $this->_numOfFields; - if ($cols < 2) { - return false; - } + function getAssoc($force_array = false, $first2cols = 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); - } - } else { - while (!$this->EOF) { - // Fix for array_slice re-numbering numeric associative keys - $keys = array_slice(array_keys($this->fields), 1); - $sliced_array = array(); + /* + * We use the associative method if ADODB_FETCH_BOTH + */ + $fetchMode = ADODB_FETCH_ASSOC; + } - 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); } - } 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 { - 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(); - } + + /* + * 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 + /* + * 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; } - } - $ref = $results; # workaround accelerator incompat with PHP 4.4 :( - return $ref; + $this->MoveNext(); + } + /* + * Done + */ + return $results; } - /** * * @param v is the character timestamp in YYYY-MM-DD hh:mm:ss format @@ -3785,18 +3962,11 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 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++; + while (! $this->EOF && $this->_currentRow < $rowNumber) { + $this->_currentRow++; - if (!$this->_fetch()) { - $this->EOF = true; - } + if (!$this->_fetch()) { + $this->EOF = true; } } return !($this->EOF); @@ -4011,9 +4181,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * */ function FieldTypesArray() { - $arr = array(); - for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) - $arr[] = $this->FetchField($i); + static $arr = array(); + if (empty($arr)) { + for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) { + $arr[] = $this->FetchField($i); + } + } return $arr; } @@ -4135,6 +4308,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $len = $fieldobj->max_length; } + // changed in 2.32 to hashing instead of switch stmt for speed... static $typeMap = array( 'VARCHAR' => 'C', @@ -4241,9 +4415,10 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 "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... @@ -4396,7 +4571,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 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; @@ -4616,7 +4791,13 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 break; default: - $class = $db; break; + if (substr($db, 0, 4) === 'pdo_') { + ADOConnection::outp("Invalid database type: $db"); + return false; + } + + $class = $db; + break; } $file = "drivers/adodb-$db.inc.php"; @@ -4968,7 +5149,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 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); } diff --git a/composer.json b/composer.json index 30fcc358..ef5f5438 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ }, "require" : { - "php" : ">=5.3.2" + "php" : "^5.3.2 || ^7.0" }, "autoload" : { diff --git a/datadict/datadict-access.inc.php b/datadict/datadict-access.inc.php index c1459154..8fbc6fe4 100644 --- a/datadict/datadict-access.inc.php +++ b/datadict/datadict-access.inc.php @@ -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. diff --git a/datadict/datadict-db2.inc.php b/datadict/datadict-db2.inc.php index 7d201ff1..69c40986 100644 --- a/datadict/datadict-db2.inc.php +++ b/datadict/datadict-db2.inc.php @@ -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 @@ class ADODB2_db2 extends ADODB_DataDict { return array(); } - - function ChangeTableSQL($tablename, $flds, $tableoptions = false) + function ChangeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false) { /** diff --git a/datadict/datadict-firebird.inc.php b/datadict/datadict-firebird.inc.php index f247c8dc..acf605c1 100644 --- a/datadict/datadict-firebird.inc.php +++ b/datadict/datadict-firebird.inc.php @@ -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) + 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 @@ class ADODB2_firebird extends ADODB_DataDict { 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 @@ class ADODB2_firebird extends ADODB_DataDict { } } - function NameQuote($name = NULL) + function NameQuote($name = NULL,$allowBrackets=false) { if (!is_string($name)) { return FALSE; @@ -90,9 +99,9 @@ class ADODB2_firebird extends ADODB_DataDict { { 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 @@ class ADODB2_firebird extends ADODB_DataDict { 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,24 +167,60 @@ end; 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['DROP'])) + { $sql[] = "DROP GENERATOR $seqname"; } - if (isset($tableoptions['REPLACE'])) + 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; 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; + } + } diff --git a/datadict/datadict-generic.inc.php b/datadict/datadict-generic.inc.php index e2e6909e..e257df15 100644 --- a/datadict/datadict-generic.inc.php +++ b/datadict/datadict-generic.inc.php @@ -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. diff --git a/datadict/datadict-ibase.inc.php b/datadict/datadict-ibase.inc.php index 495a722d..a36c2211 100644 --- a/datadict/datadict-ibase.inc.php +++ b/datadict/datadict-ibase.inc.php @@ -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. diff --git a/datadict/datadict-informix.inc.php b/datadict/datadict-informix.inc.php index 25726f49..9cbad313 100644 --- a/datadict/datadict-informix.inc.php +++ b/datadict/datadict-informix.inc.php @@ -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. diff --git a/datadict/datadict-mssql.inc.php b/datadict/datadict-mssql.inc.php index 2c496dea..86ac66ba 100644 --- a/datadict/datadict-mssql.inc.php +++ b/datadict/datadict-mssql.inc.php @@ -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 @@ CREATE TABLE } - function _GetSize($ftype, $ty, $fsize, $fprec) + function _GetSize($ftype, $ty, $fsize, $fprec, $options=false) { switch ($ftype) { case 'INT': @@ -279,7 +279,7 @@ CREATE TABLE return $ftype; } if ($ty == 'T') return $ftype; - return parent::_GetSize($ftype, $ty, $fsize, $fprec); + return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options); } } diff --git a/datadict/datadict-mssqlnative.inc.php b/datadict/datadict-mssqlnative.inc.php index 36d5fcad..bd4e238d 100644 --- a/datadict/datadict-mssqlnative.inc.php +++ b/datadict/datadict-mssqlnative.inc.php @@ -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 @@ class ADODB2_mssqlnative extends ADODB_DataDict { -3 => 'X' ); - return $_typeConversion($t); + if (isset($_typeConversion[$t])) + return $_typeConversion[$t]; + + return ADODB_DEFAULT_METATYPE; } @@ -126,7 +129,6 @@ class ADODB2_mssqlnative extends ADODB_DataDict { case 'F': return 'REAL'; case 'N': return 'NUMERIC'; default: - print "RETURN $meta"; return $meta; } } @@ -353,7 +355,7 @@ CREATE TABLE } - function _GetSize($ftype, $ty, $fsize, $fprec) + function _GetSize($ftype, $ty, $fsize, $fprec,$options=false) { switch ($ftype) { case 'INT': @@ -363,7 +365,7 @@ CREATE TABLE return $ftype; } if ($ty == 'T') return $ftype; - return parent::_GetSize($ftype, $ty, $fsize, $fprec); + return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options); } } diff --git a/datadict/datadict-mysql.inc.php b/datadict/datadict-mysql.inc.php index 00a43a2a..640fb87a 100644 --- a/datadict/datadict-mysql.inc.php +++ b/datadict/datadict-mysql.inc.php @@ -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 @@ class ADODB2_mysql extends ADODB_DataDict { function MetaType($t,$len=-1,$fieldobj=false) { + if (is_object($t)) { $fieldobj = $t; $t = $fieldobj->type; @@ -74,7 +75,7 @@ class ADODB2_mysql extends ADODB_DataDict { 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; } } diff --git a/datadict/datadict-oci8.inc.php b/datadict/datadict-oci8.inc.php index 57cf0af5..53548d34 100644 --- a/datadict/datadict-oci8.inc.php +++ b/datadict/datadict-oci8.inc.php @@ -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 @@ class ADODB2_oci8 extends ADODB_DataDict { return 'I'; default: - return 'N'; + return ADODB_DEFAULT_METATYPE; } } diff --git a/datadict/datadict-postgres.inc.php b/datadict/datadict-postgres.inc.php index 99a56413..d2d3d6da 100644 --- a/datadict/datadict-postgres.inc.php +++ b/datadict/datadict-postgres.inc.php @@ -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 @@ class ADODB2_postgres extends ADODB_DataDict { return 'F'; default: - return 'N'; + return ADODB_DEFAULT_METATYPE; } } @@ -472,13 +472,31 @@ CREATE [ UNIQUE ] INDEX index_name ON table 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; 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; } } diff --git a/datadict/datadict-sapdb.inc.php b/datadict/datadict-sapdb.inc.php index fbf931c7..b169e924 100644 --- a/datadict/datadict-sapdb.inc.php +++ b/datadict/datadict-sapdb.inc.php @@ -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 @@ class ADODB2_sapdb extends ADODB_DataDict { '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)) { diff --git a/datadict/datadict-sqlite.inc.php b/datadict/datadict-sqlite.inc.php index 86b1b047..44b949c9 100644 --- a/datadict/datadict-sqlite.inc.php +++ b/datadict/datadict-sqlite.inc.php @@ -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 @@ class ADODB2_sqlite extends ADODB_DataDict { } // 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'; diff --git a/datadict/datadict-sybase.inc.php b/datadict/datadict-sybase.inc.php index d4e5f053..e4cdddd4 100644 --- a/datadict/datadict-sybase.inc.php +++ b/datadict/datadict-sybase.inc.php @@ -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. diff --git a/docs/changelog.md b/docs/changelog.md index 1e097e96..6241852c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -5,6 +5,50 @@ Older changelogs: [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 diff --git a/drivers/adodb-access.inc.php b/drivers/adodb-access.inc.php index 3a5a8edc..2d0048f3 100644 --- a/drivers/adodb-access.inc.php +++ b/drivers/adodb-access.inc.php @@ -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. @@ -15,10 +15,11 @@ 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')) { - define('_ADODB_ACCESS',1); + +if (!defined('_ADODB_ACCESS')) { + define('_ADODB_ACCESS',1); class ADODB_access extends ADODB_odbc { var $databaseType = 'access'; @@ -31,14 +32,6 @@ class ADODB_access extends ADODB_odbc { var $hasTransactions = false; var $upperCase = 'ucase'; - function __construct() - { - global $ADODB_EXTENSION; - - $ADODB_EXTENSION = false; - parent::__construct(); - } - function Time() { return time(); @@ -80,9 +73,6 @@ class ADORecordSet_access extends ADORecordSet_odbc { var $databaseType = "access"; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } -}// class +} // class + } diff --git a/drivers/adodb-ado.inc.php b/drivers/adodb-ado.inc.php index 449cdd00..32f251cb 100644 --- a/drivers/adodb-ado.inc.php +++ b/drivers/adodb-ado.inc.php @@ -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. @@ -225,7 +225,7 @@ class ADODB_ado extends ADOConnection { // 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 @@ class ADORecordSet_ado extends ADORecordSet { $mode = $ADODB_FETCH_MODE; } $this->fetchMode = $mode; - return parent::__construct($id,$mode); + return parent::__construct($id); } @@ -538,7 +538,7 @@ class ADORecordSet_ado extends ADORecordSet { case 19://adUnsignedInt = 19, case 20://adUnsignedBigInt = 21, return 'I'; - default: return 'N'; + default: return ADODB_DEFAULT_METATYPE; } } diff --git a/drivers/adodb-ado5.inc.php b/drivers/adodb-ado5.inc.php index 21df32f1..e58fed8f 100644 --- a/drivers/adodb-ado5.inc.php +++ b/drivers/adodb-ado5.inc.php @@ -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. @@ -248,7 +248,7 @@ class ADODB_ado extends ADOConnection { $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 @@ class ADORecordSet_ado extends ADORecordSet { $mode = $ADODB_FETCH_MODE; } $this->fetchMode = $mode; - return parent::__construct($id,$mode); + return parent::__construct($id); } @@ -579,7 +579,7 @@ class ADORecordSet_ado extends ADORecordSet { case 19://adUnsignedInt = 19, case 20://adUnsignedBigInt = 21, return 'I'; - default: return 'N'; + default: return ADODB_DEFAULT_METATYPE; } } diff --git a/drivers/adodb-ado_access.inc.php b/drivers/adodb-ado_access.inc.php index c167ce63..117b0363 100644 --- a/drivers/adodb-ado_access.inc.php +++ b/drivers/adodb-ado_access.inc.php @@ -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. @@ -17,8 +17,8 @@ Set tabs to 4 for best viewing. 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 @@ class ADORecordSet_ado_access extends ADORecordSet_ado { var $databaseType = "ado_access"; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-ado_mssql.inc.php b/drivers/adodb-ado_mssql.inc.php index 57eacc93..6923b850 100644 --- a/drivers/adodb-ado_mssql.inc.php +++ b/drivers/adodb-ado_mssql.inc.php @@ -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. @@ -21,8 +21,8 @@ Set tabs to 4 for best viewing. 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"); } @@ -43,12 +43,12 @@ class ADODB_ado_mssql extends ADODB_ado { function _insertid() { - return $this->GetOne('select SCOPE_IDENTITY()'); + return $this->GetOne('select SCOPE_IDENTITY()'); } function _affectedrows() { - return $this->GetOne('select @@rowcount'); + return $this->GetOne('select @@rowcount'); } function SetTransactionMode( $transaction_mode ) @@ -70,32 +70,32 @@ class ADODB_ado_mssql extends ADODB_ado { function MetaColumns($table, $normalize=true) { - $table = strtoupper($table); - $arr= array(); - $dbc = $this->_connectionID; + $table = strtoupper($table); + $arr= array(); + $dbc = $this->_connectionID; - $osoptions = array(); - $osoptions[0] = null; - $osoptions[1] = null; - $osoptions[2] = $table; - $osoptions[3] = null; + $osoptions = array(); + $osoptions[0] = null; + $osoptions[1] = null; + $osoptions[2] = $table; + $osoptions[3] = null; - $adors=@$dbc->OpenSchema(4, $osoptions);//tables + $adors=@$dbc->OpenSchema(4, $osoptions);//tables - if ($adors){ - while (!$adors->EOF){ - $fld = new ADOFieldObject(); - $c = $adors->Fields(3); - $fld->name = $c->Value; - $fld->type = 'CHAR'; // cannot discover type in ADO! - $fld->max_length = -1; - $arr[strtoupper($fld->name)]=$fld; + if ($adors){ + while (!$adors->EOF){ + $fld = new ADOFieldObject(); + $c = $adors->Fields(3); + $fld->name = $c->Value; + $fld->type = 'CHAR'; // cannot discover type in ADO! + $fld->max_length = -1; + $arr[strtoupper($fld->name)]=$fld; - $adors->MoveNext(); - } - $adors->Close(); - } - $false = false; + $adors->MoveNext(); + } + $adors->Close(); + } + $false = false; return empty($arr) ? $false : $arr; } @@ -137,14 +137,10 @@ class ADODB_ado_mssql extends ADODB_ado { //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); - } } diff --git a/drivers/adodb-borland_ibase.inc.php b/drivers/adodb-borland_ibase.inc.php index d3de2caa..7c08f354 100644 --- a/drivers/adodb-borland_ibase.inc.php +++ b/drivers/adodb-borland_ibase.inc.php @@ -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. @@ -80,8 +80,4 @@ class ADORecordSet_borland_ibase extends ADORecordSet_ibase { var $databaseType = "borland_ibase"; - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-csv.inc.php b/drivers/adodb-csv.inc.php index fd47784d..bceaf394 100644 --- a/drivers/adodb-csv.inc.php +++ b/drivers/adodb-csv.inc.php @@ -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. @@ -38,18 +38,14 @@ class ADODB_csv extends ADOConnection { var $hasTransactions = false; var $_errorNo = false; - function __construct() - { - } - function _insertid() { - return $this->_insertid; + return $this->_insertid; } function _affectedrows() { - return $this->_affectedrows; + return $this->_affectedrows; } function MetaDatabases() @@ -176,7 +172,7 @@ class ADODB_csv extends ADOConnection { /* Returns: the last error message from previous database operation */ function ErrorMsg() { - return $this->_errorMsg; + return $this->_errorMsg; } /* Returns: the last error number from previous database operation */ @@ -193,10 +189,6 @@ class ADODB_csv extends ADOConnection { } // class class ADORecordset_csv extends ADORecordset { - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } function _close() { diff --git a/drivers/adodb-db2.inc.php b/drivers/adodb-db2.inc.php index e7b9dbdd..be84ae49 100644 --- a/drivers/adodb-db2.inc.php +++ b/drivers/adodb-db2.inc.php @@ -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 diff --git a/drivers/adodb-db2oci.inc.php b/drivers/adodb-db2oci.inc.php index 91d61af1..0ca5209e 100644 --- a/drivers/adodb-db2oci.inc.php +++ b/drivers/adodb-db2oci.inc.php @@ -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. @@ -15,49 +15,19 @@ Set tabs to 4 for best viewing. // 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 @@ class ADORecordSet_db2oci extends ADORecordSet_db2 { var $databaseType = "db2oci"; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } } //define diff --git a/drivers/adodb-db2ora.inc.php b/drivers/adodb-db2ora.inc.php index 1261689d..c3a8c1d2 100644 --- a/drivers/adodb-db2ora.inc.php +++ b/drivers/adodb-db2ora.inc.php @@ -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. @@ -15,7 +15,7 @@ Set tabs to 4 for best viewing. // 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 @@ class ADORecordSet_db2oci extends ADORecordSet_odbc { var $databaseType = "db2oci"; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } } //define diff --git a/drivers/adodb-fbsql.inc.php b/drivers/adodb-fbsql.inc.php index 9a2440cf..c5c5f5a8 100644 --- a/drivers/adodb-fbsql.inc.php +++ b/drivers/adodb-fbsql.inc.php @@ -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 @@ class ADODB_fbsql extends ADOConnection { 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 @@ class ADORecordSet_fbsql extends ADORecordSet{ if (!empty($fieldobj->primary_key)) return 'R'; else return 'I'; - default: return 'N'; + default: return ADODB_DEFAULT_METATYPE; } } diff --git a/drivers/adodb-firebird.inc.php b/drivers/adodb-firebird.inc.php index 415f66f2..a1b7f9ac 100644 --- a/drivers/adodb-firebird.inc.php +++ b/drivers/adodb-firebird.inc.php @@ -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. @@ -10,18 +10,114 @@ Set tabs to 4 for best viewing. 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 @@ class ADODB_firebird extends ADODB_ibase { 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 <kevinboillet@yahoo.fr> + 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 @@ class ADODB_firebird extends ADODB_ibase { 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; + } + } + } diff --git a/drivers/adodb-ibase.inc.php b/drivers/adodb-ibase.inc.php index c4f0cbdb..3a079811 100644 --- a/drivers/adodb-ibase.inc.php +++ b/drivers/adodb-ibase.inc.php @@ -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. @@ -911,7 +911,7 @@ class ADORecordset_ibase extends ADORecordSet case 'INT': case 'SHORT': case 'INTEGER': return 'I'; - default: return 'N'; + default: return ADODB_DEFAULT_METATYPE; } } diff --git a/drivers/adodb-informix.inc.php b/drivers/adodb-informix.inc.php index 801451ea..399f642d 100644 --- a/drivers/adodb-informix.inc.php +++ b/drivers/adodb-informix.inc.php @@ -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 ADODB_informix extends ADODB_informix72 { class ADORecordset_informix extends ADORecordset_informix72 { var $databaseType = "informix"; - - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-informix72.inc.php b/drivers/adodb-informix72.inc.php index 58f233a1..8b67dad6 100644 --- a/drivers/adodb-informix72.inc.php +++ b/drivers/adodb-informix72.inc.php @@ -1,6 +1,6 @@ <?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 Released under both BSD license and Lesser GPL library license. diff --git a/drivers/adodb-ldap.inc.php b/drivers/adodb-ldap.inc.php index 633705e0..a54bb09a 100644 --- a/drivers/adodb-ldap.inc.php +++ b/drivers/adodb-ldap.inc.php @@ -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 @@ class ADODB_ldap extends ADOConnection { # 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 @@ class ADORecordSet_ldap extends ADORecordSet{ /* Return whole recordset as a multi-dimensional associative array */ - function GetAssoc($force_array = false, $first2cols = false) + function GetAssoc($force_array = false, $first2cols = false, $fetchMode = -1) { $records = $this->_numOfRows; $results = array(); diff --git a/drivers/adodb-mssql.inc.php b/drivers/adodb-mssql.inc.php index 068dffce..de3c75ba 100644 --- a/drivers/adodb-mssql.inc.php +++ b/drivers/adodb-mssql.inc.php @@ -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. @@ -155,9 +155,9 @@ class ADODB_mssql extends ADOConnection { // the same scope. A scope is a module -- a stored procedure, trigger, // function, or batch. Thus, two statements are in the same scope if // they are in the same stored procedure, function, or batch. - if ($this->lastInsID !== false) { - return $this->lastInsID; // InsID from sp_executesql call - } else { + if ($this->lastInsID !== false) { + return $this->lastInsID; // InsID from sp_executesql call + } else { return $this->GetOne($this->identitySQL); } } @@ -177,22 +177,22 @@ class ADODB_mssql extends ADOConnection { */ function qstr($s,$magic_quotes=false) { - if (!$magic_quotes) { - return "'".str_replace("'",$this->replaceQuote,$s)."'"; + if (!$magic_quotes) { + return "'".str_replace("'",$this->replaceQuote,$s)."'"; } - // undo magic quotes for " unless sybase is on - $sybase = ini_get('magic_quotes_sybase'); - if (!$sybase) { - $s = str_replace('\\"','"',$s); - if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything - return "'$s'"; - else {// change \' to '' for sybase/mssql - $s = str_replace('\\\\','\\',$s); - return "'".str_replace("\\'",$this->replaceQuote,$s)."'"; - } - } else { - return "'".$s."'"; + // undo magic quotes for " unless sybase is on + $sybase = ini_get('magic_quotes_sybase'); + if (!$sybase) { + $s = str_replace('\\"','"',$s); + if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything + return "'$s'"; + else {// change \' to '' for sybase/mssql + $s = str_replace('\\\\','\\',$s); + return "'".str_replace("\\'",$this->replaceQuote,$s)."'"; + } + } else { + return "'".$s."'"; } } // moodle change end - see readme_moodle.txt @@ -307,7 +307,9 @@ class ADODB_mssql extends ADOConnection { case 'A': $s .= "substring(convert(char(19),$col,0),18,2)"; break; - + case 'l': + $s .= "datename(dw,$col)"; + break; default: if ($ch == '\\') { $i++; @@ -325,8 +327,8 @@ class ADODB_mssql extends ADOConnection { { if ($this->transOff) return true; $this->transCnt += 1; - $ok = $this->Execute('BEGIN TRAN'); - return $ok; + $ok = $this->Execute('BEGIN TRAN'); + return $ok; } function CommitTrans($ok=true) @@ -449,29 +451,29 @@ class ADODB_mssql extends ADOConnection { global $ADODB_FETCH_MODE; $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - if ($this->fetchMode !== FALSE) { - $savem = $this->SetFetchMode(FALSE); - } + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->fetchMode !== FALSE) { + $savem = $this->SetFetchMode(FALSE); + } - $rs = $this->Execute($sql); - if (isset($savem)) { - $this->SetFetchMode($savem); - } - $ADODB_FETCH_MODE = $save; + $rs = $this->Execute($sql); + if (isset($savem)) { + $this->SetFetchMode($savem); + } + $ADODB_FETCH_MODE = $save; - if (!is_object($rs)) { - return FALSE; - } + if (!is_object($rs)) { + return FALSE; + } $indexes = array(); while ($row = $rs->FetchRow()) { if ($primary && !$row[5]) continue; - $indexes[$row[0]]['unique'] = $row[6]; - $indexes[$row[0]]['columns'][] = $row[1]; - } - return $indexes; + $indexes[$row[0]]['unique'] = $row[6]; + $indexes[$row[0]]['columns'][] = $row[1]; + } + return $indexes; } function MetaForeignKeys($table, $owner=false, $upper=false) @@ -486,7 +488,7 @@ class ADODB_mssql extends ADOConnection { "select object_name(constid) as constraint_name, col_name(fkeyid, fkey) as column_name, object_name(rkeyid) as referenced_table_name, - col_name(rkeyid, rkey) as referenced_column_name + col_name(rkeyid, rkey) as referenced_column_name from sysforeignkeys where upper(object_name(fkeyid)) = $table order by constraint_name, referenced_table_name, keyno"; @@ -517,22 +519,24 @@ order by constraint_name, referenced_table_name, keyno"; function MetaDatabases() { if(@mssql_select_db("master")) { - $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)) - return($ar); - else - return(false); - } else { - @mssql_select_db($this->database); - return(false); - } - } - return(false); + $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)) { + return($ar); + } else { + return(false); + } + } else { + @mssql_select_db($this->database); + return(false); + } + } + return(false); } // "Stein-Aksel Basma" <basma@accelero.no> @@ -605,14 +609,18 @@ order by constraint_name, referenced_table_name, keyno"; 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. 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 @@ order by constraint_name, referenced_table_name, keyno"; 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; @@ -637,9 +646,9 @@ order by constraint_name, referenced_table_name, keyno"; } function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename) - { + { return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true); - } + } function Prepare($sql) { @@ -664,28 +673,28 @@ order by constraint_name, referenced_table_name, keyno"; } // returns concatenated string - // MSSQL requires integers to be cast as strings - // automatically cast every datatype to VARCHAR(255) - // @author David Rogers (introspectshun) - function Concat() - { - $s = ""; - $arr = func_get_args(); + // MSSQL requires integers to be cast as strings + // automatically cast every datatype to VARCHAR(255) + // @author David Rogers (introspectshun) + function Concat() + { + $s = ""; + $arr = func_get_args(); - // Split single record on commas, if possible - if (sizeof($arr) == 1) { - foreach ($arr as $arg) { - $args = explode(',', $arg); - } - $arr = $args; - } + // Split single record on commas, if possible + if (sizeof($arr) == 1) { + foreach ($arr as $arg) { + $args = explode(',', $arg); + } + $arr = $args; + } - array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";')); - $s = implode('+',$arr); - if (sizeof($arr) > 0) return "$s"; + array_walk($arr, create_function('&$v', '$v = "CAST(" . $v . " AS VARCHAR(255))";')); + $s = implode('+',$arr); + if (sizeof($arr) > 0) return "$s"; return ''; - } + } /* Usage: @@ -773,11 +782,11 @@ order by constraint_name, referenced_table_name, keyno"; # bind input params with sp_executesql: # see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm # works only with sql server 7 and newer - $getIdentity = false; - if (!is_array($sql) && preg_match('/^\\s*insert/i', $sql)) { - $getIdentity = true; - $sql .= (preg_match('/;\\s*$/i', $sql) ? ' ' : '; ') . $this->identitySQL; - } + $getIdentity = false; + if (!is_array($sql) && preg_match('/^\\s*insert/i', $sql)) { + $getIdentity = true; + $sql .= (preg_match('/;\\s*$/i', $sql) ? ' ' : '; ') . $this->identitySQL; + } if (!is_array($sql)) $sql = $this->Prepare($sql); $params = ''; $decl = ''; @@ -817,20 +826,20 @@ order by constraint_name, referenced_table_name, keyno"; $decl = $this->qstr($decl); if ($this->debug) ADOConnection::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>"); $rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params", $this->_connectionID); - if ($getIdentity) { - $arr = @mssql_fetch_row($rez); - $this->lastInsID = isset($arr[0]) ? $arr[0] : false; - @mssql_data_seek($rez, 0); - } + if ($getIdentity) { + $arr = @mssql_fetch_row($rez); + $this->lastInsID = isset($arr[0]) ? $arr[0] : false; + @mssql_data_seek($rez, 0); + } } else if (is_array($sql)) { # PrepareSP() $rez = mssql_execute($sql[1]); - $this->lastInsID = false; + $this->lastInsID = false; } else { $rez = mssql_query($sql,$this->_connectionID); - $this->lastInsID = false; + $this->lastInsID = false; } return $rez; } @@ -838,8 +847,12 @@ order by constraint_name, referenced_table_name, keyno"; // 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,10 +867,36 @@ order by constraint_name, referenced_table_name, keyno"; { 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; + } } /*-------------------------------------------------------------------------------------- - Class Name: Recordset + Class Name: Recordset --------------------------------------------------------------------------------------*/ class ADORecordset_mssql extends ADORecordSet { @@ -878,7 +917,7 @@ class ADORecordset_mssql extends ADORecordSet { } $this->fetchMode = $mode; - return parent::__construct($id,$mode); + return parent::__construct($id); } @@ -914,7 +953,7 @@ class ADORecordset_mssql extends ADORecordSet { } } - return $this->fields[$this->bind[strtoupper($colname)]]; + return $this->fields[$this->bind[strtoupper($colname)]]; } /* Returns: an object containing field information. @@ -954,7 +993,7 @@ class ADORecordset_mssql extends ADORecordSet { } else { if ($this->hasFetchAssoc) {// only for PHP 4.2.0 or later - $this->fields = @mssql_fetch_assoc($this->_queryID); + $this->fields = @mssql_fetch_assoc($this->_queryID); } else { $flds = @mssql_fetch_array($this->_queryID); if (is_array($flds)) { @@ -1070,16 +1109,36 @@ class ADORecordset_mssql extends ADORecordSet { 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 + // mssql uses a default date like Dec 30 2000 12:00AM static function UnixDate($v) { @@ -1119,8 +1178,8 @@ class ADORecordSet_array_mssql extends ADORecordSet_array { global $ADODB_mssql_mths,$ADODB_mssql_date_order; //Dec 30 2000 12:00AM - if ($ADODB_mssql_date_order == 'dmy') { - if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|" + if ($ADODB_mssql_date_order == 'dmy') { + if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|" ,$v, $rr)) return parent::UnixTimeStamp($v); if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0; @@ -1156,11 +1215,11 @@ class ADORecordSet_array_mssql extends ADORecordSet_array { /* Code Example 1: -select object_name(constid) as constraint_name, - object_name(fkeyid) as table_name, - col_name(fkeyid, fkey) as column_name, +select object_name(constid) as constraint_name, + object_name(fkeyid) as table_name, + col_name(fkeyid, fkey) as column_name, object_name(rkeyid) as referenced_table_name, - col_name(rkeyid, rkey) as referenced_column_name + col_name(rkeyid, rkey) as referenced_column_name from sysforeignkeys where object_name(fkeyid) = x order by constraint_name, table_name, referenced_table_name, keyno diff --git a/drivers/adodb-mssql_n.inc.php b/drivers/adodb-mssql_n.inc.php index 2bbac5b2..d1768571 100644 --- a/drivers/adodb-mssql_n.inc.php +++ b/drivers/adodb-mssql_n.inc.php @@ -65,12 +65,12 @@ class ADODB_mssql_n extends ADODB_mssql { * and ODBTP) keeping SQL compatibility at ADOdb level (instead of hacking every project to add * the "N" notation when working against MSSQL. * - * The orginal note indicated that this hack should only be used if ALL the char-based columns + * The orginal note indicated that this hack should only be used if ALL the char-based columns * in your DB are of type nchar, nvarchar and ntext, but testing seems to indicate that SQL server * doesn't seem to care if the statement is used against char etc fields. * * @todo This function should raise an ADOdb error if one of the transformations fail - * + * * @param mixed $inboundData Either a string containing an SQL statement * or an array with resources from prepared statements * @@ -79,22 +79,22 @@ class ADODB_mssql_n extends ADODB_mssql { function _appendN($inboundData) { $inboundIsArray = false; - + if (is_array($inboundData)) { $inboundIsArray = true; $inboundArray = $inboundData; } else $inboundArray = (array)$inboundData; - + /* * All changes will be placed here */ $outboundArray = $inboundArray; - + foreach($inboundArray as $inboundKey=>$inboundValue) { - + if (is_resource($inboundValue)) { /* @@ -105,7 +105,7 @@ class ADODB_mssql_n extends ADODB_mssql { continue; } - + if (strpos($inboundValue, SINGLEQUOTE) === false) { /* @@ -120,11 +120,11 @@ class ADODB_mssql_n extends ADODB_mssql { * Check we haven't an odd number of single quotes (this can cause problems below * and should be considered one wrong SQL). Exit with debug info. */ - if ((substr_count($inboundValue, SINGLEQUOTE) & 1)) + if ((substr_count($inboundValue, SINGLEQUOTE) & 1)) { if ($this->debug) ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Wrong number of quotes (odd)"); - + break; } @@ -135,9 +135,9 @@ class ADODB_mssql_n extends ADODB_mssql { $regexp = '/(\\\\' . SINGLEQUOTE . '[^' . SINGLEQUOTE . '])/'; if (preg_match($regexp, $inboundValue)) { - if ($this->debug) + if ($this->debug) ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Found bad use of backslash + single quote"); - + break; } @@ -147,16 +147,16 @@ class ADODB_mssql_n extends ADODB_mssql { $pairs = array(); $regexp = '/(' . SINGLEQUOTE . SINGLEQUOTE . ')/'; preg_match_all($regexp, $inboundValue, $list_of_pairs); - + if ($list_of_pairs) { foreach (array_unique($list_of_pairs[0]) as $key=>$value) $pairs['<@#@#@PAIR-'.$key.'@#@#@>'] = $value; - - + + if (!empty($pairs)) $inboundValue = str_replace($pairs, array_keys($pairs), $inboundValue); - + } /* @@ -165,13 +165,13 @@ class ADODB_mssql_n extends ADODB_mssql { $literals = array(); $regexp = '/(N?' . SINGLEQUOTE . '.*?' . SINGLEQUOTE . ')/is'; preg_match_all($regexp, $inboundValue, $list_of_literals); - + if ($list_of_literals) { foreach (array_unique($list_of_literals[0]) as $key=>$value) $literals['<#@#@#LITERAL-'.$key.'#@#@#>'] = $value; - - + + if (!empty($literals)) $inboundValue = str_replace($literals, array_keys($literals), $inboundValue); } @@ -184,11 +184,11 @@ class ADODB_mssql_n extends ADODB_mssql { foreach ($literals as $key=>$value) { if (!is_numeric(trim($value, SINGLEQUOTE))) /* - * Non numeric string, prepend our dear N, whilst + * Non numeric string, prepend our dear N, whilst * Trimming potentially existing previous "N" */ - $literals[$key] = 'N' . trim($value, 'N'); - + $literals[$key] = 'N' . trim($value, 'N'); + } } @@ -197,7 +197,7 @@ class ADODB_mssql_n extends ADODB_mssql { */ if (!empty($literals)) $inboundValue = str_replace(array_keys($literals), $literals, $inboundValue); - + /* * Any pairs followed by N' must be switched to N' followed by those pairs @@ -210,40 +210,36 @@ class ADODB_mssql_n extends ADODB_mssql { */ if (!empty($pairs)) $inboundValue = str_replace(array_keys($pairs), $pairs, $inboundValue); - + /* * Print transformation if debug = on */ if (strcmp($inboundValue,$inboundArray[$inboundKey]) <> 0 && $this->debug) ADOConnection::outp("{$this->databaseType} internal transformation: {$inboundArray[$inboundKey]} to {$inboundValue}"); - + if (strcmp($inboundValue,$inboundArray[$inboundKey]) <> 0) /* * Place the transformed value into the outbound array */ $outboundArray[$inboundKey] = $inboundValue; } - + /* * Any transformations are in the $outboundArray */ if ($inboundIsArray) return $outboundArray; - + /* * We passed a string in originally */ return $outboundArray[0]; - + } } class ADORecordset_mssql_n extends ADORecordset_mssql { var $databaseType = "mssql_n"; - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-mssqlnative.inc.php b/drivers/adodb-mssqlnative.inc.php index 0be32990..f7b1e9f2 100644 --- a/drivers/adodb-mssqlnative.inc.php +++ b/drivers/adodb-mssqlnative.inc.php @@ -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. @@ -55,11 +55,11 @@ if (!function_exists('sqlsrv_log_set_subsystems')) { // MORE LOCALIZATION INFO // ---------------------- // To configure datetime, look for and modify sqlcommn.loc, -// typically found in c:\mssql\install +// typically found in c:\mssql\install // Also read : -// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918 +// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918 // Alternatively use: -// CONVERT(char(12),datecol,120) +// CONVERT(char(12),datecol,120) // // Also if your month is showing as month-1, // e.g. Jan 13, 2002 is showing as 13/0/2002, then see @@ -73,7 +73,7 @@ if (ADODB_PHPVER >= 0x4300) { // docs say 4.2.0, but testing shows only since 4.3.0 does it work! ini_set('mssql.datetimeconvert',0); } else { - global $ADODB_mssql_mths; // array, months must be upper-case + global $ADODB_mssql_mths; // array, months must be upper-case $ADODB_mssql_date_order = 'mdy'; $ADODB_mssql_mths = array( 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6, @@ -124,8 +124,10 @@ class ADODB_mssqlnative extends ADOConnection { 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 = ''; @@ -163,7 +165,7 @@ class ADODB_mssqlnative extends ADOConnection { } function ServerInfo() { - global $ADODB_FETCH_MODE; + global $ADODB_FETCH_MODE; static $arr = false; if (is_array($arr)) return $arr; @@ -189,11 +191,9 @@ class ADODB_mssqlnative extends ADOConnection { 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 @@ class ADODB_mssqlnative extends ADOConnection { } function GenID($seq='adodbseq',$start=1) { - if (!$this->mssql_version) - $this->ServerVersion(); switch($this->mssql_version){ case 9: case 10: @@ -219,9 +217,6 @@ class ADODB_mssqlnative extends ADOConnection { function CreateSequence($seq='adodbseq',$start=1) { - if (!$this->mssql_version) - $this->ServerVersion(); - switch($this->mssql_version){ case 9: case 10: @@ -231,7 +226,6 @@ class ADODB_mssqlnative extends ADOConnection { return $this->CreateSequence2012($seq, $start); break; } - } /** @@ -365,7 +359,9 @@ class ADODB_mssqlnative extends ADOConnection { 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 @@ class ADODB_mssqlnative extends ADOConnection { sqlsrv_commit($this->_connectionID); return true; } + function RollbackTrans() { if ($this->transOff) return true; @@ -473,22 +470,30 @@ class ADODB_mssqlnative extends ADOConnection { 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; - - foreach ($this->connectionParameters as $parameter=>$value) - $connectionInfo[$parameter] = $value; - + + $connectionInfo = $this->connectionInfo; + $connectionInfo["Database"] = $argDatabasename; + $connectionInfo["UID"] = $argUsername; + $connectionInfo["PWD"] = $argPassword; + + /* + * 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; } @@ -502,10 +507,6 @@ class ADODB_mssqlnative extends ADOConnection { 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 @@ -560,7 +561,8 @@ class ADODB_mssqlnative extends ADOConnection { { $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 @@ -568,7 +570,14 @@ class ADODB_mssqlnative extends ADOConnection { $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); @@ -576,23 +585,21 @@ class ADODB_mssqlnative extends ADOConnection { 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; } // 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; } @@ -665,7 +672,7 @@ class ADODB_mssqlnative extends ADOConnection { 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; @@ -747,7 +754,9 @@ class ADODB_mssqlnative extends ADOConnection { } 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(); @@ -755,10 +764,7 @@ class ADODB_mssqlnative extends ADOConnection { 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) { @@ -792,7 +798,7 @@ class ADODB_mssqlnative extends ADOConnection { $fld->type = $rs->fields[1]; $fld->max_length = $rs->fields[2]; $fld->precision = $rs->fields[3]; - $fld->scale = $rs->fields[4]; + $fld->scale = $rs->fields[4]; $fld->not_null =!$rs->fields[5]; $fld->has_default = $rs->fields[6]; $fld->xtype = $rs->fields[7]; @@ -803,7 +809,7 @@ class ADODB_mssqlnative extends ADOConnection { $fld->type = $rs->fields['type']; $fld->max_length = $rs->fields['length']; $fld->precision = $rs->fields['precision']; - $fld->scale = $rs->fields['scale']; + $fld->scale = $rs->fields['scale']; $fld->not_null =!$rs->fields['nullable']; $fld->has_default = $rs->fields['default_value']; $fld->xtype = $rs->fields['xtype']; @@ -820,16 +826,64 @@ class ADODB_mssqlnative extends ADOConnection { } $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; + } } /*-------------------------------------------------------------------------------------- - Class Name: Recordset + Class Name: Recordset --------------------------------------------------------------------------------------*/ class ADORecordset_mssqlnative extends ADORecordSet { @@ -839,6 +893,67 @@ class ADORecordset_mssqlnative extends ADORecordSet { 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) { @@ -847,29 +962,19 @@ class ADORecordset_mssqlnative extends ADORecordSet { } $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(); } @@ -901,79 +1006,74 @@ class ADORecordset_mssqlnative extends ADORecordSet { 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 - } - 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']] - ); + if ($this->fieldObjectsRetrieved){ + if ($this->fieldObjects) { + /* + * Already got the information + */ + if ($fieldOffset == -1) + return $this->fieldObjects; + else + 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']] - ); - } - } - $f = (object) $fb; + /* + * No metadata available + */ + return false; } - return $f; + + $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; + + } + if ($fieldOffset == -1) + return $this->fieldObjects; + + return $this->fieldObjects[$fieldOffset]; } /* @@ -981,12 +1081,16 @@ class ADORecordset_mssqlnative extends ADORecordSet { * 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) @@ -997,76 +1101,50 @@ class ADORecordset_mssqlnative extends ADORecordSet { // 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; - } - } - } - } else { - //# KMN # if ($this->connection->debug) ADOConnection::outp("fetch mode: num"); - $this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_NUMERIC); - } - if(is_array($this->fields) && array_key_exists(1,$this->fields) && !array_key_exists(0,$this->fields)) {//fix fetch numeric keys since they're not 0 based - $arrFixed = array(); - foreach($this->fields as $key=>$value) { - if(is_numeric($key)) { - $arrFixed[$key-1] = $value; - } else { - $arrFixed[$key] = $value; - } - } - //if($this->connection->debug) 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 (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); + } } - 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)); + else + $this->fields = @sqlsrv_fetch_array($this->_queryID,SQLSRV_FETCH_NUMERIC); + + 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)) { @@ -1091,12 +1169,8 @@ class ADORecordset_mssqlnative extends ADORecordSet { 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 + // mssql uses a default date like Dec 30 2000 12:00AM static function UnixDate($v) { @@ -1136,8 +1210,8 @@ class ADORecordSet_array_mssqlnative extends ADORecordSet_array { global $ADODB_mssql_mths,$ADODB_mssql_date_order; //Dec 30 2000 12:00AM - if ($ADODB_mssql_date_order == 'dmy') { - if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|" + if ($ADODB_mssql_date_order == 'dmy') { + if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|" ,$v, $rr)) return parent::UnixTimeStamp($v); if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0; diff --git a/drivers/adodb-mssqlpo.inc.php b/drivers/adodb-mssqlpo.inc.php index cd6a2850..2075514a 100644 --- a/drivers/adodb-mssqlpo.inc.php +++ b/drivers/adodb-mssqlpo.inc.php @@ -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 ADODB_mssqlpo extends ADODB_mssql { class ADORecordset_mssqlpo extends ADORecordset_mssql { var $databaseType = "mssqlpo"; - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-mysql.inc.php b/drivers/adodb-mysql.inc.php index 2d999c6b..159edca4 100644 --- a/drivers/adodb-mysql.inc.php +++ b/drivers/adodb-mysql.inc.php @@ -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. @@ -12,7 +12,7 @@ is deprected in PHP version 5.5 and removed in PHP version 7. It is deprecated as of ADOdb version 5.20.0. Use the mysqli driver instead, which supports both transactional and non-transactional updates - + Requires mysql client. Works on Windows and Unix. 28 Feb 2001: MetaColumns bug fix - suggested by Freek Dijkstra (phpeverywhere@macfreek.com) @@ -51,11 +51,6 @@ class ADODB_mysql extends ADOConnection { 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 @@ class ADORecordSet_mysql extends ADORecordSet{ 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,17 +863,13 @@ class ADORecordSet_mysql extends ADORecordSet{ if (!empty($fieldobj->primary_key)) return 'R'; else return 'I'; - default: return 'N'; + default: return ADODB_DEFAULT_METATYPE; } } } class ADORecordSet_ext_mysql extends ADORecordSet_mysql { - function __construct($queryID,$mode=false) - { - parent::__construct($queryID,$mode); - } function MoveNext() { diff --git a/drivers/adodb-mysqli.inc.php b/drivers/adodb-mysqli.inc.php index f9c7319c..82ad9af6 100644 --- a/drivers/adodb-mysqli.inc.php +++ b/drivers/adodb-mysqli.inc.php @@ -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. @@ -12,7 +12,7 @@ and non-transactional table types. You can use this as a drop-in replacement for both the mysql and mysqlt drivers. As of ADOdb Version 5.20.0, all other native MySQL drivers are deprecated - + Requires mysql client. Works on Windows and Unix. 21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl) @@ -29,9 +29,6 @@ if (! defined("_ADODB_MYSQLI_LAYER")) { 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 @@ class ADODB_mysqli extends ADOConnection { 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,10 +103,20 @@ class ADODB_mysqli extends ADOConnection { 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; @@ -254,10 +262,26 @@ class ADODB_mysqli extends ADOConnection { function _insertid() { - $result = @mysqli_insert_id($this->_connectionID); + /* + * 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 @@ class ADODB_mysqli extends ADOConnection { // "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; + global $ADODB_FETCH_MODE; + + 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) { - $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]; + + $this->setFetchMode($savem); + + $create_sql = isset($a_create_table["Create Table"]) ? $a_create_table["Create Table"] : $a_create_table["Create View"]; $matches = array(); @@ -727,6 +759,14 @@ class ADODB_mysqli extends ADOConnection { 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 @@ class ADODB_mysqli extends ADOConnection { 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 @@ class ADODB_mysqli extends ADOConnection { // returns true or false function _close() { - @mysqli_close($this->_connectionID); + if($this->_connectionID) { + mysqli_close($this->_connectionID); + } $this->_connectionID = false; } @@ -958,7 +1015,13 @@ class ADORecordSet_mysqli extends ADORecordSet{ // $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_mysqli extends ADORecordSet{ 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)) { diff --git a/drivers/adodb-mysqlpo.inc.php b/drivers/adodb-mysqlpo.inc.php index 26b354ae..cf430799 100644 --- a/drivers/adodb-mysqlpo.inc.php +++ b/drivers/adodb-mysqlpo.inc.php @@ -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. @@ -11,8 +11,8 @@ MySQL code that supports transactions. For MySQL 3.23 or later. Code from James Poon <jpoon88@yahoo.com> - - This driver extends the deprecated mysql driver, and was originally designed to be a + + This driver extends the deprecated mysql driver, and was originally designed to be a portable driver in the same manner as oci8po and mssqlpo. Its functionality is exactly duplicated in the mysqlt driver, which is itself deprecated. This driver will be removed in ADOdb version 6.0.0. @@ -32,11 +32,6 @@ class ADODB_mysqlt extends ADODB_mysql { 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_mysqlt extends ADORecordSet_mysql{ class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt { - function __construct($queryID,$mode=false) - { - parent::__construct($queryID,$mode); - } - function MoveNext() { return adodb_movenext($this); diff --git a/drivers/adodb-mysqlt.inc.php b/drivers/adodb-mysqlt.inc.php index 79c93760..c627643e 100644 --- a/drivers/adodb-mysqlt.inc.php +++ b/drivers/adodb-mysqlt.inc.php @@ -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. @@ -29,11 +29,6 @@ class ADODB_mysqlt extends ADODB_mysql { 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 diff --git a/drivers/adodb-netezza.inc.php b/drivers/adodb-netezza.inc.php index af3a1a11..398472ac 100644 --- a/drivers/adodb-netezza.inc.php +++ b/drivers/adodb-netezza.inc.php @@ -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 @@ class ADODB_netezza extends ADODB_postgres64 { // http://bugs.php.net/bug.php?id=25404 - function __construct() - { - - } - function MetaColumns($table,$upper=true) { @@ -141,11 +136,6 @@ class ADORecordSet_netezza extends ADORecordSet_postgres64 var $databaseType = "netezza"; var $canSeek = true; - function __construct($queryID,$mode=false) - { - parent::__construct($queryID,$mode); - } - // _initrs modified to disable blob handling function _initrs() { diff --git a/drivers/adodb-oci8.inc.php b/drivers/adodb-oci8.inc.php index 928d1b84..272a6625 100644 --- a/drivers/adodb-oci8.inc.php +++ b/drivers/adodb-oci8.inc.php @@ -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 @@ END; function __construct() { $this->_hasOciFetchStatement = ADODB_PHPVER >= 0x4200; - if (defined('ADODB_EXTENSION')) { - $this->rsPrefix .= 'ext_'; - } } /* function MetaColumns($table, $normalize=true) added by smondino@users.sourceforge.net*/ @@ -1743,7 +1740,8 @@ class ADORecordset_oci8 extends ADORecordSet { oci_free_cursor($this->_refcursor); $this->_refcursor = false; } - @oci_free_statement($this->_queryID); + if (is_resource($this->_queryID)) + @oci_free_statement($this->_queryID); $this->_queryID = false; } @@ -1800,16 +1798,12 @@ class ADORecordset_oci8 extends ADORecordSet { 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() { diff --git a/drivers/adodb-oci805.inc.php b/drivers/adodb-oci805.inc.php index 112e9ecc..77c242d7 100644 --- a/drivers/adodb-oci805.inc.php +++ b/drivers/adodb-oci805.inc.php @@ -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 ADODB_oci805 extends ADODB_oci8 { class ADORecordset_oci805 extends ADORecordset_oci8 { var $databaseType = "oci805"; - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-oci8po.inc.php b/drivers/adodb-oci8po.inc.php index 6b939b0a..e04e25b6 100644 --- a/drivers/adodb-oci8po.inc.php +++ b/drivers/adodb-oci8po.inc.php @@ -1,6 +1,6 @@ <?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 Released under both BSD license and Lesser GPL library license. @@ -33,7 +33,6 @@ class ADODB_oci8po extends ADODB_oci8 { function __construct() { $this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200; - # oci8po does not support adodb extension: adodb_movenext() } function Param($name,$type='C') @@ -114,11 +113,6 @@ class ADORecordset_oci8po extends ADORecordset_oci8 { var $databaseType = 'oci8po'; - function __construct($queryID,$mode=false) - { - parent::__construct($queryID,$mode); - } - function Fields($colname) { if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname]; diff --git a/drivers/adodb-oci8quercus.inc.php b/drivers/adodb-oci8quercus.inc.php index 1940e802..79e3d006 100644 --- a/drivers/adodb-oci8quercus.inc.php +++ b/drivers/adodb-oci8quercus.inc.php @@ -1,6 +1,6 @@ <?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 Released under both BSD license and Lesser GPL library license. @@ -28,10 +28,6 @@ class ADODB_oci8quercus extends ADODB_oci8 { var $databaseType = 'oci8quercus'; var $dataProvider = 'oci8'; - function __construct() - { - } - } /*-------------------------------------------------------------------------------------- @@ -42,11 +38,6 @@ class ADORecordset_oci8quercus extends ADORecordset_oci8 { var $databaseType = 'oci8quercus'; - function __construct($queryID,$mode=false) - { - parent::__construct($queryID,$mode); - } - function _FetchField($fieldOffset = -1) { global $QUERCUS; diff --git a/drivers/adodb-odbc.inc.php b/drivers/adodb-odbc.inc.php index efaa5bb1..3c6cbb2c 100644 --- a/drivers/adodb-odbc.inc.php +++ b/drivers/adodb-odbc.inc.php @@ -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. @@ -17,6 +17,18 @@ if (!defined('ADODB_DIR')) die(); 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); + /*-------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------*/ @@ -40,6 +52,11 @@ class ADODB_odbc extends ADOConnection { var $_has_stupid_odbc_fetch_api_change = true; 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() { @@ -463,7 +480,16 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/od if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { $fld = new ADOFieldObject(); $fld->name = $rs->fields[3]; - $fld->type = $this->ODBCTypes($rs->fields[4]); + 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 diff --git a/drivers/adodb-odbc_db2.inc.php b/drivers/adodb-odbc_db2.inc.php index fa6d8b84..3d032323 100644 --- a/drivers/adodb-odbc_db2.inc.php +++ b/drivers/adodb-odbc_db2.inc.php @@ -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. @@ -92,7 +92,7 @@ to DB2 full rights to the DB2 SQLLIB directory, and place the user in the DBUSER if (!defined('ADODB_DIR')) die(); if (!defined('_ADODB_ODBC_LAYER')) { - include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); + include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php"); } if (!defined('ADODB_ODBC_DB2')){ define('ADODB_ODBC_DB2',1); @@ -306,11 +306,6 @@ class ADORecordSet_odbc_db2 extends ADORecordSet_odbc { var $databaseType = "db2"; - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } - function MetaType($t,$len=-1,$fieldobj=false) { if (is_object($t)) { @@ -361,7 +356,7 @@ class ADORecordSet_odbc_db2 extends ADORecordSet_odbc { case 'I': return 'I'; - default: return 'N'; + default: return ADODB_DEFAULT_METATYPE; } } } diff --git a/drivers/adodb-odbc_mssql.inc.php b/drivers/adodb-odbc_mssql.inc.php index aa643168..974b3c95 100644 --- a/drivers/adodb-odbc_mssql.inc.php +++ b/drivers/adodb-odbc_mssql.inc.php @@ -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. @@ -18,7 +18,7 @@ Set tabs to 4 for best viewing. if (!defined('ADODB_DIR')) die(); if (!defined('_ADODB_ODBC_LAYER')) { - include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); + include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php"); } @@ -47,12 +47,6 @@ class ADODB_odbc_mssql extends ADODB_odbc { var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # When SET CONCAT_NULL_YIELDS_NULL is ON, # concatenating a null value with a string yields a NULL result - function __construct() - { - parent::__construct(); - //$this->curmode = SQL_CUR_USE_ODBC; - } - // crashes php... function ServerInfo() { @@ -349,6 +343,56 @@ order by constraint_name, referenced_table_name, keyno"; } return $s; } + + /** + * 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; + } } @@ -356,8 +400,4 @@ class ADORecordSet_odbc_mssql extends ADORecordSet_odbc { var $databaseType = 'odbc_mssql'; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-odbc_mssql2012.inc.php b/drivers/adodb-odbc_mssql2012.inc.php new file mode 100644 index 00000000..a3b7f69f --- /dev/null +++ b/drivers/adodb-odbc_mssql2012.inc.php @@ -0,0 +1,28 @@ +<?php +/* + @version v5.21.0-dev ??-???-2016 + @copyright (c) 2015 Damien Regad, Mark Newnham and the ADOdb community + Released under both BSD license and Lesser GPL library license. + Whenever there is any discrepancy between the two licenses, + the BSD license will take precedence. + Set tabs to 4. + + Microsoft SQL Server 2012 via ODBC +*/ + +if (!defined('ADODB_DIR')) + die(); + +include_once(ADODB_DIR."/drivers/adodb-odbc_mssql.inc.php"); + +class ADODB_odbc_mssql2012 extends ADODB_odbc_mssql +{ + /* + * Makes behavior similar to prior versions of SQL Server + */ + var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL ON'; +} + +class ADORecordSet_odbc_mssql2012 extends ADORecordSet_odbc_mssql +{ +}
\ No newline at end of file diff --git a/drivers/adodb-odbc_oracle.inc.php b/drivers/adodb-odbc_oracle.inc.php index dfa851c0..b594b60d 100644 --- a/drivers/adodb-odbc_oracle.inc.php +++ b/drivers/adodb-odbc_oracle.inc.php @@ -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. @@ -16,7 +16,7 @@ Set tabs to 4 for best viewing. if (!defined('ADODB_DIR')) die(); if (!defined('_ADODB_ODBC_LAYER')) { - include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); + include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php"); } @@ -104,8 +104,4 @@ class ADORecordSet_odbc_oracle extends ADORecordSet_odbc { var $databaseType = 'odbc_oracle'; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-odbtp.inc.php b/drivers/adodb-odbtp.inc.php index ec374a5d..fc1e32b4 100644 --- a/drivers/adodb-odbtp.inc.php +++ b/drivers/adodb-odbtp.inc.php @@ -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. @@ -35,10 +35,6 @@ class ADODB_odbtp extends ADOConnection{ var $_canPrepareSP = false; var $_dontPoolDBC = true; - function __construct() - { - } - function ServerInfo() { return array('description' => @odbtp_get_attr( ODB_ATTR_DBMSNAME, $this->_connectionID), @@ -793,48 +789,28 @@ class ADORecordSet_odbtp_mssql extends ADORecordSet_odbtp { var $databaseType = 'odbtp_mssql'; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } class ADORecordSet_odbtp_access extends ADORecordSet_odbtp { var $databaseType = 'odbtp_access'; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } class ADORecordSet_odbtp_vfp extends ADORecordSet_odbtp { var $databaseType = 'odbtp_vfp'; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } class ADORecordSet_odbtp_oci8 extends ADORecordSet_odbtp { var $databaseType = 'odbtp_oci8'; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } class ADORecordSet_odbtp_sybase extends ADORecordSet_odbtp { var $databaseType = 'odbtp_sybase'; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } } diff --git a/drivers/adodb-odbtp_unicode.inc.php b/drivers/adodb-odbtp_unicode.inc.php index 5ca03e71..22f93594 100644 --- a/drivers/adodb-odbtp_unicode.inc.php +++ b/drivers/adodb-odbtp_unicode.inc.php @@ -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. @@ -26,7 +26,7 @@ if (!defined('ADODB_DIR')) die(); */ if (!defined('_ADODB_ODBTP_LAYER')) { - include(ADODB_DIR."/drivers/adodb-odbtp.inc.php"); + include_once(ADODB_DIR."/drivers/adodb-odbtp.inc.php"); } class ADODB_odbtp_unicode extends ADODB_odbtp { diff --git a/drivers/adodb-oracle.inc.php b/drivers/adodb-oracle.inc.php index ca737d66..daf9c8f3 100644 --- a/drivers/adodb-oracle.inc.php +++ b/drivers/adodb-oracle.inc.php @@ -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. @@ -29,10 +29,6 @@ class ADODB_oracle extends ADOConnection { var $sysTimeStamp = 'SYSDATE'; var $connectSID = true; - function __construct() - { - } - // format and return date string in database date format function DBDate($d, $isfld = false) { diff --git a/drivers/adodb-pdo.inc.php b/drivers/adodb-pdo.inc.php index 41d5b98f..7eb4b3d2 100644 --- a/drivers/adodb-pdo.inc.php +++ b/drivers/adodb-pdo.inc.php @@ -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 @@ -87,10 +87,6 @@ class ADODB_pdo extends ADOConnection { var $stmt = false; var $_driver; - function __construct() - { - } - function _UpdatePDO() { $d = $this->_driver; @@ -102,6 +98,7 @@ class ADODB_pdo extends ADOConnection { $this->random = $d->random; $this->concat_operator = $d->concat_operator; $this->nameQuote = $d->nameQuote; + $this->arrayClass = $d->arrayClass; $this->hasGenID = $d->hasGenID; $this->_genIDSQL = $d->_genIDSQL; @@ -175,6 +172,16 @@ class ADODB_pdo extends ADOConnection { //$this->_connectionID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT ); $this->_connectionID->setAttribute(PDO::ATTR_CASE,$m); + // Now merge in any provided attributes for PDO + foreach ($this->connectionParameters as $options) { + foreach($options as $k=>$v) { + if ($this->debug) { + ADOconnection::outp('Setting attribute: ' . $k . ' to ' . $v); + } + $this->_connectionID->setAttribute($k,$v); + } + } + $class = 'ADODB_pdo_'.$this->dsnType; //$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true); switch($this->dsnType) { @@ -480,7 +487,9 @@ class ADODB_pdo extends ADOConnection { #adodb_backtrace(); #var_dump($this->_bindInputArray); if ($stmt) { - $this->_driver->debug = $this->debug; + if (isset($this->_driver)) { + $this->_driver->debug = $this->debug; + } if ($inputarr) { $ok = $stmt->execute($inputarr); } @@ -812,3 +821,5 @@ class ADORecordSet_pdo extends ADORecordSet { } } + +class ADORecordSet_array_pdo extends ADORecordSet_array {} diff --git a/drivers/adodb-pdo_mssql.inc.php b/drivers/adodb-pdo_mssql.inc.php index 219cf131..d4d16a8f 100644 --- a/drivers/adodb-pdo_mssql.inc.php +++ b/drivers/adodb-pdo_mssql.inc.php @@ -2,7 +2,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. diff --git a/drivers/adodb-pdo_mysql.inc.php b/drivers/adodb-pdo_mysql.inc.php index becfad9e..ca4f2727 100644 --- a/drivers/adodb-pdo_mysql.inc.php +++ b/drivers/adodb-pdo_mysql.inc.php @@ -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. @@ -201,6 +201,8 @@ class ADODB_pdo_mysql extends ADODB_pdo { // parameters use PostgreSQL convention, not MySQL function SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs=0) { + $nrows = (int) $nrows; + $offset = (int) $offset; $offsetStr =($offset>=0) ? "$offset," : ''; // jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220 if ($nrows < 0) { diff --git a/drivers/adodb-pdo_oci.inc.php b/drivers/adodb-pdo_oci.inc.php index 5bd462e3..7776440e 100644 --- a/drivers/adodb-pdo_oci.inc.php +++ b/drivers/adodb-pdo_oci.inc.php @@ -2,7 +2,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. diff --git a/drivers/adodb-pdo_pgsql.inc.php b/drivers/adodb-pdo_pgsql.inc.php index 9afe4b0e..d707d914 100644 --- a/drivers/adodb-pdo_pgsql.inc.php +++ b/drivers/adodb-pdo_pgsql.inc.php @@ -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. @@ -227,4 +227,64 @@ select viewname,'V' from pg_views where viewname like $mask"; } + function BeginTrans() + { + if (!$this->hasTransactions) { + return false; + } + if ($this->transOff) { + return true; + } + $this->transCnt += 1; + + return $this->_connectionID->beginTransaction(); + } + + function CommitTrans($ok = true) + { + if (!$this->hasTransactions) { + return false; + } + if ($this->transOff) { + return true; + } + if (!$ok) { + return $this->RollbackTrans(); + } + if ($this->transCnt) { + $this->transCnt -= 1; + } + $this->_autocommit = true; + + $ret = $this->_connectionID->commit(); + return $ret; + } + + function RollbackTrans() + { + if (!$this->hasTransactions) { + return false; + } + if ($this->transOff) { + return true; + } + if ($this->transCnt) { + $this->transCnt -= 1; + } + $this->_autocommit = true; + + $ret = $this->_connectionID->rollback(); + return $ret; + } + + function SetTransactionMode( $transaction_mode ) + { + $this->_transmode = $transaction_mode; + if (empty($transaction_mode)) { + $this->_connectionID->query('SET TRANSACTION ISOLATION LEVEL READ COMMITTED'); + return; + } + if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode; + $this->_connectionID->query("SET TRANSACTION ".$transaction_mode); + } } diff --git a/drivers/adodb-pdo_sqlite.inc.php b/drivers/adodb-pdo_sqlite.inc.php index d42c5191..a1a9cc68 100644 --- a/drivers/adodb-pdo_sqlite.inc.php +++ b/drivers/adodb-pdo_sqlite.inc.php @@ -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. diff --git a/drivers/adodb-pdo_sqlsrv.inc.php b/drivers/adodb-pdo_sqlsrv.inc.php index 869e8e18..7650000d 100644 --- a/drivers/adodb-pdo_sqlsrv.inc.php +++ b/drivers/adodb-pdo_sqlsrv.inc.php @@ -5,10 +5,10 @@ */ class ADODB_pdo_sqlsrv extends ADODB_pdo { - var $hasTop = 'top'; var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)'; var $sysTimeStamp = 'GetDate()'; + var $arrayClass = 'ADORecordSet_array_pdo_sqlsrv'; function _init(ADODB_pdo $parentDriver) { @@ -45,5 +45,136 @@ class ADODB_pdo_sqlsrv extends ADODB_pdo { return ADOConnection::ServerInfo(); } +} + +class ADORecordSet_pdo_sqlsrv extends ADORecordSet_pdo +{ + + public $databaseType = "pdo_sqlsrv"; + + /** + * returns the field object + * + * @param int $fieldOffset Optional field offset + * + * @return object The ADOFieldObject describing the field + */ + public function fetchField($fieldOffset = 0) + { + + static $fieldObjects = array(); + // Default behavior allows passing in of -1 offset, which crashes the method + if ($fieldOffset == -1) { + $fieldOffset++; + } + + if (isset($fieldObjects[$fieldOffset])) { + // Look for cached field offset + return $fieldObjects[$fieldOffset]; + } + + $o = new ADOFieldObject(); + $arr = @$this->_queryID->getColumnMeta($fieldOffset); + + if (!$arr) { + $o->name = 'bad getColumnMeta()'; + $o->max_length = -1; + $o->type = 'VARCHAR'; + $o->precision = 0; + return $o; + } + $o->name = $arr['name']; + if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") { + // Use the SQL Server driver specific value + $o->type = $arr['sqlsrv:decl_type']; + } else { + $o->type = adodb_pdo_type($arr['pdo_type']); + } + $o->max_length = $arr['len']; + $o->precision = $arr['precision']; + + switch (ADODB_ASSOC_CASE) { + case ADODB_ASSOC_CASE_LOWER: + $o->name = strtolower($o->name); + break; + case ADODB_ASSOC_CASE_UPPER: + $o->name = strtoupper($o->name); + break; + } + + // Add to the cache + $fieldObjects[$fieldOffset] = $o; + return $o; + } +} + +class ADORecordSet_array_pdo_sqlsrv extends ADORecordSet_array_pdo +{ + + /** + * returns the field object + * + * Note that this is a direct copy of the ADORecordSet_pdo_sqlsrv method + * + * @param int $fieldOffset Optional field offset + * + * @return object The ADOfieldobject describing the field + */ + public function fetchField($fieldOffset = 0) + { + static $fieldObjects = array(); + // Default behavior allows passing in of -1 offset, which crashes the method + if ($fieldOffset == -1) { + $fieldOffset++; + } + + if (isset($fieldObjects[$fieldOffset])) { + // Look for cached field offset + return $fieldObjects[$fieldOffset]; + } + $o = new ADOFieldObject(); + $arr = @$this->_queryID->getColumnMeta($fieldOffset); + + if (!$arr) { + $o->name = 'bad getColumnMeta()'; + $o->max_length = -1; + $o->type = 'VARCHAR'; + $o->precision = 0; + return $o; + } + $o->name = $arr['name']; + if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") { + // Use the SQL Server driver specific value + $o->type = $arr['sqlsrv:decl_type']; + } else { + $o->type = adodb_pdo_type($arr['pdo_type']); + } + $o->max_length = $arr['len']; + $o->precision = $arr['precision']; + + switch (ADODB_ASSOC_CASE) { + case ADODB_ASSOC_CASE_LOWER: + $o->name = strtolower($o->name); + break; + case ADODB_ASSOC_CASE_UPPER: + $o->name = strtoupper($o->name); + break; + } + + // Add to the cache + $fieldObjects[$fieldOffset] = $o; + return $o; + } + + function SetTransactionMode( $transaction_mode ) + { + $this->_transmode = $transaction_mode; + if (empty($transaction_mode)) { + $this->_connectionID->query('SET TRANSACTION ISOLATION LEVEL READ COMMITTED'); + return; + } + if (!stristr($transaction_mode,'isolation')) $transaction_mode = 'ISOLATION LEVEL '.$transaction_mode; + $this->_connectionID->query("SET TRANSACTION ".$transaction_mode); + } } diff --git a/drivers/adodb-postgres.inc.php b/drivers/adodb-postgres.inc.php index 3c866b72..784227d3 100644 --- a/drivers/adodb-postgres.inc.php +++ b/drivers/adodb-postgres.inc.php @@ -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. diff --git a/drivers/adodb-postgres64.inc.php b/drivers/adodb-postgres64.inc.php index 5fd27110..99d6d047 100644 --- a/drivers/adodb-postgres64.inc.php +++ b/drivers/adodb-postgres64.inc.php @@ -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. @@ -124,19 +124,40 @@ class ADODB_postgres64 extends ADOConnection{ // to know what the concequences are. The other values are correct (wheren't in 0.94) // -- Freek Dijkstra - function __construct() + /** + * Retrieve Server information. + * In addition to server version and desription, the function also returns + * the client version. + * @param bool $detailed If true, retrieve detailed version string (executes + * a SQL query) in addition to the version number + * @return array|bool Server info or false if version could not be retrieved + * e.g. if there is no active connection + */ + function ServerInfo($detailed = true) { - // changes the metaColumnsSQL, adds columns: attnum[6] - } + if (empty($this->version['version'])) { + // We don't have a connection, so we can't retrieve server info + if (!$this->_connectionID) { + return false; + } - function ServerInfo() - { - if (isset($this->version)) return $this->version; + $version = pg_version($this->_connectionID); + $this->version = array( + // If PHP has been compiled with PostgreSQL 7.3 or lower, then + // server version is not set so we use pg_parameter_status() + // which includes logic to obtain values server_version + 'version' => isset($version['server']) + ? $version['server'] + : pg_parameter_status($this->_connectionID, 'server_version'), + 'client' => $version['client'], + 'description' => null, + ); + } + if ($detailed && $this->version['description'] === null) { + $this->version['description'] = $this->GetOne('select version()'); + } - $arr['description'] = $this->GetOne("select version()"); - $arr['version'] = ADOConnection::_findvers($arr['description']); - $this->version = $arr; - return $arr; + return $this->version; } function IfNull( $field, $ifNull ) @@ -430,13 +451,17 @@ class ADODB_postgres64 extends ADOConnection{ return $realblob; } - /* - See http://www.postgresql.org/idocs/index.php?datatype-binary.html - - NOTE: SQL string literals (input strings) must be preceded with two backslashes - due to the fact that they must pass through two parsers in the PostgreSQL - backend. - */ + /** + * Encode binary value prior to DB storage. + * + * See https://www.postgresql.org/docs/current/static/datatype-binary.html + * + * NOTE: SQL string literals (input strings) must be preceded with two + * backslashes due to the fact that they must pass through two parsers in + * the PostgreSQL backend. + * + * @param string $blob + */ function BlobEncode($blob) { if (ADODB_PHPVER >= 0x5200) return pg_escape_bytea($this->_connectionID, $blob); @@ -729,9 +754,9 @@ class ADODB_postgres64 extends ADOConnection{ if ($this->_connectionID === false) return false; $this->Execute("set datestyle='ISO'"); - $info = $this->ServerInfo(); - $this->pgVersion = (float) substr($info['version'],0,3); - if ($this->pgVersion >= 7.1) { // good till version 999 + $info = $this->ServerInfo(false); + + if (version_compare($info['version'], '7.1', '>=')) { $this->_nestedSQL = true; } @@ -739,8 +764,11 @@ class ADODB_postgres64 extends ADOConnection{ # PHP does not handle 'hex' properly ('x74657374' is returned as 't657374') # https://bugs.php.net/bug.php?id=59831 states this is in fact not a bug, # so we manually set bytea_output - if ( !empty($this->connection->noBlobs) && version_compare($info['version'], '9.0', '>=')) { - $this->Execute('set bytea_output=escape'); + if (!empty($this->connection->noBlobs) && version_compare($info['version'], '9.0', '>=')) { + $version = pg_version($this->connectionID); + if (version_compare($info['client'], '9.2', '<')) { + $this->Execute('set bytea_output=escape'); + } } return true; @@ -1068,6 +1096,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{ case 'NAME': case 'BPCHAR': case '_VARCHAR': + case 'CIDR': case 'INET': case 'MACADDR': if ($len <= $this->blobSize) return 'C'; @@ -1111,7 +1140,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{ return 'R'; default: - return 'N'; + return ADODB_DEFAULT_METATYPE; } } diff --git a/drivers/adodb-postgres7.inc.php b/drivers/adodb-postgres7.inc.php index ebdf2acf..9fc73213 100644 --- a/drivers/adodb-postgres7.inc.php +++ b/drivers/adodb-postgres7.inc.php @@ -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. @@ -307,12 +307,6 @@ class ADORecordSet_postgres7 extends ADORecordSet_postgres64{ var $databaseType = "postgres7"; - - function __construct($queryID, $mode=false) - { - parent::__construct($queryID, $mode); - } - // 10% speedup to move MoveNext to child class function MoveNext() { @@ -339,11 +333,6 @@ class ADORecordSet_assoc_postgres7 extends ADORecordSet_postgres64{ var $databaseType = "postgres7"; - function __construct($queryID, $mode=false) - { - parent::__construct($queryID, $mode); - } - function _fetch() { if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0) { diff --git a/drivers/adodb-postgres8.inc.php b/drivers/adodb-postgres8.inc.php index 54b14abb..8c7253e0 100644 --- a/drivers/adodb-postgres8.inc.php +++ b/drivers/adodb-postgres8.inc.php @@ -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. diff --git a/drivers/adodb-postgres9.inc.php b/drivers/adodb-postgres9.inc.php index fb589188..86cd1b7a 100644 --- a/drivers/adodb-postgres9.inc.php +++ b/drivers/adodb-postgres9.inc.php @@ -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. diff --git a/drivers/adodb-proxy.inc.php b/drivers/adodb-proxy.inc.php index 4004fa78..ed53195d 100644 --- a/drivers/adodb-proxy.inc.php +++ b/drivers/adodb-proxy.inc.php @@ -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. @@ -15,19 +15,16 @@ if (!defined('ADODB_DIR')) die(); if (! defined("_ADODB_PROXY_LAYER")) { - define("_ADODB_PROXY_LAYER", 1 ); - include(ADODB_DIR."/drivers/adodb-csv.inc.php"); + define("_ADODB_PROXY_LAYER", 1 ); + include_once(ADODB_DIR."/drivers/adodb-csv.inc.php"); - class ADODB_proxy extends ADODB_csv { - var $databaseType = 'proxy'; - var $databaseProvider = 'csv'; - } - class ADORecordset_proxy extends ADORecordset_csv { +class ADODB_proxy extends ADODB_csv { + var $databaseType = 'proxy'; + var $databaseProvider = 'csv'; +} + +class ADORecordset_proxy extends ADORecordset_csv { var $databaseType = "proxy"; +} - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } - }; } // define diff --git a/drivers/adodb-sapdb.inc.php b/drivers/adodb-sapdb.inc.php index a11e7e06..a25491f7 100644 --- a/drivers/adodb-sapdb.inc.php +++ b/drivers/adodb-sapdb.inc.php @@ -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. @@ -18,7 +18,7 @@ Set tabs to 4 for best viewing. if (!defined('ADODB_DIR')) die(); if (!defined('_ADODB_ODBC_LAYER')) { - include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); + include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php"); } if (!defined('ADODB_SAPDB')){ define('ADODB_SAPDB',1); @@ -33,12 +33,6 @@ class ADODB_SAPDB extends ADODB_odbc { var $hasInsertId = true; var $_bindInputArray = true; - function __construct() - { - //if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC; - parent::__construct(); - } - function ServerInfo() { $info = ADODB_odbc::ServerInfo(); @@ -55,7 +49,7 @@ class ADODB_SAPDB extends ADODB_odbc { return $this->GetCol("SELECT columnname FROM COLUMNS WHERE tablename=$table AND mode='KEY' ORDER BY pos"); } - function MetaIndexes ($table, $primary = FALSE, $owner = false) + function MetaIndexes ($table, $primary = FALSE, $owner = false) { $table = $this->Quote(strtoupper($table)); @@ -65,43 +59,43 @@ class ADODB_SAPDB extends ADODB_odbc { global $ADODB_FETCH_MODE; $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - if ($this->fetchMode !== FALSE) { - $savem = $this->SetFetchMode(FALSE); - } + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->fetchMode !== FALSE) { + $savem = $this->SetFetchMode(FALSE); + } - $rs = $this->Execute($sql); - if (isset($savem)) { - $this->SetFetchMode($savem); - } - $ADODB_FETCH_MODE = $save; + $rs = $this->Execute($sql); + if (isset($savem)) { + $this->SetFetchMode($savem); + } + $ADODB_FETCH_MODE = $save; - if (!is_object($rs)) { - return FALSE; - } + if (!is_object($rs)) { + return FALSE; + } $indexes = array(); while ($row = $rs->FetchRow()) { - $indexes[$row[0]]['unique'] = $row[1] == 'UNIQUE'; - $indexes[$row[0]]['columns'][] = $row[2]; - } + $indexes[$row[0]]['unique'] = $row[1] == 'UNIQUE'; + $indexes[$row[0]]['columns'][] = $row[2]; + } if ($primary) { $indexes['SYSPRIMARYKEYINDEX'] = array( 'unique' => True, // by definition 'columns' => $this->GetCol("SELECT columnname FROM COLUMNS WHERE tablename=$table AND mode='KEY' ORDER BY pos"), ); } - return $indexes; + return $indexes; } function MetaColumns ($table, $normalize = true) { global $ADODB_FETCH_MODE; $save = $ADODB_FETCH_MODE; - $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - if ($this->fetchMode !== FALSE) { - $savem = $this->SetFetchMode(FALSE); - } + $ADODB_FETCH_MODE = ADODB_FETCH_NUM; + if ($this->fetchMode !== FALSE) { + $savem = $this->SetFetchMode(FALSE); + } $table = $this->Quote(strtoupper($table)); $retarr = array(); @@ -134,10 +128,10 @@ class ADODB_SAPDB extends ADODB_odbc { } $retarr[$fld->name] = $fld; } - if (isset($savem)) { - $this->SetFetchMode($savem); - } - $ADODB_FETCH_MODE = $save; + if (isset($savem)) { + $this->SetFetchMode($savem); + } + $ADODB_FETCH_MODE = $save; return $retarr; } @@ -158,13 +152,13 @@ class ADODB_SAPDB extends ADODB_odbc { /* SelectLimit implementation problems: - The following will return random 10 rows as order by performed after "WHERE rowno<10" - which is not ideal... + The following will return random 10 rows as order by performed after "WHERE rowno<10" + which is not ideal... - select * from table where rowno < 10 order by 1 + select * from table where rowno < 10 order by 1 - This means that we have to use the adoconnection base class SelectLimit when - there is an "order by". + This means that we have to use the adoconnection base class SelectLimit when + there is an "order by". See http://listserv.sap.com/pipermail/sapdb.general/2002-January/010405.html */ @@ -172,14 +166,10 @@ class ADODB_SAPDB extends ADODB_odbc { }; -class ADORecordSet_sapdb extends ADORecordSet_odbc { +class ADORecordSet_sapdb extends ADORecordSet_odbc { var $databaseType = "sapdb"; - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } } } //define diff --git a/drivers/adodb-sqlanywhere.inc.php b/drivers/adodb-sqlanywhere.inc.php index 03a9da2a..8b8d9cb2 100644 --- a/drivers/adodb-sqlanywhere.inc.php +++ b/drivers/adodb-sqlanywhere.inc.php @@ -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 @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community reserved. @@ -47,7 +47,7 @@ Set tabs to 4 for best viewing. if (!defined('ADODB_DIR')) die(); if (!defined('_ADODB_ODBC_LAYER')) { - include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); + include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php"); } if (!defined('ADODB_SYBASE_SQLANYWHERE')){ @@ -153,11 +153,6 @@ if (!defined('ADODB_SYBASE_SQLANYWHERE')){ var $databaseType = "sqlanywhere"; - function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } - }; //class diff --git a/drivers/adodb-sqlite.inc.php b/drivers/adodb-sqlite.inc.php index 5cc6b9ea..05335f34 100644 --- a/drivers/adodb-sqlite.inc.php +++ b/drivers/adodb-sqlite.inc.php @@ -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,10 +33,6 @@ class ADODB_sqlite extends ADOConnection { var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')"; var $fmtTimeStamp = "'Y-m-d H:i:s'"; - function __construct() - { - } - function ServerInfo() { $arr['version'] = sqlite_libversion(); @@ -353,6 +349,63 @@ class ADODB_sqlite extends ADOConnection { return $indexes; } + /** + * Returns the maximum size of a MetaType C field. Because of the + * database design, sqlite places no limits on the size of data inserted + * + * @return int + */ + function charMax() + { + return ADODB_STRINGMAX_NOLIMIT; + } + + /** + * Returns the maximum size of a MetaType X field. Because of the + * database design, sqlite places no limits on the size of data inserted + * + * @return int + */ + function textMax() + { + return ADODB_STRINGMAX_NOLIMIT; + } + + /* + * Converts a date to a month only field and pads it to 2 characters + * + * @param str $fld The name of the field to process + * @return str The SQL Statement + */ + function month($fld) + { + $x = "strftime('%m',$fld)"; + + return $x; + } + + /* + * Converts a date to a day only field and pads it to 2 characters + * + * @param str $fld The name of the field to process + * @return str The SQL Statement + */ + function day($fld) { + $x = "strftime('%d',$fld)"; + return $x; + } + + /* + * Converts a date to a year only field + * + * @param str $fld The name of the field to process + * @return str The SQL Statement + */ + function year($fld) { + $x = "strftime('%Y',$fld)"; + + return $x; + } } /*-------------------------------------------------------------------------------------- diff --git a/drivers/adodb-sqlite3.inc.php b/drivers/adodb-sqlite3.inc.php index 7600c3a9..d38d5104 100644 --- a/drivers/adodb-sqlite3.inc.php +++ b/drivers/adodb-sqlite3.inc.php @@ -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,10 +33,6 @@ class ADODB_sqlite3 extends ADOConnection { var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')"; var $fmtTimeStamp = "'Y-m-d H:i:s'"; - function __construct() - { - } - function ServerInfo() { $version = SQLite3::version(); @@ -82,6 +78,73 @@ class ADODB_sqlite3 extends ADOConnection { return !empty($ret); } + function metaType($t,$len=-1,$fieldobj=false) + { + + if (is_object($t)) + { + $fieldobj = $t; + $t = $fieldobj->type; + $len = $fieldobj->max_length; + } + + $t = strtoupper($t); + + /* + * We are using the Sqlite affinity method here + * @link https://www.sqlite.org/datatype3.html + */ + $affinity = array( + 'INT'=>'INTEGER', + 'INTEGER'=>'INTEGER', + 'TINYINT'=>'INTEGER', + 'SMALLINT'=>'INTEGER', + 'MEDIUMINT'=>'INTEGER', + 'BIGINT'=>'INTEGER', + 'UNSIGNED BIG INT'=>'INTEGER', + 'INT2'=>'INTEGER', + 'INT8'=>'INTEGER', + + 'CHARACTER'=>'TEXT', + 'VARCHAR'=>'TEXT', + 'VARYING CHARACTER'=>'TEXT', + 'NCHAR'=>'TEXT', + 'NATIVE CHARACTER'=>'TEXT', + 'NVARCHAR'=>'TEXT', + 'TEXT'=>'TEXT', + 'CLOB'=>'TEXT', + + 'BLOB'=>'BLOB', + + 'REAL'=>'REAL', + 'DOUBLE'=>'REAL', + 'DOUBLE PRECISION'=>'REAL', + 'FLOAT'=>'REAL', + + 'NUMERIC'=>'NUMERIC', + 'DECIMAL'=>'NUMERIC', + 'BOOLEAN'=>'NUMERIC', + 'DATE'=>'NUMERIC', + 'DATETIME'=>'NUMERIC' + ); + + if (!isset($affinity[$t])) + return ADODB_DEFAULT_METATYPE; + + $subt = $affinity[$t]; + /* + * Now that we have subclassed the provided data down + * the sqlite 'affinity', we convert to ADOdb metatype + */ + + $subclass = array('INTEGER'=>'I', + 'TEXT'=>'X', + 'BLOB'=>'B', + 'REAL'=>'N', + 'NUMERIC'=>'N'); + + return $subclass[$subt]; + } // mark newnham function MetaColumns($table, $normalize=true) { @@ -129,6 +192,60 @@ class ADODB_sqlite3 extends ADOConnection { return $arr; } + 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; + + /* + * Read sqlite master to find foreign keys + */ + $sql = "SELECT sql + FROM ( + SELECT sql sql, type type, tbl_name tbl_name, name name + FROM sqlite_master + ) + WHERE type != 'meta' + AND sql NOTNULL + AND LOWER(name) ='" . strtolower($table) . "'"; + + $tableSql = $this->getOne($sql); + + $fkeyList = array(); + $ylist = preg_split("/,+/",$tableSql); + foreach ($ylist as $y) + { + if (!preg_match('/FOREIGN/',$y)) + continue; + + $matches = false; + preg_match_all('/\((.+?)\)/i',$y,$matches); + $tmatches = false; + preg_match_all('/REFERENCES (.+?)\(/i',$y,$tmatches); + + if ($associative) + { + if (!isset($fkeyList[$tmatches[1][0]])) + $fkeyList[$tmatches[1][0]] = array(); + $fkeyList[$tmatches[1][0]][$matches[1][0]] = $matches[1][1]; + } + else + $fkeyList[$tmatches[1][0]][] = $matches[1][0] . '=' . $matches[1][1]; + } + + if ($associative) + { + if ($upper) + $fkeyList = array_change_key_case($fkeyList,CASE_UPPER); + else + $fkeyList = array_change_key_case($fkeyList,CASE_LOWER); + } + return $fkeyList; + } + + function _init($parentDriver) { $parentDriver->hasTransactions = false; @@ -160,11 +277,22 @@ class ADODB_sqlite3 extends ADOConnection { function SQLDate($fmt, $col=false) { + /* + * In order to map the values correctly, we must ensure the proper + * casing for certain fields + * Y must be UC, because y is a 2 digit year + * d must be LC, because D is 3 char day + * A must be UC because a is non-portable am + * Q must be UC because q means nothing + */ + $fromChars = array('y','D','a','q'); + $toChars = array('Y','d','A','Q'); + $fmt = str_replace($fromChars,$toChars,$fmt); + $fmt = $this->qstr($fmt); return ($col) ? "adodb_date2($fmt,$col)" : "adodb_date($fmt)"; } - function _createFunctions() { $this->_connectionID->createFunction('adodb_date', 'adodb_date', 1); @@ -297,7 +425,7 @@ class ADODB_sqlite3 extends ADOConnection { if ($this->fetchMode !== FALSE) { $savem = $this->SetFetchMode(FALSE); } - $SQL=sprintf("SELECT name,sql FROM sqlite_master WHERE type='index' AND tbl_name='%s'", strtolower($table)); + $SQL=sprintf("SELECT name,sql FROM sqlite_master WHERE type='index' AND LOWER(tbl_name)='%s'", strtolower($table)); $rs = $this->Execute($SQL); if (!is_object($rs)) { if (isset($savem)) { @@ -336,6 +464,72 @@ class ADODB_sqlite3 extends ADOConnection { return $indexes; } + /** + * Returns the maximum size of a MetaType C field. Because of the + * database design, sqlite places no limits on the size of data inserted + * + * @return int + */ + function charMax() + { + return ADODB_STRINGMAX_NOLIMIT; + } + + /** + * Returns the maximum size of a MetaType X field. Because of the + * database design, sqlite places no limits on the size of data inserted + * + * @return int + */ + function textMax() + { + return ADODB_STRINGMAX_NOLIMIT; + } + + /** + * Converts a date to a month only field and pads it to 2 characters + * + * This uses the more efficient strftime native function to process + * + * @param str $fld The name of the field to process + * + * @return str The SQL Statement + */ + function month($fld) + { + $x = "strftime('%m',$fld)"; + return $x; + } + + /** + * Converts a date to a day only field and pads it to 2 characters + * + * This uses the more efficient strftime native function to process + * + * @param str $fld The name of the field to process + * + * @return str The SQL Statement + */ + function day($fld) { + $x = "strftime('%d',$fld)"; + return $x; + } + + /** + * Converts a date to a year only field + * + * This uses the more efficient strftime native function to process + * + * @param str $fld The name of the field to process + * + * @return str The SQL Statement + */ + function year($fld) + { + $x = "strftime('%Y',$fld)"; + return $x; + } + } /*-------------------------------------------------------------------------------------- diff --git a/drivers/adodb-sqlitepo.inc.php b/drivers/adodb-sqlitepo.inc.php index b167e8c8..f9c99835 100644 --- a/drivers/adodb-sqlitepo.inc.php +++ b/drivers/adodb-sqlitepo.inc.php @@ -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. @@ -35,11 +35,6 @@ class ADORecordset_sqlitepo extends ADORecordset_sqlite { var $databaseType = 'sqlitepo'; - function __construct($queryID,$mode=false) - { - parent::__construct($queryID,$mode); - } - // Modified to strip table names from returned fields function _fetch($ignore_fields=false) { diff --git a/drivers/adodb-sybase.inc.php b/drivers/adodb-sybase.inc.php index e7735550..52e7ecb7 100644 --- a/drivers/adodb-sybase.inc.php +++ b/drivers/adodb-sybase.inc.php @@ -1,6 +1,6 @@ <?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 Released under both BSD license and Lesser GPL library license. @@ -44,10 +44,6 @@ class ADODB_sybase extends ADOConnection { var $port; - function __construct() - { - } - // might require begintrans -- committrans function _insertid() { @@ -318,7 +314,7 @@ class ADORecordset_sybase extends ADORecordSet { } if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC; else $this->fetchMode = $mode; - parent::__construct($id,$mode); + parent::__construct($id); } /* Returns: an object containing field information. @@ -391,12 +387,8 @@ class ADORecordset_sybase extends ADORecordSet { } class ADORecordSet_array_sybase extends ADORecordSet_array { - function __construct($id=-1) - { - parent::__construct($id); - } - // sybase/mssql uses a default date like Dec 30 2000 12:00AM + // sybase/mssql uses a default date like Dec 30 2000 12:00AM static function UnixDate($v) { global $ADODB_sybase_mths; diff --git a/drivers/adodb-sybase_ase.inc.php b/drivers/adodb-sybase_ase.inc.php index 669dd22f..13211f5c 100644 --- a/drivers/adodb-sybase_ase.inc.php +++ b/drivers/adodb-sybase_ase.inc.php @@ -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. @@ -22,10 +22,6 @@ class ADODB_sybase_ase extends ADODB_sybase { var $metaColumnsSQL = "SELECT syscolumns.name AS field_name, systypes.name AS type, systypes.length AS width FROM sysobjects, syscolumns, systypes WHERE sysobjects.name='%s' AND syscolumns.id = sysobjects.id AND systypes.type=syscolumns.type"; var $metaDatabasesSQL ="SELECT a.name FROM master.dbo.sysdatabases a, master.dbo.syslogins b WHERE a.suid = b.suid and a.name like '%' and a.name != 'tempdb' and a.status3 != 256 order by 1"; - function __construct() - { - } - // split the Views, Tables and procedures. function MetaTables($ttype=false,$showSchema=false,$mask=false) { @@ -111,10 +107,5 @@ class ADODB_sybase_ase extends ADODB_sybase { } class adorecordset_sybase_ase extends ADORecordset_sybase { -var $databaseType = "sybase_ase"; -function __construct($id,$mode=false) - { - parent::__construct($id,$mode); - } - + var $databaseType = "sybase_ase"; } diff --git a/drivers/adodb-text.inc.php b/drivers/adodb-text.inc.php index 347167a7..b9a588d4 100644 --- a/drivers/adodb-text.inc.php +++ b/drivers/adodb-text.inc.php @@ -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 Set tabs to 4. @@ -90,10 +90,6 @@ class ADODB_text extends ADOConnection { var $_reznames; var $_reztypes; - function __construct() - { - } - function RSRecordCount() { if (!empty($this->_rezarray)) return sizeof($this->_rezarray); @@ -209,7 +205,7 @@ class ADODB_text extends ADOConnection { $where_arr = array(); reset($this->_origarray); - while (list($k_arr,$arr) = each($this->_origarray)) { + foreach ($this->_origarray as $arr) { if ($i == 0 && $this->_skiprow1) $where_arr[] = $arr; @@ -247,7 +243,7 @@ class ADODB_text extends ADOConnection { $i = 0; $n = ''; reset($this->_colnames); - while (list($k_n,$n) = each($this->_colnames)) { + foreach ($this->_colnames as $n) { if ($col == strtoupper(trim($n))) break; $i += 1; @@ -302,7 +298,7 @@ class ADODB_text extends ADOConnection { if ($at == 0) { $i = 0; reset($projnames); - while (list($k_n,$n) = each($projnames)) { + foreach ($projnames as $n) { if (strtoupper(trim($n)) == $col) { $at = $i+1; break; diff --git a/drivers/adodb-vfp.inc.php b/drivers/adodb-vfp.inc.php index 840c9c10..545c468b 100644 --- a/drivers/adodb-vfp.inc.php +++ b/drivers/adodb-vfp.inc.php @@ -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. @@ -17,7 +17,7 @@ Set tabs to 4 for best viewing. if (!defined('ADODB_DIR')) die(); if (!defined('_ADODB_ODBC_LAYER')) { - include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); + include_once(ADODB_DIR."/drivers/adodb-odbc.inc.php"); } if (!defined('ADODB_VFP')){ define('ADODB_VFP',1); @@ -69,11 +69,6 @@ class ADORecordSet_vfp extends ADORecordSet_odbc { var $databaseType = "vfp"; - function __construct($id,$mode=false) - { - return parent::__construct($id,$mode); - } - function MetaType($t, $len = -1, $fieldobj = false) { if (is_object($t)) { @@ -95,7 +90,7 @@ class ADORecordSet_vfp extends ADORecordSet_odbc { case 'I': return 'I'; - default: return 'N'; + default: return ADODB_DEFAULT_METATYPE; } } } diff --git a/lang/adodb-id.inc.php b/lang/adodb-id.inc.php new file mode 100644 index 00000000..f5344c63 --- /dev/null +++ b/lang/adodb-id.inc.php @@ -0,0 +1,36 @@ +<?php +# Indonesian language +# Bambang Riswanto <bamz3r@gmail.com> +$ADODB_LANG_ARRAY = array ( + 'LANG' => 'id', + DB_ERROR => 'kesalahan tidak diketahui', + DB_ERROR_ALREADY_EXISTS => 'sudah ada', + DB_ERROR_CANNOT_CREATE => 'tak dapat membuat', + DB_ERROR_CANNOT_DELETE => 'tak dapat menghapus', + DB_ERROR_CANNOT_DROP => 'tak dapat menghapus', + DB_ERROR_CONSTRAINT => 'pelanggaran kendala', + DB_ERROR_DIVZERO => 'pembagian dengan 0', + DB_ERROR_INVALID => 'tidak sah', + DB_ERROR_INVALID_DATE => 'tanggal atau waktu tidak valid', + DB_ERROR_INVALID_NUMBER => 'nomor tidak sah', + DB_ERROR_MISMATCH => 'tak cocok', + DB_ERROR_NODBSELECTED => 'tak ada database dipilih', + DB_ERROR_NOSUCHFIELD => 'kolom tak ditemukan', + DB_ERROR_NOSUCHTABLE => 'tabel tak ditemukan', + DB_ERROR_NOT_CAPABLE => 'kemampuan DB tak memadai', + DB_ERROR_NOT_FOUND => 'tidak ditemukan', + DB_ERROR_NOT_LOCKED => 'tidak terkunci', + DB_ERROR_SYNTAX => 'kesalahan sintak', + DB_ERROR_UNSUPPORTED => 'tak didukung', + DB_ERROR_VALUE_COUNT_ON_ROW => 'menghitung isi pada baris', + DB_ERROR_INVALID_DSN => 'DSN tidak sah', + DB_ERROR_CONNECT_FAILED => 'koneksi gagal', + 0 => 'tak ada kesalahan', // DB_OK + DB_ERROR_NEED_MORE_DATA => 'data yang dimasukan tidak memadai', + DB_ERROR_EXTENSION_NOT_FOUND=> 'ekstensi tak ditemukan', + DB_ERROR_NOSUCHDB => 'database tak ditemukan', + DB_ERROR_ACCESS_VIOLATION => 'izin tidak memadai', + DB_ERROR_DEADLOCK => 'kebuntuan terdeteksi', + DB_ERROR_STATEMENT_TIMEOUT => 'perintah kehabisan waktu', + DB_ERROR_SERIALIZATION_FAILURE => 'tak dapat melanjutkan akses' +); diff --git a/lang/adodb-oc.inc.php b/lang/adodb-oc.inc.php new file mode 100644 index 00000000..d62b67b3 --- /dev/null +++ b/lang/adodb-oc.inc.php @@ -0,0 +1,31 @@ +<?php +$ADODB_LANG_ARRAY = array ( + 'LANG' => 'oc', + DB_ERROR => 'error desconeguda', + DB_ERROR_ALREADY_EXISTS => 'existÃs ja', + DB_ERROR_CANNOT_CREATE => 'creacion impossibla', + DB_ERROR_CANNOT_DELETE => 'escafament impossible', + DB_ERROR_CANNOT_DROP => 'supression impossibla', + DB_ERROR_CONSTRAINT => 'violacion de constrenta', + DB_ERROR_DIVZERO => 'division per zèro', + DB_ERROR_INVALID => 'invalid', + DB_ERROR_INVALID_DATE => 'data o ora invalida', + DB_ERROR_INVALID_NUMBER => 'nombre invalid', + DB_ERROR_MISMATCH => 'error de concordà ncia', + DB_ERROR_NODBSELECTED => 'pas de basa de donadas de seleccionada', + DB_ERROR_NOSUCHFIELD => 'nom de colomna invalid', + DB_ERROR_NOSUCHTABLE => 'taula o vista inexistenta', + DB_ERROR_NOT_CAPABLE => 'foncion opcionala pas installada', + DB_ERROR_NOT_FOUND => 'pas trobat', + DB_ERROR_NOT_LOCKED => 'pas verrolhat', + DB_ERROR_SYNTAX => 'error de sintaxi', + DB_ERROR_UNSUPPORTED => 'pas suportat', + DB_ERROR_VALUE_COUNT_ON_ROW => 'valor inserida tròp granda per colomna', + DB_ERROR_INVALID_DSN => 'DSN invalid', + DB_ERROR_CONNECT_FAILED => 'fracà s a la connexion', + 0 => "pas d'error", // DB_OK + DB_ERROR_NEED_MORE_DATA => 'donadas provesidas insufisentas', + DB_ERROR_EXTENSION_NOT_FOUND=> 'extension pas trobada', + DB_ERROR_NOSUCHDB => 'basa de donadas desconeguda', + DB_ERROR_ACCESS_VIOLATION => 'dreits insufisents' +); diff --git a/pear/Auth/Container/ADOdb.php b/pear/Auth/Container/ADOdb.php index 26c3a23e..51169feb 100644 --- a/pear/Auth/Container/ADOdb.php +++ b/pear/Auth/Container/ADOdb.php @@ -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. diff --git a/perf/perf-db2.inc.php b/perf/perf-db2.inc.php index 143fc3d5..01d4932d 100644 --- a/perf/perf-db2.inc.php +++ b/perf/perf-db2.inc.php @@ -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. diff --git a/perf/perf-informix.inc.php b/perf/perf-informix.inc.php index e5cfb25d..e0588962 100644 --- a/perf/perf-informix.inc.php +++ b/perf/perf-informix.inc.php @@ -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. diff --git a/perf/perf-mssql.inc.php b/perf/perf-mssql.inc.php index cd8a6641..d2bcb66c 100644 --- a/perf/perf-mssql.inc.php +++ b/perf/perf-mssql.inc.php @@ -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. diff --git a/perf/perf-mssqlnative.inc.php b/perf/perf-mssqlnative.inc.php index b2778882..bb184db3 100644 --- a/perf/perf-mssqlnative.inc.php +++ b/perf/perf-mssqlnative.inc.php @@ -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. diff --git a/perf/perf-mysql.inc.php b/perf/perf-mysql.inc.php index adccbdc9..ea73e37f 100644 --- a/perf/perf-mysql.inc.php +++ b/perf/perf-mysql.inc.php @@ -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. @@ -302,11 +302,9 @@ class perf_mysql extends adodb_perf{ case ADODB_OPT_LOW : $sql = $this->optimizeTableLow; break; case ADODB_OPT_HIGH : $sql = $this->optimizeTableHigh; break; default : - { // May dont use __FUNCTION__ constant for BC (__FUNCTION__ Added in PHP 4.3.0) ADOConnection::outp( sprintf( "<p>%s: '%s' using of undefined mode '%s'</p>", __CLASS__, __FUNCTION__, $mode)); return false; - } } $sql = sprintf( $sql, $table); diff --git a/perf/perf-oci8.inc.php b/perf/perf-oci8.inc.php index 69df104f..a272b863 100644 --- a/perf/perf-oci8.inc.php +++ b/perf/perf-oci8.inc.php @@ -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. diff --git a/perf/perf-postgres.inc.php b/perf/perf-postgres.inc.php index bd0ccb1b..2c80820c 100644 --- a/perf/perf-postgres.inc.php +++ b/perf/perf-postgres.inc.php @@ -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. @@ -113,10 +113,8 @@ class perf_postgres extends adodb_perf{ case ADODB_OPT_LOW : $sql = $this->optimizeTableLow; break; case ADODB_OPT_HIGH: $sql = $this->optimizeTableHigh; break; default : - { ADOConnection::outp(sprintf("<p>%s: '%s' using of undefined mode '%s'</p>", __CLASS__, 'optimizeTable', $mode)); return false; - } } $sql = sprintf($sql, $table); diff --git a/pivottable.inc.php b/pivottable.inc.php index dd7d5d88..1b8e4076 100644 --- a/pivottable.inc.php +++ b/pivottable.inc.php @@ -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. diff --git a/replicate/adodb-replicate.inc.php b/replicate/adodb-replicate.inc.php index 9aaf3c42..f13e4af7 100644 --- a/replicate/adodb-replicate.inc.php +++ b/replicate/adodb-replicate.inc.php @@ -794,8 +794,7 @@ word-wrap: break-word; /* Internet Explorer 5.5+ */ if ($useQmark) { $sql = ''; $i = 0; $arr = array_reverse($rs->fields); - //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 diff --git a/rsfilter.inc.php b/rsfilter.inc.php index 4b609b98..626ae903 100644 --- a/rsfilter.inc.php +++ b/rsfilter.inc.php @@ -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. diff --git a/scripts/buildrelease.py b/scripts/buildrelease.py index 0b37b97b..6930d169 100755 --- a/scripts/buildrelease.py +++ b/scripts/buildrelease.py @@ -41,7 +41,7 @@ exclude_list = (".git*", # Command-line options options = "hb:dfk" -long_options = ["help", "branch", "debug", "fresh", "keep"] +long_options = ["help", "branch=", "debug", "fresh", "keep"] # Global flags debug_mode = False diff --git a/scripts/fix-static-docs.php b/scripts/fix-static-docs.php new file mode 100644 index 00000000..32133e02 --- /dev/null +++ b/scripts/fix-static-docs.php @@ -0,0 +1,221 @@ +<?php +/** +* A Program to post-process the dokuwiki document export to clean it up +* and fix the broken links +* +* @link http://adodb.org/dokuwiki/doku.php?id=v6:offline_docs_build +* @author Mark Newnham +* @since 02/13/2015 +*/ + +/** +* Recurses a directory and deletes files inside +* +* Copied from php.net +* +* @param string $dir The driectory name +* $return null +*/ +function delTree($dir) { + $files = array_diff(scandir($dir), array('.','..')); + foreach ($files as $file) { + (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); + } + return rmdir($dir); +} + +/** +* Initializes the listdiraux method with a starting directory point +* +* copied from php.net +* +* @param string $dir Starting directory +* @return array FQ list of files +*/ +function listdir($dir='.') { + if (!is_dir($dir)) { + return false; + } + $files = array(); + listdiraux($dir, $files); + + return $files; +} + +/** +* Recurses a directory structure and creates a list of files +* +* @param string $dir Starting directory +* @param string[] $files By reference, the current file list +* @return null +*/ +function listdiraux($dir, &$files) { + $handle = opendir($dir); + while (($file = readdir($handle)) !== false) { + if ($file == '.' || $file == '..') { + continue; + } + + if (preg_match('/v6$/',$file)) + /* + * This is only v5 documentation + */ + continue; + + $filepath = $dir == '.' ? $file : $dir . '/' . $file; + if (is_link($filepath)) + continue; + if (is_file($filepath)) + $files[] = $filepath; + else if (is_dir($filepath)) + listdiraux($filepath, $files); + } + closedir($handle); +} +/* +* Clean up the documentation directory from prior use +*/ +if (is_dir('documentation')) + deltree('documentation'); +mkdir('documentation'); + +$files = listdir('documentation-base'); +sort($files, SORT_LOCALE_STRING); + +/* +* Loop through files in documentation-base directory, creating a mirror +* structure in documentation, and applying the post-process rules defined +* below +*/ +foreach ($files as $f) { + + $r = str_replace('documentation-base','documentation',$f); + $dList = explode ('/',$r); + $titleList = $dList; + /* + * Get rid of the initial directory + */ + array_shift($titleList); + + $depth = count($dList) -2; + $dSlash = ''; + while(count($dList) > 1) + { + $dSlash .= array_shift($dList) . '/'; + if (!is_dir($dSlash)) + mkdir($dSlash); + } + if (!is_file($f)) + continue; + if (substr($f,-4) <> 'html') + { + /* + * An image or something else, copy unmodified + */ + copy ($f,$r); + continue; + } + + $prepend = str_repeat('../',$depth); + + $doc = new DOMDocument(); + @$doc->loadHTMLFile($f); + + /* + * Remove Page Tools Group + */ + $xpath = new DOMXPath($doc); + + /* + * Remove Top Menu Tools Group, and add a link to the ADOdb site + */ + $nodes = $xpath->query("//div[@class='tools group']"); + foreach($nodes as $node) { + $pn = $node->parentNode; + $pn->removeChild($node); + $newChild = $doc->createElement('div',''); + $newDiv = $pn->appendChild($newChild); + $newDiv->setAttribute('style','text-align:right'); + $newChild = $doc->createElement('a','ADOdb Web Site'); + $newA = $newDiv->appendChild($newChild); + $newA->setAttribute('href','http://adodb.org'); + } + + /* + * Remove Trace + */ + $nodes = $xpath->query("//div[@class='breadcrumbs']"); + foreach($nodes as $node) { + $node->parentNode->removeChild($node); + } + + /* + * Remove Side Menu Tools Group + */ + $nodes = $xpath->query("//div[@id='dokuwiki__pagetools']"); + foreach($nodes as $node) { + $node->parentNode->removeChild($node); + } + + /* + * Fix main links + */ + $nodes = $xpath->query("//a[@class='wikilink1']"); + foreach($nodes as $node) { + $n = $node->getAttribute('title'); + $p = $prepend . str_replace(':','/',$n) . '.html'; + $node->setAttribute('href', $p); + } + + /* + * Fix In Page links + */ + $nodes = $xpath->query("//a[@class='wikilink2']"); + foreach($nodes as $node) { + $n = $node->getAttribute('title'); + $p = $prepend . str_replace(':','/',$n) . '.html'; + $node->setAttribute('href', $p); + } + + /* + * Make Graphic point to first page. This will break if the image size + * ever changes. + */ + $corePage = $prepend . '/index.html'; + $nodes = $xpath->query("//img[@width='176']"); + foreach($nodes as $node) { + $node->parentNode->setAttribute('href', $corePage); + } + + /* + * Change title of page + */ + $nodes = $xpath->query("//title"); + foreach($nodes as $node) { + + + $docTitle = implode(':',$titleList); + $docTitle = str_replace('.html','',$docTitle); + $pn = $node->parentNode; + $pn->removeChild($node); + $newChild = $doc->createElement('title',$docTitle); + $pn->appendChild($newChild); + + } + + $doc->saveHTMLFile($r); + + echo $r, "\n"; +} +/* +* Now remove the original index and replace it with the hardcopy documentation one +*/ +unlink ('documentation/index.html'); +rename('documentation/adodb_index.html','documentation/index.html'); + +/* +* We could add in an auto zip and upload here, but this is a good place to +* stop and check the output +*/ + +?> diff --git a/scripts/uploadrelease.py b/scripts/uploadrelease.py index 5b295cbb..9f6f0aee 100755 --- a/scripts/uploadrelease.py +++ b/scripts/uploadrelease.py @@ -5,6 +5,7 @@ from distutils.version import LooseVersion import getopt +import getpass import glob import os from os import path @@ -14,12 +15,15 @@ import sys # Directories and files to exclude from release tarballs +# for debugging, set to a local dir e.g. "localhost:/tmp/sf-adodb/" sf_files = "frs.sourceforge.net:/home/frs/project/adodb/" + +# rsync command template rsync_cmd = "rsync -vP --rsh ssh {opt} {src} {usr}@{dst}" # Command-line options -options = "hn" -long_options = ["help", "dry-run"] +options = "hu:n" +long_options = ["help", "user=", "dry-run"] def usage(): @@ -29,12 +33,12 @@ def usage(): current one if unspecified) to Sourceforge. Parameters: - username Sourceforge user account release_path Location of the release files to upload (see buildrelease.py) Options: -h | --help Show this usage message + -u | --user <name> Sourceforge account (defaults to current user) -n | --dry-run Do not upload the files ''' % ( path.basename(__file__) @@ -53,14 +57,27 @@ def call_rsync(usr, opt, src, dst): command = rsync_cmd.format(usr=usr, opt=opt, src=src, dst=dst) + # Create directory if it does not exist + dst_split = dst.rsplit(':') + host = dst_split[0] + dst = dst_split[1] + mkdir = 'ssh {usr}@{host} mkdir -p {dst}'.format( + usr=usr, + host=host, + dst=dst + ) + if dry_run: + print mkdir print command else: + subprocess.call(mkdir, shell=True) subprocess.call(command, shell=True) def get_release_version(): - ''' Get the version number from the zip file to upload + ''' Returns the version number (X.Y.Z) from the zip file to upload, + excluding the SemVer suffix ''' try: zipfile = glob.glob('adodb-*.zip')[0] @@ -70,7 +87,7 @@ def get_release_version(): try: version = re.search( - "^adodb-([\d]+\.[\d]+\.[\d]+)\.zip$", + "^adodb-([\d]+\.[\d]+\.[\d]+)(-(alpha|beta|rc)\.[\d]+)?\.zip$", zipfile ).group(1) except AttributeError: @@ -82,15 +99,26 @@ def get_release_version(): def sourceforge_target_dir(version): - ''' Returns the sourceforge target directory - Base directory as defined in sf_files global variable, plus + ''' Returns the sourceforge target directory, relative to the root + directory (defined in sf_files global variable): basedir/subdir, with + basedir: + - for ADOdb version 5: adodb-php5-only + - for newer versions: adodbX (where X is the major version number) + subdir: - if version >= 5.21: adodb-X.Y - for older versions: adodb-XYZ-for-php5 ''' - # Keep only X.Y (discard patch number) - short_version = version.rsplit('.', 1)[0] + major_version = int(version.rsplit('.')[0]) + + # Base directory + if major_version == 5: + directory = 'adodb-php5-only/' + else: + directory = 'adodb{}/'.format(major_version) + + # Keep only X.Y (discard patch number and pre-release suffix) + short_version = version.split('-')[0].rsplit('.', 1)[0] - directory = 'adodb-php5-only/' if LooseVersion(version) >= LooseVersion('5.21'): directory += "adodb-" + short_version else: @@ -112,12 +140,9 @@ def process_command_line(): usage() sys.exit(2) - if len(args) < 1: - usage() - print "ERROR: please specify the Sourceforge user and release_path" - sys.exit(1) - # Default values for flags + username = getpass.getuser() + print username dry_run = False for opt, val in opts: @@ -125,15 +150,18 @@ def process_command_line(): usage() sys.exit(0) + elif opt in ("-u", "--user"): + username = val + elif opt in ("-n", "--dry-run"): dry_run = True # Mandatory parameters - username = args[0] + # (none) # Change to release directory, current if not specified try: - release_path = args[1] + release_path = args[0] os.chdir(release_path) except IndexError: release_path = os.getcwd() @@ -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. diff --git a/session/adodb-compress-bzip2.php b/session/adodb-compress-bzip2.php index 4e6ab501..5b55e191 100644 --- a/session/adodb-compress-bzip2.php +++ b/session/adodb-compress-bzip2.php @@ -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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-compress-gzip.php b/session/adodb-compress-gzip.php index 53bb0530..386199b2 100644 --- a/session/adodb-compress-gzip.php +++ b/session/adodb-compress-gzip.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-cryptsession.php b/session/adodb-cryptsession.php index 763cb50e..59e87960 100644 --- a/session/adodb-cryptsession.php +++ b/session/adodb-cryptsession.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-cryptsession2.php b/session/adodb-cryptsession2.php index b2ef54dd..7d6ef1d5 100644 --- a/session/adodb-cryptsession2.php +++ b/session/adodb-cryptsession2.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-encrypt-mcrypt.php b/session/adodb-encrypt-mcrypt.php index fc99fbc2..cb0375ee 100644 --- a/session/adodb-encrypt-mcrypt.php +++ b/session/adodb-encrypt-mcrypt.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-encrypt-md5.php b/session/adodb-encrypt-md5.php index f5b2da61..19915f86 100644 --- a/session/adodb-encrypt-md5.php +++ b/session/adodb-encrypt-md5.php @@ -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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-encrypt-secret.php b/session/adodb-encrypt-secret.php index 96ae8549..cc992e72 100644 --- a/session/adodb-encrypt-secret.php +++ b/session/adodb-encrypt-secret.php @@ -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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-session-clob.php b/session/adodb-session-clob.php index a6906f60..8e5d4f39 100644 --- a/session/adodb-session-clob.php +++ b/session/adodb-session-clob.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-session-clob2.php b/session/adodb-session-clob2.php index 2cb1cab6..a0b5aaf9 100644 --- a/session/adodb-session-clob2.php +++ b/session/adodb-session-clob2.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). diff --git a/session/adodb-session.php b/session/adodb-session.php index aa2ea1e8..7c060d0a 100644 --- a/session/adodb-session.php +++ b/session/adodb-session.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). @@ -70,7 +70,7 @@ function adodb_session_regenerate_id() } else { session_id(md5(uniqid(rand(), true))); $ck = session_get_cookie_params(); - setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']); + setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure'], $ck['httponly']); //@session_start(); } $new_id = session_id(); @@ -80,7 +80,7 @@ function adodb_session_regenerate_id() if (!$ok) { session_id($old_id); if (empty($ck)) $ck = session_get_cookie_params(); - setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']); + setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure'], $ck['httponly']); return false; } diff --git a/session/adodb-session2.php b/session/adodb-session2.php index adeefc62..71a29b7a 100644 --- a/session/adodb-session2.php +++ b/session/adodb-session2.php @@ -2,7 +2,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 Contributed by Ross Smith (adodb@netebb.com). @@ -100,7 +100,7 @@ function adodb_session_regenerate_id() } else { session_id(md5(uniqid(rand(), true))); $ck = session_get_cookie_params(); - setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']); + setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure'], $ck['httponly']); //@session_start(); } $new_id = session_id(); @@ -110,7 +110,7 @@ function adodb_session_regenerate_id() if (!$ok) { session_id($old_id); if (empty($ck)) $ck = session_get_cookie_params(); - setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']); + setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure'], $ck['httponly']); return false; } @@ -158,7 +158,7 @@ class ADODB_Session { */ static function driver($driver = null) { - static $_driver = 'mysql'; + static $_driver = 'mysqli'; static $set = false; if (!is_null($driver)) { diff --git a/session/old/adodb-cryptsession.php b/session/old/adodb-cryptsession.php index ca0d7930..e0b3dd1c 100644 --- a/session/old/adodb-cryptsession.php +++ b/session/old/adodb-cryptsession.php @@ -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. diff --git a/session/old/adodb-session-clob.php b/session/old/adodb-session-clob.php index 3361ea59..64dfb0d4 100644 --- a/session/old/adodb-session-clob.php +++ b/session/old/adodb-session-clob.php @@ -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. diff --git a/session/old/adodb-session.php b/session/old/adodb-session.php index 5764339e..49da02c5 100644 --- a/session/old/adodb-session.php +++ b/session/old/adodb-session.php @@ -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. diff --git a/tests/benchmark.php b/tests/benchmark.php index 5ba5e8bc..29223e3f 100644 --- a/tests/benchmark.php +++ b/tests/benchmark.php @@ -8,7 +8,7 @@ <body> <?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. diff --git a/tests/client.php b/tests/client.php index 5b30065a..591c26b2 100644 --- a/tests/client.php +++ b/tests/client.php @@ -2,7 +2,7 @@ <body bgcolor=white> <?php /** - * @version v5.20.9 21-Dec-2016 + * @version v5.21.0-dev ??-???-2016 * @copyright (c) 2001-2013 John Lim (jlim#natsoft.com). All rights reserved. * @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community * Released under both BSD license and Lesser GPL library license. diff --git a/tests/test-datadict.php b/tests/test-datadict.php index 9c7422aa..5eebe71d 100644 --- a/tests/test-datadict.php +++ b/tests/test-datadict.php @@ -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. diff --git a/tests/test-php5.php b/tests/test-php5.php index a8f1ffe5..6ab4cf28 100644 --- a/tests/test-php5.php +++ b/tests/test-php5.php @@ -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. diff --git a/tests/test.php b/tests/test.php index 50e74ad4..e2910bf1 100644 --- a/tests/test.php +++ b/tests/test.php @@ -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. @@ -40,13 +40,9 @@ function Err($msg) function CheckWS($conn) { -global $ADODB_EXTENSION; - include_once('../session/adodb-session.php'); if (defined('CHECKWSFAIL')){ echo " TESTING $conn ";flush();} - $saved = $ADODB_EXTENSION; $db = ADONewConnection($conn); - $ADODB_EXTENSION = $saved; if (headers_sent()) { print "<p><b>White space detected in adodb-$conn.inc.php or include file...</b></p>"; //die(); @@ -125,12 +121,10 @@ FROM `nuke_stories` `t1`, `nuke_authors` `t2`, `nuke_stories_cat` `t3`, `nuke_to //print $db->UnixTimeStamp('2003-7-22 23:00:00'); $phpv = phpversion(); - if (defined('ADODB_EXTENSION')) $ext = ' Extension '.ADODB_EXTENSION.' installed'; - else $ext = ''; print "<h3>ADODB Version: $ADODB_vers"; print "<p>Host: <i>$db->host</i>"; print "<br>Database: <i>$db->database</i>"; - print "<br>PHP: <i>$phpv $ext</i></h3>"; + print "<br>PHP: <i>$phpv</i></h3>"; flush(); diff --git a/tests/test3.php b/tests/test3.php index 78c7c775..5d155725 100644 --- a/tests/test3.php +++ b/tests/test3.php @@ -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. diff --git a/tests/test4.php b/tests/test4.php index 7a5d821c..9567dd32 100644 --- a/tests/test4.php +++ b/tests/test4.php @@ -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. diff --git a/tests/test5.php b/tests/test5.php index e46bbc1d..c7e73188 100644 --- a/tests/test5.php +++ b/tests/test5.php @@ -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. diff --git a/tests/test_mssqlnative.php b/tests/test_mssqlnative.php new file mode 100644 index 00000000..2965fea9 --- /dev/null +++ b/tests/test_mssqlnative.php @@ -0,0 +1,47 @@ +<?php + + +include('../adodb.inc.php'); + +/* SQL Script to clean objects created +drop sequence MySequence1; +drop sequence MySequence2; +drop sequence MySequence3; +drop table MySequence1Emul; +drop table MySequence2Emul; +drop table MySequence3Emul; + + * */ + + +$db = ADONewConnection("mssqlnative"); // create a connection +$db->debug=true; +$db->Connect('127.0.0.1','adodb','natsoft','northwind') or die('Fail'); + +//========================== +// This code tests GenId +//========================== +$ID1a=$db->GenID("MySequence1"); +$ID2a=$db->GenID("MySequence2"); +$ID1b=$db->GenID("MySequence1"); +$ID2b=$db->GenID("MySequence2"); +echo "ID1a=$ID1a,ID1b=$ID1b, ID2a=$ID2a,ID2b=$ID2b <br>\n"; +if(intval($ID1a)+1!==intval($ID1b)) die(sprintf("ERROR : Second value obtains by MySequence1 should be %d but is %d",$ID1a+1,$ID1b)); + +$db->CreateSequence("MySequence3",100); +$ID2b=$db->GenID("MySequence3"); +if(intval($ID2b)!==100) die(sprintf("ERROR : Value from MySequence3 should be 100 but is %d",$ID2b)); + +$db->mssql_version=10; // Force to simulate Pre 2012 (without sequence) behavior +$ID1a=$db->GenID("MySequence1Emul"); +$ID2a=$db->GenID("MySequence2Emul"); +$ID1b=$db->GenID("MySequence1Emul"); +$ID2b=$db->GenID("MySequence2Emul"); +echo "ID1a=$ID1a,ID1b=$ID1b, ID2a=$ID2a,ID2b=$ID2b <br>\n"; +if(intval($ID1a+1)!==intval($ID1b)) die(sprintf("ERROR : Second value obtains by MySequence1Emul should be %d but is %d",$ID1a+1,$ID1b)); + +$db->CreateSequence("MySequence3Emul",100); +$ID2b=$db->GenID("MySequence3Emul"); +if(intval($ID2b)!==100) die(sprintf("ERROR : Value from MySequence3Emul should be 100 but is %d",$ID2b)); + +echo "End of tests.";
\ No newline at end of file diff --git a/tests/testcache.php b/tests/testcache.php index 87f6d51a..46e5b26a 100644 --- a/tests/testcache.php +++ b/tests/testcache.php @@ -2,7 +2,7 @@ <body> <?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. diff --git a/tests/testdatabases.inc.php b/tests/testdatabases.inc.php index f9f000a6..5df07011 100644 --- a/tests/testdatabases.inc.php +++ b/tests/testdatabases.inc.php @@ -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. diff --git a/tests/testmssql.php b/tests/testmssql.php index 733f0d45..8b8d052e 100644 --- a/tests/testmssql.php +++ b/tests/testmssql.php @@ -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. diff --git a/tests/testoci8.php b/tests/testoci8.php index 5eadc22e..0c5b89af 100644 --- a/tests/testoci8.php +++ b/tests/testoci8.php @@ -2,7 +2,7 @@ <body> <?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. diff --git a/tests/testoci8cursor.php b/tests/testoci8cursor.php index 1f7b381e..15fad3e1 100644 --- a/tests/testoci8cursor.php +++ b/tests/testoci8cursor.php @@ -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. diff --git a/tests/testpaging.php b/tests/testpaging.php index 947641be..dc84184f 100644 --- a/tests/testpaging.php +++ b/tests/testpaging.php @@ -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. diff --git a/tests/testpear.php b/tests/testpear.php index a59f5f2c..350efe45 100644 --- a/tests/testpear.php +++ b/tests/testpear.php @@ -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. diff --git a/tests/testsessions.php b/tests/testsessions.php index 79a66191..1a68fe19 100644 --- a/tests/testsessions.php +++ b/tests/testsessions.php @@ -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. diff --git a/toexport.inc.php b/toexport.inc.php index 94c394b8..70f4e6dc 100644 --- a/toexport.inc.php +++ b/toexport.inc.php @@ -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. @@ -77,7 +77,7 @@ function _adodb_export(&$rs,$sep,$sepreplace,$fp=false,$addtitles=true,$quote = reset($fieldTypes); $i = 0; $elements = array(); - while(list(,$o) = each($fieldTypes)) { + foreach ($fieldTypes as $o) { $v = ($o) ? $o->name : 'Field'.($i++); if ($escquote) $v = str_replace($quote,$escquotequote,$v); diff --git a/tohtml.inc.php b/tohtml.inc.php index d39ed291..e75079fc 100644 --- a/tohtml.inc.php +++ b/tohtml.inc.php @@ -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. |
