From 47ea43f5e865c2bb2ecc1f5eea0229b0db95d1d1 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Tue, 1 Feb 2022 16:58:30 +0100 Subject: [PATCH 1/2] MDL-73664 lib: Upgrade ADODB to 5.21.4 --- lib/adodb/adodb-active-record.inc.php | 141 +-- lib/adodb/adodb-active-recordx.inc.php | 44 +- lib/adodb/adodb-csvlib.inc.php | 38 +- lib/adodb/adodb-datadict.inc.php | 64 +- lib/adodb/adodb-error.inc.php | 28 +- lib/adodb/adodb-errorhandler.inc.php | 25 +- lib/adodb/adodb-errorpear.inc.php | 25 +- lib/adodb/adodb-exceptions.inc.php | 25 +- lib/adodb/adodb-lib.inc.php | 200 ++-- lib/adodb/adodb-loadbalancer.inc.php | 24 +- lib/adodb/adodb-memcache.lib.inc.php | 50 +- lib/adodb/adodb-pager.inc.php | 42 +- lib/adodb/adodb-pear.inc.php | 27 +- lib/adodb/adodb-perf.inc.php | 37 +- lib/adodb/adodb-time.inc.php | 129 +- lib/adodb/adodb-xmlschema.inc.php | 32 +- lib/adodb/adodb-xmlschema03.inc.php | 34 +- lib/adodb/adodb.inc.php | 298 +++-- lib/adodb/datadict/datadict-access.inc.php | 29 +- lib/adodb/datadict/datadict-db2.inc.php | 27 +- lib/adodb/datadict/datadict-firebird.inc.php | 29 +- lib/adodb/datadict/datadict-generic.inc.php | 29 +- lib/adodb/datadict/datadict-ibase.inc.php | 29 +- lib/adodb/datadict/datadict-informix.inc.php | 29 +- lib/adodb/datadict/datadict-mssql.inc.php | 29 +- .../datadict/datadict-mssqlnative.inc.php | 177 +-- lib/adodb/datadict/datadict-mysql.inc.php | 29 +- lib/adodb/datadict/datadict-oci8.inc.php | 29 +- lib/adodb/datadict/datadict-postgres.inc.php | 220 ++-- lib/adodb/datadict/datadict-sapdb.inc.php | 30 +- lib/adodb/datadict/datadict-sqlite.inc.php | 31 +- lib/adodb/datadict/datadict-sybase.inc.php | 29 +- lib/adodb/drivers/adodb-access.inc.php | 33 +- lib/adodb/drivers/adodb-ado.inc.php | 34 +- lib/adodb/drivers/adodb-ado5.inc.php | 34 +- lib/adodb/drivers/adodb-ado_access.inc.php | 34 +- lib/adodb/drivers/adodb-ado_mssql.inc.php | 40 +- lib/adodb/drivers/adodb-ads.inc.php | 40 +- lib/adodb/drivers/adodb-borland_ibase.inc.php | 35 +- lib/adodb/drivers/adodb-csv.inc.php | 45 +- lib/adodb/drivers/adodb-db2.inc.php | 1041 +++++++++-------- lib/adodb/drivers/adodb-db2oci.inc.php | 36 +- lib/adodb/drivers/adodb-db2ora.inc.php | 37 +- lib/adodb/drivers/adodb-fbsql.inc.php | 32 +- lib/adodb/drivers/adodb-firebird.inc.php | 35 +- lib/adodb/drivers/adodb-ibase.inc.php | 46 +- lib/adodb/drivers/adodb-informix.inc.php | 36 +- lib/adodb/drivers/adodb-informix72.inc.php | 41 +- lib/adodb/drivers/adodb-ldap.inc.php | 38 +- lib/adodb/drivers/adodb-mssql.inc.php | 44 +- lib/adodb/drivers/adodb-mssql_n.inc.php | 66 +- lib/adodb/drivers/adodb-mssqlnative.inc.php | 311 ++--- lib/adodb/drivers/adodb-mssqlpo.inc.php | 38 +- lib/adodb/drivers/adodb-mysql.inc.php | 77 +- lib/adodb/drivers/adodb-mysqli.inc.php | 173 +-- lib/adodb/drivers/adodb-mysqlpo.inc.php | 46 +- lib/adodb/drivers/adodb-mysqlt.inc.php | 43 +- lib/adodb/drivers/adodb-netezza.inc.php | 46 +- lib/adodb/drivers/adodb-oci8.inc.php | 80 +- lib/adodb/drivers/adodb-oci805.inc.php | 29 +- lib/adodb/drivers/adodb-oci8po.inc.php | 43 +- lib/adodb/drivers/adodb-oci8quercus.inc.php | 38 +- lib/adodb/drivers/adodb-odbc.inc.php | 31 +- lib/adodb/drivers/adodb-odbc_db2.inc.php | 109 +- lib/adodb/drivers/adodb-odbc_mssql.inc.php | 49 +- .../drivers/adodb-odbc_mssql2012.inc.php | 29 +- lib/adodb/drivers/adodb-odbc_oracle.inc.php | 31 +- lib/adodb/drivers/adodb-odbtp.inc.php | 35 +- lib/adodb/drivers/adodb-odbtp_unicode.inc.php | 50 +- lib/adodb/drivers/adodb-oracle.inc.php | 35 +- lib/adodb/drivers/adodb-pdo.inc.php | 67 +- lib/adodb/drivers/adodb-pdo_dblib.inc.php | 20 +- lib/adodb/drivers/adodb-pdo_firebird.inc.php | 29 +- lib/adodb/drivers/adodb-pdo_mssql.inc.php | 31 +- lib/adodb/drivers/adodb-pdo_mysql.inc.php | 90 +- lib/adodb/drivers/adodb-pdo_oci.inc.php | 31 +- lib/adodb/drivers/adodb-pdo_pgsql.inc.php | 30 +- lib/adodb/drivers/adodb-pdo_sqlite.inc.php | 36 +- lib/adodb/drivers/adodb-pdo_sqlsrv.inc.php | 21 +- lib/adodb/drivers/adodb-postgres.inc.php | 38 +- lib/adodb/drivers/adodb-postgres64.inc.php | 176 ++- lib/adodb/drivers/adodb-postgres7.inc.php | 89 +- lib/adodb/drivers/adodb-postgres8.inc.php | 36 +- lib/adodb/drivers/adodb-postgres9.inc.php | 30 +- lib/adodb/drivers/adodb-proxy.inc.php | 32 +- lib/adodb/drivers/adodb-sapdb.inc.php | 35 +- lib/adodb/drivers/adodb-sqlanywhere.inc.php | 76 +- lib/adodb/drivers/adodb-sqlite.inc.php | 42 +- lib/adodb/drivers/adodb-sqlite3.inc.php | 78 +- lib/adodb/drivers/adodb-sqlitepo.inc.php | 46 +- lib/adodb/drivers/adodb-sybase.inc.php | 45 +- lib/adodb/drivers/adodb-sybase_ase.inc.php | 33 +- lib/adodb/drivers/adodb-text.inc.php | 85 +- lib/adodb/drivers/adodb-vfp.inc.php | 34 +- lib/adodb/perf/perf-db2.inc.php | 33 +- lib/adodb/perf/perf-informix.inc.php | 33 +- lib/adodb/perf/perf-mssql.inc.php | 34 +- lib/adodb/perf/perf-mssqlnative.inc.php | 34 +- lib/adodb/perf/perf-mysql.inc.php | 33 +- lib/adodb/perf/perf-oci8.inc.php | 33 +- lib/adodb/perf/perf-postgres.inc.php | 34 +- lib/adodb/phpdoc | 20 + lib/adodb/pivottable.inc.php | 27 +- lib/adodb/rsfilter.inc.php | 25 +- lib/adodb/toexport.inc.php | 26 +- lib/adodb/tohtml.inc.php | 43 +- 106 files changed, 3636 insertions(+), 3018 deletions(-) create mode 100644 lib/adodb/phpdoc diff --git a/lib/adodb/adodb-active-record.inc.php b/lib/adodb/adodb-active-record.inc.php index aea7be7db73..8f3b00538f6 100644 --- a/lib/adodb/adodb-active-record.inc.php +++ b/lib/adodb/adodb-active-record.inc.php @@ -1,23 +1,25 @@ _quoteNames)) { + $this->_quoteNames = $ADODB_QUOTE_FIELDNAMES; + } if ($db == false && is_object($pkeyarr)) { $db = $pkeyarr; @@ -880,7 +886,7 @@ class ADODB_Active_Record { $cnt += 1; } } - + $tableName = $this->nameQuoter($db,$this->_table); $sql = sprintf('INSERT INTO %s (%s) VALUES (%s)', $tableName, @@ -919,7 +925,7 @@ class ADODB_Active_Record { $where = $this->GenWhere($db,$table); $tableName = $this->nameQuoter($db,$this->_table); - + $sql = sprintf('DELETE FROM %s WHERE %s', $tableName, $where @@ -995,19 +1001,19 @@ class ADODB_Active_Record { } break; } - + $newArr = array(); foreach($arr as $k=>$v) $newArr[$this->nameQuoter($db,$k)] = $v; $arr = $newArr; - + $newPkey = array(); foreach($pkey as $k=>$v) $newPkey[$k] = $this->nameQuoter($db,$v); $pkey = $newPkey; - + $tableName = $this->nameQuoter($db,$this->_table); - + $ok = $db->Replace($tableName,$arr,$pkey); if ($ok) { $this->_saved = true; // 1= update 2=insert @@ -1095,7 +1101,7 @@ class ADODB_Active_Record { $tableName, implode(',',$pairs), $where); - + $ok = $db->Execute($sql,$valarr); if ($ok) { $this->_original = $neworig; @@ -1114,62 +1120,27 @@ class ADODB_Active_Record { } /** - * Quotes the table and column and field names - * - * this honours the ADODB_QUOTE_FIELDNAMES directive. The routines that - * use it should really just call _adodb_getinsertsql and _adodb_getupdatesql - * which is a nice easy project if you are interested - * - * @param obj $db The database connection - * @param string $name The table or column name to quote - * - * @return string The quoted name - */ - private function nameQuoter($db,$string) + * Quotes the table, column and field names. + * + * This honours the internal {@see $_quoteNames} property, which overrides + * the global $ADODB_QUOTE_FIELDNAMES directive. + * + * @param ADOConnection $db The database connection + * @param string $name The table or column name to quote + * + * @return string The quoted name + */ + private function nameQuoter($db, $name) { global $ADODB_QUOTE_FIELDNAMES; - - if (!$ADODB_QUOTE_FIELDNAMES && !$this->_quoteNames) - /* - * Nothing to be done - */ - return $string; - - if ($this->_quoteNames == 'NONE') - /* - * Force no quoting when ADODB_QUOTE_FIELDNAMES is set - */ - return $string; - - if ($this->_quoteNames) - /* - * Internal setting takes precedence - */ - $quoteMethod = $this->_quoteNames; - - else - $quoteMethod = $ADODB_QUOTE_FIELDNAMES; - - switch ($quoteMethod) - { - case 'LOWER': - $string = strtolower($string); - break; - case 'NATIVE': - /* - * Nothing to be done - */ - break; - case 'UPPER': - default: - $string = strtoupper($string); - } - - $string = sprintf( '%s%s%s', - $db->nameQuote, - $string, - $db->nameQuote - ); + + $save = $ADODB_QUOTE_FIELDNAMES; + $ADODB_QUOTE_FIELDNAMES = $this->_quoteNames; + + $string = _adodb_quote_fieldname($db, $name); + + $ADODB_QUOTE_FIELDNAMES = $save; + return $string; } @@ -1182,7 +1153,7 @@ global $_ADODB_ACTIVE_DBS; $save = $db->SetFetchMode(ADODB_FETCH_NUM); - + $qry = "select * from ".$table; if (!empty($whereOrderBy)) { diff --git a/lib/adodb/adodb-active-recordx.inc.php b/lib/adodb/adodb-active-recordx.inc.php index a9356eee7e8..5de5b13096f 100644 --- a/lib/adodb/adodb-active-recordx.inc.php +++ b/lib/adodb/adodb-active-recordx.inc.php @@ -1,27 +1,27 @@ $v) { - if ($attr == 2 && is_numeric($v)) + if ($attr == 2 && is_numeric($v)) $attr = 'SIZE'; - elseif ($attr == 2 && strtoupper($ftype) == 'ENUM') + elseif ($attr == 2 && strtoupper($ftype) == 'ENUM') $attr = 'ENUM'; - else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) + else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v); switch($attr) { @@ -744,9 +750,9 @@ class ADODB_DataDict { * some blob types do not accept nulls, so we override the * previously defined value */ - $fnotnull = false; + $fnotnull = false; - if ($fprimary) + if ($fprimary) $pkey[] = $fname; if (($ty == 'X' || $ty == 'X2' || $ty == 'XL' || $ty == 'B') && !$this->blobAllowsDefaultValue) @@ -843,7 +849,7 @@ class ADODB_DataDict { if (strlen($fprec)) $ftype .= ",".$fprec; $ftype .= ')'; } - + /* * Handle additional options */ @@ -856,12 +862,12 @@ class ADODB_DataDict { case 'ENUM': $ftype .= '(' . $value . ')'; break; - + default: } } } - + return $ftype; } @@ -924,7 +930,7 @@ class ADODB_DataDict { return $sql; } } - + $s = "CREATE TABLE $tabname (\n"; $s .= implode(",\n", $lines); if (sizeof($pkey)>0) { diff --git a/lib/adodb/adodb-error.inc.php b/lib/adodb/adodb-error.inc.php index b5a352c60c2..517cf9b0138 100644 --- a/lib/adodb/adodb-error.inc.php +++ b/lib/adodb/adodb-error.inc.php @@ -1,19 +1,27 @@ _nestedSQL) || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || - preg_match('/\s+GROUP\s+BY\s+/is',$sql) || - preg_match('/\s+UNION\s+/is',$sql)) { + /* + * These databases require a "SELECT * FROM (SELECT" type + * statement to have an alias for the result + */ + $requiresAlias = ''; + $requiresAliasArray = array('postgres9','postgres','mysql','mysqli','mssql','mssqlnative','sqlsrv'); + if (in_array($zthis->databaseType,$requiresAliasArray) + || in_array($zthis->dsnType,$requiresAliasArray) + ) { + $requiresAlias = '_ADODB_ALIAS_'; + } + if (!empty($zthis->_nestedSQL) + || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) + || preg_match('/\s+GROUP\s+BY\s+/is',$sql) + || preg_match('/\s+UNION\s+/is',$sql) + ) { $rewritesql = adodb_strip_order_by($sql); // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias @@ -408,24 +431,37 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) $rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")"; } else $rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")"; + } else { + $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) $requiresAlias"; + } - } else if (strncmp($zthis->databaseType,'postgres',8) == 0 - || strncmp($zthis->databaseType,'mysql',5) == 0 - || strncmp($zthis->databaseType,'mssql',5) == 0 - || strncmp($zthis->dsnType,'sqlsrv',5) == 0 - || strncmp($zthis->dsnType,'mssql',5) == 0 - ){ - $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_"; - } else { - $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)"; - } } else { - // now replace SELECT ... FROM with SELECT COUNT(*) FROM - if ( strpos($sql, '_ADODB_COUNT') !== FALSE ) { - $rewritesql = preg_replace('/^\s*?SELECT\s+_ADODB_COUNT(.*)_ADODB_COUNT\s/is','SELECT COUNT(*) ',$sql); - } else { - $rewritesql = preg_replace('/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql); + // Replace 'SELECT ... FROM' with 'SELECT COUNT(*) FROM' + // Parse the query one char at a time starting after the SELECT + // to find the FROM clause's position, ignoring any sub-queries. + $start = stripos($sql, 'SELECT') + 7; + if ($start === false) { + // Not a SELECT statement - probably should trigger an exception here + return 0; } + $len = strlen($sql); + $numParentheses = 0; + for ($pos = $start; $pos < $len; $pos++) { + switch ($sql[$pos]) { + case '(': $numParentheses++; continue 2; + case ')': $numParentheses--; continue 2; + } + // Ignore whatever is between parentheses (sub-queries) + if ($numParentheses > 0) { + continue; + } + // Exit loop if 'FROM' keyword was found + if (strtoupper(substr($sql, $pos, 4)) == 'FROM') { + break; + } + } + $rewritesql = 'SELECT COUNT(*) ' . substr($sql, $pos); + // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails // with mssql, access and postgresql. Also a good speedup optimization - skips sorting! // also see PHPLens Issue No: 12752 @@ -433,7 +469,9 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) } if (isset($rewritesql) && $rewritesql != $sql) { - if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0]; + if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) { + $rewritesql .= $limitarr[0]; + } if ($secs2cache) { // we only use half the time of secs2cache because the count can quickly @@ -442,18 +480,23 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) } else { $qryRecs = $zthis->GetOne($rewritesql,$inputarr); - } + } if ($qryRecs !== false) return $qryRecs; } + //-------------------------------------------- // query rewrite failed - so try slower way... - // strip off unneeded ORDER BY if no UNION - if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql; - else $rewritesql = $rewritesql = adodb_strip_order_by($sql); + if (preg_match('/\s*UNION\s*/is', $sql)) { + $rewritesql = $sql; + } else { + $rewritesql = $rewritesql = adodb_strip_order_by($sql); + } - if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0]; + if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) { + $rewritesql .= $limitarr[0]; + } if ($secs2cache) { $rstest = $zthis->CacheExecute($secs2cache,$rewritesql,$inputarr); @@ -630,10 +673,50 @@ function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr return $rsreturn; } -function _adodb_getupdatesql(&$zthis, &$rs, $arrFields, $forceUpdate=false, $force=2) +/** + * Performs case conversion and quoting of the given field name. + * + * See Global variable $ADODB_QUOTE_FIELDNAMES. + * + * @param ADOConnection $zthis + * @param string $fieldName + * + * @return string Quoted field name + */ +function _adodb_quote_fieldname($zthis, $fieldName) { global $ADODB_QUOTE_FIELDNAMES; + // Case conversion - defaults to UPPER + $case = is_bool($ADODB_QUOTE_FIELDNAMES) ? 'UPPER' : $ADODB_QUOTE_FIELDNAMES; + switch ($case) { + case 'LOWER': + $fieldName = strtolower($fieldName); + break; + case 'NATIVE': + // Do nothing + break; + case 'UPPER': + case 'BRACKETS': + default: + $fieldName = strtoupper($fieldName); + break; + } + + // Quote field if requested, or necessary (field contains space) + if ($ADODB_QUOTE_FIELDNAMES || strpos($fieldName, ' ') !== false ) { + if ($ADODB_QUOTE_FIELDNAMES === 'BRACKETS') { + return $zthis->leftBracket . $fieldName . $zthis->rightBracket; + } else { + return $zthis->nameQuote . $fieldName . $zthis->nameQuote; + } + } else { + return $fieldName; + } +} + +function _adodb_getupdatesql(&$zthis, &$rs, $arrFields, $forceUpdate=false, $force=2) +{ if (!$rs) { printf(ADODB_BAD_RS,'GetUpdateSQL'); return false; @@ -679,21 +762,7 @@ function _adodb_getupdatesql(&$zthis, &$rs, $arrFields, $forceUpdate=false, $for $type = 'C'; } - if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) { - switch ($ADODB_QUOTE_FIELDNAMES) { - case 'BRACKETS': - $fnameq = $zthis->leftBracket.$upperfname.$zthis->rightBracket;break; - case 'LOWER': - $fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break; - case 'NATIVE': - $fnameq = $zthis->nameQuote.$field->name.$zthis->nameQuote;break; - case 'UPPER': - default: - $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break; - } - } else { - $fnameq = $upperfname; - } + $fnameq = _adodb_quote_fieldname($zthis, $field->name); //********************************************************// if (is_null($arrFields[$upperfname]) @@ -819,7 +888,6 @@ function _adodb_getinsertsql(&$zthis, &$rs, $arrFields, $force=2) static $cacheRS = false; static $cacheSig = 0; static $cacheCols; - global $ADODB_QUOTE_FIELDNAMES; $tableName = ''; $values = ''; @@ -870,21 +938,7 @@ static $cacheCols; $upperfname = strtoupper($field->name); if (adodb_key_exists($upperfname,$arrFields,$force)) { $bad = false; - if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES)) { - switch ($ADODB_QUOTE_FIELDNAMES) { - case 'BRACKETS': - $fnameq = $zthis->leftBracket.$upperfname.$zthis->rightBracket;break; - case 'LOWER': - $fnameq = $zthis->nameQuote.strtolower($field->name).$zthis->nameQuote;break; - case 'NATIVE': - $fnameq = $zthis->nameQuote.$field->name.$zthis->nameQuote;break; - case 'UPPER': - default: - $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;break; - } - } else - $fnameq = $upperfname; - + $fnameq = _adodb_quote_fieldname($zthis, $field->name); $type = $recordSet->MetaType($field->type); /********************************************************/ @@ -1119,8 +1173,16 @@ function _adodb_debug_execute(&$zthis, $sql, $inputarr) foreach($inputarr as $kk=>$vv) { if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...'; if (is_null($vv)) $ss .= "($kk=>null) "; - else $ss .= "($kk=>'$vv') "; + else + { + if (is_array($vv)) + { + $vv = sprintf("Array Of Values: [%s]", implode(',',$vv)); + } + $ss .= "($kk=>'$vv') "; + } } + $ss = "[ $ss ]"; } $sqlTxt = is_array($sql) ? $sql[0] : $sql; diff --git a/lib/adodb/adodb-loadbalancer.inc.php b/lib/adodb/adodb-loadbalancer.inc.php index c0e3de00b1d..2e4f3928d3e 100644 --- a/lib/adodb/adodb-loadbalancer.inc.php +++ b/lib/adodb/adodb-loadbalancer.inc.php @@ -8,20 +8,20 @@ * including dealing with connection failures and retrying queries on a different * connection instead. * - * Released under both BSD license and Lesser GPL library license. - * Whenever there is any discrepancy between the two licenses, - * the BSD license will take precedence. See LICENSE.md. + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. * - * Latest version is available at https://adodb.org/ + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker * - * @package ADOdb - * @version v5.21.0 2021-02-27 - * @author Mike Benoit - * @copyright (c) 2016 Mike Benoit and the ADOdb community - * @license BSD-3-Clause - * @license GNU Lesser General Public License (LGPL) v2.1 or later - * @link https://adodb.org/ - * @since v5.21.0 + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2016 Mike Benoit and the ADOdb community */ /** diff --git a/lib/adodb/adodb-memcache.lib.inc.php b/lib/adodb/adodb-memcache.lib.inc.php index f143e8cb47b..7f110e7493c 100644 --- a/lib/adodb/adodb-memcache.lib.inc.php +++ b/lib/adodb/adodb-memcache.lib.inc.php @@ -1,4 +1,23 @@ 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); - - 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 -*/ - class ADODB_Cache_MemCache { var $createdir = false; // create caching directory structure? diff --git a/lib/adodb/adodb-pager.inc.php b/lib/adodb/adodb-pager.inc.php index ec6aba4649c..cfe981d32c8 100644 --- a/lib/adodb/adodb-pager.inc.php +++ b/lib/adodb/adodb-pager.inc.php @@ -1,28 +1,24 @@ implemented Render_PageLinks(). - - Please note, this class is entirely unsupported, - and no free support requests except for bug reports - will be entertained by the author. - -*/ class ADODB_Pager { var $id; // unique id for pager (defaults to 'adodb') var $db; // ADODB connection object diff --git a/lib/adodb/adodb-pear.inc.php b/lib/adodb/adodb-pear.inc.php index e0ee74bac96..c48ef132d27 100644 --- a/lib/adodb/adodb-pear.inc.php +++ b/lib/adodb/adodb-pear.inc.php @@ -1,18 +1,25 @@ + * and Tomas V.V.Cox . Portions (c)1997-2002 The PHP Group. * - * PEAR DB Emulation Layer for ADODB. + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. * - * The following code is modelled on PEAR DB code by Stig Bakken | - * and Tomas V.V.Cox . Portions (c)1997-2002 The PHP Group. + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community */ /* diff --git a/lib/adodb/adodb-perf.inc.php b/lib/adodb/adodb-perf.inc.php index 6bce7354d5b..d9d8a993783 100644 --- a/lib/adodb/adodb-perf.inc.php +++ b/lib/adodb/adodb-perf.inc.php @@ -1,22 +1,23 @@ 4 digit year + * conversion. The maximum is billions of years in the future, but this + * is a theoretical limit as the computation of that year would take too + * long with the current implementation of adodb_mktime(). + * + * Replaces native functions as follows: + * - getdate() with adodb_getdate() + * - date() with adodb_date() + * - gmdate() with adodb_gmdate() + * - mktime() with adodb_mktime() + * - gmmktime() with adodb_gmmktime() + * - strftime() with adodb_strftime() + * - strftime() with adodb_gmstrftime() + * + * The parameters are identical, except that adodb_date() accepts a subset + * of date()'s field formats. Mktime() will convert from local time to GMT, + * and date() will convert from GMT to local time, but daylight savings is + * not handled currently. + * + * To improve performance, the native date functions are used whenever + * possible, the library only switches to PHP code when the dates fall outside + * of the 32-bit signed integer range. + * + * This library is independent of the rest of ADOdb, and can be used + * as standalone code. + * + * GREGORIAN CORRECTION + * + * Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, + * October 4, 1582 (Julian) was followed immediately by Friday, October 15, + * 1582 (Gregorian). We handle this correctly, so: + * adodb_mktime(0, 0, 0, 10, 15, 1582) - adodb_mktime(0, 0, 0, 10, 4, 1582) + * == 24 * 3600 (1 day) + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2003-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ + /* -ADOdb Date Library, part of the ADOdb abstraction library - -Latest version is available at https://adodb.org/ - -@version v5.21.0 2021-02-27 -@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved. -@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community - -PHP native date functions use integer timestamps for computations. -Because of this, dates are restricted to the years 1901-2038 on Unix -and 1970-2038 on Windows due to integer overflow for dates beyond -those years. This library overcomes these limitations by replacing the -native function's signed integers (normally 32-bits) with PHP floating -point numbers (normally 64-bits). - -Dates from 100 A.D. to 3000 A.D. and later -have been tested. The minimum is 100 A.D. as <100 will invoke the -2 => 4 digit year conversion. The maximum is billions of years in the -future, but this is a theoretical limit as the computation of that year -would take too long with the current implementation of adodb_mktime(). - -This library replaces native functions as follows: - -
-	getdate()  with  adodb_getdate()
-	date()     with  adodb_date()
-	gmdate()   with  adodb_gmdate()
-	mktime()   with  adodb_mktime()
-	gmmktime() with  adodb_gmmktime()
-	strftime() with  adodb_strftime()
-	strftime() with  adodb_gmstrftime()
-
- -The parameters are identical, except that adodb_date() accepts a subset -of date()'s field formats. Mktime() will convert from local time to GMT, -and date() will convert from GMT to local time, but daylight savings is -not handled currently. - -This library is independent of the rest of ADOdb, and can be used -as standalone code. - -PERFORMANCE - -For high speed, this library uses the native date functions where -possible, and only switches to PHP code when the dates fall outside -the 32-bit signed integer range. - -GREGORIAN CORRECTION - -Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, -October 4, 1582 (Julian) was followed immediately by Friday, October 15, -1582 (Gregorian). - -Since 0.06, we handle this correctly, so: - -adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582) - == 24 * 3600 (1 day) - -============================================================================= - -COPYRIGHT - -(c) 2003-2014 John Lim and released under BSD-style license except for code by -jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year -and originally found at http://www.php.net/manual/en/function.mktime.php - - ============================================================================= FUNCTION DESCRIPTIONS diff --git a/lib/adodb/adodb-xmlschema.inc.php b/lib/adodb/adodb-xmlschema.inc.php index 0961b4dbf50..58e3affd6c5 100644 --- a/lib/adodb/adodb-xmlschema.inc.php +++ b/lib/adodb/adodb-xmlschema.inc.php @@ -1,21 +1,29 @@ db = $db; $this->debug = $this->db->debug; - $this->dict = NewDataDictionary( $this->db ); + $this->dict = newDataDictionary( $this->db ); $this->sqlArray = array(); $this->schemaVersion = XMLS_SCHEMA_VERSION; $this->executeInline( XMLS_EXECUTE_INLINE ); diff --git a/lib/adodb/adodb-xmlschema03.inc.php b/lib/adodb/adodb-xmlschema03.inc.php index 9fb8272cab9..de1ea26c7d6 100644 --- a/lib/adodb/adodb-xmlschema03.inc.php +++ b/lib/adodb/adodb-xmlschema03.inc.php @@ -1,21 +1,29 @@ db = $db; $this->debug = $this->db->debug; - $this->dict = NewDataDictionary( $this->db ); + $this->dict = newDataDictionary( $this->db ); $this->sqlArray = array(); $this->schemaVersion = XMLS_SCHEMA_VERSION; $this->executeInline( XMLS_EXECUTE_INLINE ); @@ -2114,7 +2122,7 @@ class adoSchema { . '">' . "\n"; // grab details from database - $rs = $this->db->execute( 'SELECT * FROM ' . $table . ' WHERE -1' ); + $rs = $this->db->execute('SELECT * FROM ' . $table . ' WHERE 0=1'); $fields = $this->db->metaColumns( $table ); $indexes = $this->db->metaIndexes( $table ); diff --git a/lib/adodb/adodb.inc.php b/lib/adodb/adodb.inc.php index 080a8df9cdd..3d5d1ad3c78 100644 --- a/lib/adodb/adodb.inc.php +++ b/lib/adodb/adodb.inc.php @@ -1,34 +1,22 @@ RecordCount() is used. @@ -496,7 +484,8 @@ if (!defined('_ADODB_LAYER')) { // var $_oldRaiseFn = false; var $_transOK = null; - var $_connectionID = false; /// The returned link identifier whenever a successful database connection is made. + /** @var resource Identifier for the native database connection */ + var $_connectionID = false; var $_errorMsg = false; /// A variable which was used to keep the returned last error message. The value will /// then returned by the errorMsg() function var $_errorCode = false; /// Last error code, not guaranteed to be used - only by oci8 @@ -509,6 +498,19 @@ if (!defined('_ADODB_LAYER')) { var $_logsql = false; var $_transmode = ''; // transaction mode + /** + * Additional parameters that may be passed to drivers in the connect string. + * + * Data is stored as an array of arrays and not a simple associative array, + * because some drivers (e.g. mysql) allow multiple parameters with the same + * key to be set. + * @link https://github.com/ADOdb/ADOdb/issues/187 + * + * @see setConnectionParameter() + * + * @var array $connectionParameters Set of ParameterName => Value pairs + */ + protected $connectionParameters = array(); /** * Default Constructor. @@ -520,29 +522,29 @@ if (!defined('_ADODB_LAYER')) { { } - /* - * Additional parameters that may be passed to drivers in the connect string - * Driver must be coded to accept the parameters - */ - protected $connectionParameters = array(); - /** - * Adds a parameter to the connection string. - * - * These parameters are added to the connection string when connecting, - * if the driver is coded to use it. - * - * @param string $parameter The name of the parameter to set - * @param string $value The value of the parameter - * - * @return null - * - * @example, for mssqlnative driver ('CharacterSet','UTF-8') - */ - final public function setConnectionParameter($parameter,$value) { - + * Adds a parameter to the connection string. + * + * Parameters must be added before the connection is established; + * they are then passed on to the connect statement, which will. + * process them if the driver supports this feature. + * + * Example usage: + * - mssqlnative: setConnectionParameter('CharacterSet','UTF-8'); + * - mysqli: setConnectionParameter(MYSQLI_SET_CHARSET_NAME,'utf8mb4'); + * + * If used in a portable environment, parameters set in this manner should + * be predicated on the database provider, as unexpected results may occur + * if applied to the wrong database. + * + * @param string $parameter The name of the parameter to set + * @param string $value The value of the parameter + * + * @return bool True if success, false otherwise (e.g. parameter is not valid) + */ + public function setConnectionParameter($parameter, $value) { $this->connectionParameters[] = array($parameter=>$value); - + return true; } /** @@ -1302,6 +1304,7 @@ if (!defined('_ADODB_LAYER')) { if( is_string($sql) ) { // Strips keyword used to help generate SELECT COUNT(*) queries // from SQL if it exists. + // TODO: obsoleted by #715 - kept for backwards-compatibility $sql = str_replace( '_ADODB_COUNT', '', $sql ); } @@ -1443,7 +1446,7 @@ if (!defined('_ADODB_LAYER')) { return $this->lastInsID; } if ($this->hasInsertID) { - return $this->_insertid($table,$column); + return $this->_insertID($table,$column); } if ($this->debug) { ADOConnection::outp( '

Insert_ID error

'); @@ -1452,14 +1455,35 @@ if (!defined('_ADODB_LAYER')) { return false; } + /** + * Enable or disable the Last Insert Id functionality. + * + * If the Driver supports it, this function allows setting {@see $hasInsertID}. + * + * @param bool $enable False to disable + */ + public function enableLastInsertID($enable = true) {} + + /** + * Return the id of the last row that has been inserted in a table. + * + * @param string $table + * @param string $column + * + * @return int|false + */ + protected function _insertID($table = '', $column = '') + { + return false; + } /** * Portable Insert ID. Pablo Roca * * @param string $table * @param string $id - - * @return mixed The last inserted ID. All databases support this, but be + + * @return mixed The last inserted ID. All databases support this, but be * aware of possible problems in multiuser environments. * Heavily test this before deploying. */ @@ -1648,17 +1672,19 @@ if (!defined('_ADODB_LAYER')) { // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS. global $ADODB_COUNTRECS; - $savec = $ADODB_COUNTRECS; - $ADODB_COUNTRECS = false; + try { + $savec = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; - - if ($secs2cache != 0) { - $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); - } else { - $rs = $this->Execute($sql,$inputarr); + if ($secs2cache != 0) { + $rs = $this->CacheExecute($secs2cache, $sql, $inputarr); + } else { + $rs = $this->Execute($sql, $inputarr); + } + } finally { + $ADODB_COUNTRECS = $savec; } - $ADODB_COUNTRECS = $savec; if ($rs && !$rs->EOF) { $rs = $this->_rs2rs($rs,$nrows,$offset); } @@ -1805,11 +1831,15 @@ if (!defined('_ADODB_LAYER')) { public function GetOne($sql, $inputarr=false) { global $ADODB_COUNTRECS,$ADODB_GETONE_EOF; - $crecs = $ADODB_COUNTRECS; - $ADODB_COUNTRECS = false; + try { + $crecs = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + $rs = $this->Execute($sql, $inputarr); + } finally { + $ADODB_COUNTRECS = $crecs; + } $ret = false; - $rs = $this->Execute($sql,$inputarr); if ($rs) { if ($rs->EOF) { $ret = $ADODB_GETONE_EOF; @@ -1819,7 +1849,6 @@ if (!defined('_ADODB_LAYER')) { $rs->Close(); } - $ADODB_COUNTRECS = $crecs; return $ret; } @@ -1948,10 +1977,14 @@ if (!defined('_ADODB_LAYER')) { function GetArray($sql,$inputarr=false) { global $ADODB_COUNTRECS; - $savec = $ADODB_COUNTRECS; - $ADODB_COUNTRECS = false; - $rs = $this->Execute($sql,$inputarr); - $ADODB_COUNTRECS = $savec; + try { + $savec = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + $rs = $this->Execute($sql, $inputarr); + } finally { + $ADODB_COUNTRECS = $savec; + } + if (!$rs) if (defined('ADODB_PEAR')) { return ADODB_PEAR_Error(); @@ -1970,10 +2003,13 @@ if (!defined('_ADODB_LAYER')) { function CacheGetArray($secs2cache,$sql=false,$inputarr=false) { global $ADODB_COUNTRECS; - $savec = $ADODB_COUNTRECS; - $ADODB_COUNTRECS = false; - $rs = $this->CacheExecute($secs2cache,$sql,$inputarr); - $ADODB_COUNTRECS = $savec; + try { + $savec = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + $rs = $this->CacheExecute($secs2cache, $sql, $inputarr); + } finally { + $ADODB_COUNTRECS = $savec; + } if (!$rs) if (defined('ADODB_PEAR')) { @@ -2004,12 +2040,14 @@ if (!defined('_ADODB_LAYER')) { function GetRow($sql,$inputarr=false) { global $ADODB_COUNTRECS; - $crecs = $ADODB_COUNTRECS; - $ADODB_COUNTRECS = false; + try { + $crecs = $ADODB_COUNTRECS; + $ADODB_COUNTRECS = false; + $rs = $this->Execute($sql, $inputarr); + } finally { + $ADODB_COUNTRECS = $crecs; + } - $rs = $this->Execute($sql,$inputarr); - - $ADODB_COUNTRECS = $crecs; if ($rs) { if (!$rs->EOF) { $arr = $rs->fields; @@ -2467,11 +2505,26 @@ if (!defined('_ADODB_LAYER')) { return $blob; } - function GetCharSet() { + /** + * Retrieve the client connection's current character set. + * + * @return string|false The character set, or false if it can't be determined. + */ + function getCharSet() { return $this->charSet; } - function SetCharSet($charset) { + /** + * Sets the client-side character set. + * + * This is only supported for some databases. + * @see https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:setcharset + * + * @param string $charset The character set to switch to. + * + * @return bool True if the character set was changed successfully, false otherwise. + */ + function setCharSet($charset) { $this->charSet = $charset; return true; } @@ -3390,26 +3443,32 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $this->rs = $rs; } + #[\ReturnTypeWillChange] function rewind() {} + #[\ReturnTypeWillChange] function valid() { return !$this->rs->EOF; } + #[\ReturnTypeWillChange] function key() { return false; } + #[\ReturnTypeWillChange] function current() { return false; } + #[\ReturnTypeWillChange] function next() {} function __call($func, $params) { return call_user_func_array(array($this->rs, $func), $params); } + #[\ReturnTypeWillChange] function hasMore() { return false; } @@ -3456,6 +3515,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 function Init() {} + #[\ReturnTypeWillChange] function getIterator() { return new ADODB_Iterator_empty($this); } @@ -3516,22 +3576,27 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $this->rs = $rs; } + #[\ReturnTypeWillChange] function rewind() { $this->rs->MoveFirst(); } + #[\ReturnTypeWillChange] function valid() { return !$this->rs->EOF; } + #[\ReturnTypeWillChange] function key() { return $this->rs->_currentRow; } + #[\ReturnTypeWillChange] function current() { return $this->rs->fields; } + #[\ReturnTypeWillChange] function next() { $this->rs->MoveNext(); } @@ -3581,7 +3646,8 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 */ var $_numOfRows = -1; /** number of rows, or -1 */ var $_numOfFields = -1; /** number of fields in recordset */ - var $_queryID = -1; /** This variable keeps the result link identifier. */ + /** @var resource result link identifier */ + var $_queryID = -1; var $_currentRow = -1; /** This variable keeps the current row in the Recordset. */ var $_closed = false; /** has recordset been closed */ var $_inited = false; /** Init() should only be called once */ @@ -3595,6 +3661,12 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 var $_maxRecordCount = 0; var $datetime = false; + /** + * @var ADOFieldObject[] Field metadata cache + * @see fieldTypesArray() + */ + protected $fieldObjectsCache; + /** * Constructor * @@ -3609,6 +3681,7 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 $this->Close(); } + #[\ReturnTypeWillChange] function getIterator() { return new ADODB_Iterator($this); } @@ -4399,30 +4472,31 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 } /** - * Get the ADOFieldObject of a specific column. + * Get a Field's metadata from database. * - * @param fieldoffset is the column position to access(0-based). + * Must be defined by child class. * - * @return the ADOFieldObject for that column, or false. + * @param int $fieldOffset + * + * @return ADOFieldObject|false */ - function FetchField($fieldoffset = -1) { - // must be defined by child class - + function fetchField($fieldOffset) + { return false; } /** - * Get the ADOFieldObjects of all columns in an array. + * Get Field metadata for all the recordset's columns in an array. * + * @return ADOFieldObject[] */ - function FieldTypesArray() { - static $arr = array(); - if (empty($arr)) { - for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) { - $arr[] = $this->FetchField($i); + function fieldTypesArray() { + if (empty($this->fieldObjectsCache)) { + for ($i = 0; $i < $this->_numOfFields; $i++) { + $this->fieldObjectsCache[] = $this->fetchField($i); } } - return $arr; + return $this->fieldObjectsCache; } /** @@ -5101,13 +5175,13 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 if (!defined('ADODB_ASSOC_CASE')) { define('ADODB_ASSOC_CASE', ADODB_ASSOC_CASE_NATIVE); } - + /* * Are there special characters in the dsn password * that disrupt parse_url */ $needsSpecialCharacterHandling = false; - + $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false; if (($at = strpos($db,'://')) !== FALSE) { $origdsn = $db; @@ -5134,23 +5208,23 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 * Stop # character breaking parse_url */ $cFakedsn = str_replace('#','\035',$fakedsn); - if (strcmp($fakedsn,$cFakedsn) != 0) + if (strcmp($fakedsn,$cFakedsn) != 0) { /* * There is a # in the string */ $needsSpecialCharacterHandling = true; - + /* * This allows us to successfully parse the url */ $fakedsn = $cFakedsn; - + } - + $dsna = parse_url($fakedsn); } - + if (!$dsna) { return false; } @@ -5176,13 +5250,13 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 if (!$db) { return false; } - + $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : ''; $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : ''; $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : ''; $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : ''; # strip off initial / - if ($needsSpecialCharacterHandling) + if ($needsSpecialCharacterHandling) { /* * Revert back to the original string @@ -5388,7 +5462,15 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 return new $class($conn); } - function NewDataDictionary(&$conn,$drivername=false) { + /** + * Get a new Data Dictionary object for the connection. + * + * @param ADOConnection $conn + * @param string $drivername + * + * @return ADODB_DataDict|false + */ + function newDataDictionary(&$conn, $drivername='') { if (!$drivername) { $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType); } @@ -5415,8 +5497,6 @@ http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_1 return $dict; } - - /* Perform a print_r, with pre tags for better formatting. */ diff --git a/lib/adodb/datadict/datadict-access.inc.php b/lib/adodb/datadict/datadict-access.inc.php index 2291f01d8ea..7a7d4cbbdc8 100644 --- a/lib/adodb/datadict/datadict-access.inc.php +++ b/lib/adodb/datadict/datadict-access.inc.php @@ -1,16 +1,23 @@ type; - $len = $fieldobj->max_length; } $_typeConversion = array( @@ -97,11 +105,11 @@ class ADODB2_mssqlnative extends ADODB_DataDict { -3 => 'X' ); - if (isset($_typeConversion[$t])) - return $_typeConversion[$t]; - - return ADODB_DEFAULT_METATYPE; + if (isset($_typeConversion[$t])) { + return $_typeConversion[$t]; + } + return ADODB_DEFAULT_METATYPE; } function ActualType($meta) @@ -141,7 +149,7 @@ class ADODB2_mssqlnative extends ADODB_DataDict { { $tabname = $this->TableName ($tabname); $f = array(); - list($lines,$pkey) = $this->_GenFields($flds); + list($lines,) = $this->_GenFields($flds); $s = "ALTER TABLE $tabname $this->addCol"; foreach($lines as $v) { $f[] = "\n $v"; @@ -151,30 +159,29 @@ class ADODB2_mssqlnative extends ADODB_DataDict { return $sql; } - function DefaultConstraintname($tabname, $colname) + /** + * Get a column's default constraint. + * + * @param string $tabname + * @param string $colname + * @return string|null The Constraint's name, or null if there is none. + */ + function defaultConstraintName($tabname, $colname) { - $constraintname = false; - $rs = $this->connection->Execute( - "SELECT name FROM sys.default_constraints - WHERE object_name(parent_object_id) = '$tabname' - AND col_name(parent_object_id, parent_column_id) = '$colname'" - ); - if ( is_object($rs) ) { - $row = $rs->FetchRow(); - $constraintname = $row['name']; - } - return $constraintname; + $sql = "SELECT name FROM sys.default_constraints + WHERE object_name(parent_object_id) = ? + AND col_name(parent_object_id, parent_column_id) = ?"; + return $this->connection->getOne($sql, [$tabname, $colname]); } - + function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') { $tabname = $this->TableName ($tabname); $sql = array(); - list($lines,$pkey,$idxs) = $this->_GenFields($flds); + list($lines,,$idxs) = $this->_GenFields($flds); $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; foreach($lines as $v) { - $not_null = false; if ($not_null = preg_match('/NOT NULL/i',$v)) { $v = preg_replace('/NOT NULL/i','',$v); } @@ -182,7 +189,7 @@ class ADODB2_mssqlnative extends ADODB_DataDict { list(,$colname,$default) = $matches; $v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v); $t = trim(str_replace('DEFAULT '.$default,'',$v)); - if ( $constraintname = $this->DefaultConstraintname($tabname,$colname) ) { + if ( $constraintname = $this->defaultConstraintName($tabname,$colname) ) { $sql[] = 'ALTER TABLE '.$tabname.' DROP CONSTRAINT '. $constraintname; } if ($not_null) { @@ -195,7 +202,7 @@ class ADODB2_mssqlnative extends ADODB_DataDict { . ' DEFAULT ' . $default . ' FOR ' . $colname; } else { $colname = strtok($v," "); - if ( $constraintname = $this->DefaultConstraintname($tabname,$colname) ) { + if ( $constraintname = $this->defaultConstraintName($tabname,$colname) ) { $sql[] = 'ALTER TABLE '.$tabname.' DROP CONSTRAINT '. $constraintname; } if ($not_null) { @@ -223,17 +230,19 @@ class ADODB2_mssqlnative extends ADODB_DataDict { * @param string $tableflds Throwaway value to make the function match the parent * @param string $tableoptions Throway value to make the function match the parent * - * @return string The SQL necessary to drop the column + * @return string[] The SQL necessary to drop the column */ function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') { $tabname = $this->TableName ($tabname); - if (!is_array($flds)) - $flds = explode(',',$flds); + if (!is_array($flds)) { + /** @noinspection PhpParamsInspection */ + $flds = explode(',', $flds); + } $f = array(); $s = 'ALTER TABLE ' . $tabname; foreach($flds as $v) { - if ( $constraintname = $this->DefaultConstraintname($tabname,$v) ) { + if ( $constraintname = $this->defaultConstraintName($tabname,$v) ) { $sql[] = 'ALTER TABLE ' . $tabname . ' DROP CONSTRAINT ' . $constraintname; } $f[] = ' DROP COLUMN ' . $this->NameQuote($v); @@ -244,6 +253,8 @@ class ADODB2_mssqlnative extends ADODB_DataDict { } // return string must begin with space + + /** @noinspection DuplicatedCode */ function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned) { $suffix = ''; @@ -255,78 +266,7 @@ class ADODB2_mssqlnative extends ADODB_DataDict { return $suffix; } - /* -CREATE TABLE - [ database_name.[ owner ] . | owner. ] table_name - ( { < column_definition > - | column_name AS computed_column_expression - | < table_constraint > ::= [ CONSTRAINT constraint_name ] } - - | [ { PRIMARY KEY | UNIQUE } [ ,...n ] - ) - -[ ON { filegroup | DEFAULT } ] -[ TEXTIMAGE_ON { filegroup | DEFAULT } ] - -< column_definition > ::= { column_name data_type } - [ COLLATE < collation_name > ] - [ [ DEFAULT constant_expression ] - | [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ] - ] - [ ROWGUIDCOL] - [ < column_constraint > ] [ ...n ] - -< column_constraint > ::= [ CONSTRAINT constraint_name ] - { [ NULL | NOT NULL ] - | [ { PRIMARY KEY | UNIQUE } - [ CLUSTERED | NONCLUSTERED ] - [ WITH FILLFACTOR = fillfactor ] - [ON {filegroup | DEFAULT} ] ] - ] - | [ [ FOREIGN KEY ] - REFERENCES ref_table [ ( ref_column ) ] - [ ON DELETE { CASCADE | NO ACTION } ] - [ ON UPDATE { CASCADE | NO ACTION } ] - [ NOT FOR REPLICATION ] - ] - | CHECK [ NOT FOR REPLICATION ] - ( logical_expression ) - } - -< table_constraint > ::= [ CONSTRAINT constraint_name ] - { [ { PRIMARY KEY | UNIQUE } - [ CLUSTERED | NONCLUSTERED ] - { ( column [ ASC | DESC ] [ ,...n ] ) } - [ WITH FILLFACTOR = fillfactor ] - [ ON { filegroup | DEFAULT } ] - ] - | FOREIGN KEY - [ ( column [ ,...n ] ) ] - REFERENCES ref_table [ ( ref_column [ ,...n ] ) ] - [ ON DELETE { CASCADE | NO ACTION } ] - [ ON UPDATE { CASCADE | NO ACTION } ] - [ NOT FOR REPLICATION ] - | CHECK [ NOT FOR REPLICATION ] - ( search_conditions ) - } - - - */ - - /* - CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name - ON { table | view } ( column [ ASC | DESC ] [ ,...n ] ) - [ WITH < index_option > [ ,...n] ] - [ ON filegroup ] - < index_option > :: = - { PAD_INDEX | - FILLFACTOR = fillfactor | - IGNORE_DUP_KEY | - DROP_EXISTING | - STATISTICS_NORECOMPUTE | - SORT_IN_TEMPDB - } -*/ + /** @noinspection DuplicatedCode */ function _IndexSQL($idxname, $tabname, $flds, $idxoptions) { $sql = array(); @@ -358,17 +298,18 @@ CREATE TABLE } - function _GetSize($ftype, $ty, $fsize, $fprec,$options=false) + function _GetSize($ftype, $ty, $fsize, $fprec, $options=false) { switch ($ftype) { - case 'INT': - case 'SMALLINT': - case 'TINYINT': - case 'BIGINT': + case 'INT': + case 'SMALLINT': + case 'TINYINT': + case 'BIGINT': + return $ftype; + } + if ($ty == 'T') { return $ftype; } - if ($ty == 'T') return $ftype; - return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options); - + return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options); } } diff --git a/lib/adodb/datadict/datadict-mysql.inc.php b/lib/adodb/datadict/datadict-mysql.inc.php index 58f1110265b..a1ee950a6ba 100644 --- a/lib/adodb/datadict/datadict-mysql.inc.php +++ b/lib/adodb/datadict/datadict-mysql.inc.php @@ -1,16 +1,23 @@ TableName ($tabname); + $tabname = $this->tableName($tabname); $sql = array(); $not_null = false; - list($lines,$pkey) = $this->_GenFields($flds); + list($lines,$pkey) = $this->_genFields($flds); $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; foreach($lines as $v) { if (($not_null = preg_match('/NOT NULL/i',$v))) { @@ -159,9 +166,9 @@ class ADODB2_postgres extends ADODB_DataDict { } - function DropIndexSQL ($idxname, $tabname = NULL) + function dropIndexSQL($idxname, $tabname = NULL) { - return array(sprintf($this->dropIndex, $this->TableName($idxname), $this->TableName($tabname))); + return array(sprintf($this->dropIndex, $this->tableName($idxname), $this->tableName($tabname))); } /** @@ -175,25 +182,15 @@ class ADODB2_postgres extends ADODB_DataDict { * @param array/ $tableoptions options for the new table see CreateTableSQL, default '' * @return array with SQL strings */ - /* - function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') - { - if (!$tableflds) { - if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL"); - return array(); - } - return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions); - }*/ - - function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + function alterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='') { // Check if alter single column datatype available - works with 8.0+ $has_alter_column = 8.0 <= (float) @$this->serverInfo['version']; if ($has_alter_column) { - $tabname = $this->TableName($tabname); + $tabname = $this->tableName($tabname); $sql = array(); - list($lines,$pkey) = $this->_GenFields($flds); + list($lines,$pkey) = $this->_genFields($flds); $set_null = false; foreach($lines as $v) { $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; @@ -211,13 +208,12 @@ class ADODB2_postgres extends ADODB_DataDict { } if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) { - $existing = $this->MetaColumns($tabname); + $existing = $this->metaColumns($tabname); list(,$colname,$default) = $matches; $alter .= $colname; if ($this->connection) { - $old_coltype = $this->connection->MetaType($existing[strtoupper($colname)]); - } - else { + $old_coltype = $this->connection->metaType($existing[strtoupper($colname)]); + } else { $old_coltype = $t; } $v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v); @@ -253,7 +249,7 @@ class ADODB2_postgres extends ADODB_DataDict { $sql[] = $alter . ' TYPE ' . $rest; } -# list($colname) = explode(' ',$v); + #list($colname) = explode(' ',$v); if ($not_null) { // this does not error out if the column is already not null $sql[] = $alter . ' SET NOT NULL'; @@ -271,7 +267,7 @@ class ADODB2_postgres extends ADODB_DataDict { if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL"); return array(); } - return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions); + return $this->_recreate_copy_table($tabname, false, $tableflds,$tableoptions); } /** @@ -285,17 +281,19 @@ class ADODB2_postgres extends ADODB_DataDict { * @param array/ $tableoptions options for the new table see CreateTableSQL, default '' * @return array with SQL strings */ - function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + function dropColumnSQL($tabname, $flds, $tableflds='', $tableoptions='') { $has_drop_column = 7.3 <= (float) @$this->serverInfo['version']; if (!$has_drop_column && !$tableflds) { - if ($this->debug) ADOConnection::outp("DropColumnSQL needs complete table-definiton for PostgreSQL < 7.3"); - return array(); - } - if ($has_drop_column) { - return ADODB_DataDict::DropColumnSQL($tabname, $flds); + if ($this->debug) { + ADOConnection::outp("dropColumnSQL needs complete table-definiton for PostgreSQL < 7.3"); + } + return array(); } - return $this->_recreate_copy_table($tabname,$flds,$tableflds,$tableoptions); + if ($has_drop_column) { + return ADODB_DataDict::dropColumnSQL($tabname, $flds); + } + return $this->_recreate_copy_table($tabname, $flds, $tableflds, $tableoptions); } /** @@ -310,11 +308,11 @@ class ADODB2_postgres extends ADODB_DataDict { * @param array/string $tableoptions options for the new table see CreateTableSQL, default '' * @return array with SQL strings */ - function _recreate_copy_table($tabname,$dropflds,$tableflds,$tableoptions='') + function _recreate_copy_table($tabname, $dropflds, $tableflds, $tableoptions='') { if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds); $copyflds = array(); - foreach($this->MetaColumns($tabname) as $fld) { + foreach($this->metaColumns($tabname) as $fld) { if (preg_match('/'.$fld->name.' (\w+)/i', $tableflds, $matches)) { $new_type = strtoupper($matches[1]); // AlterColumn of a char column to a nummeric one needs an explicit conversation @@ -324,7 +322,7 @@ class ADODB2_postgres extends ADODB_DataDict { $copyflds[] = "to_number($fld->name,'S9999999999999D99')"; } else { // other column-type changes needs explicit decode, encode for bytea or cast otherwise - $new_actual_type = $this->ActualType($new_type); + $new_actual_type = $this->actualType($new_type); if (strtoupper($fld->type) != $new_actual_type) { if ($new_actual_type == 'BYTEA' && $fld->type == 'text') { $copyflds[] = "DECODE($fld->name, 'escape')"; @@ -340,48 +338,48 @@ class ADODB2_postgres extends ADODB_DataDict { } // identify the sequence name and the fld its on if ($fld->primary_key && $fld->has_default && - preg_match("/nextval\('([^']+)'::(text|regclass)\)/",$fld->default_value,$matches)) { + preg_match("/nextval\('([^']+)'::(text|regclass)\)/", $fld->default_value, $matches)) { $seq_name = $matches[1]; $seq_fld = $fld->name; } } - $copyflds = implode(', ',$copyflds); + $copyflds = implode(', ', $copyflds); $tempname = $tabname.'_tmp'; $aSql[] = 'BEGIN'; // we use a transaction, to make sure not to loose the content of the table $aSql[] = "SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname"; - $aSql = array_merge($aSql,$this->DropTableSQL($tabname)); - $aSql = array_merge($aSql,$this->CreateTableSQL($tabname,$tableflds,$tableoptions)); + $aSql = array_merge($aSql,$this->dropTableSQL($tabname)); + $aSql = array_merge($aSql,$this->createTableSQL($tabname, $tableflds, $tableoptions)); $aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname"; if ($seq_name && $seq_fld) { // if we have a sequence we need to set it again $seq_name = $tabname.'_'.$seq_fld.'_seq'; // has to be the name of the new implicit sequence - $aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname"; + $aSql[] = "SELECT setval('$seq_name', MAX($seq_fld)) FROM $tabname"; } $aSql[] = "DROP TABLE $tempname"; // recreate the indexes, if they not contain one of the dropped columns - foreach($this->MetaIndexes($tabname) as $idx_name => $idx_data) - { + foreach($this->metaIndexes($tabname) as $idx_name => $idx_data) { if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) { - $aSql = array_merge($aSql,$this->CreateIndexSQL($idx_name,$tabname,$idx_data['columns'], - $idx_data['unique'] ? array('UNIQUE') : False)); + $aSql = array_merge($aSql,$this->createIndexSQL($idx_name, $tabname, $idx_data['columns'], + $idx_data['unique'] ? array('UNIQUE') : false)); } } $aSql[] = 'COMMIT'; return $aSql; } - function DropTableSQL($tabname) + function dropTableSQL($tabname) { - $sql = ADODB_DataDict::DropTableSQL($tabname); - - $drop_seq = $this->_DropAutoIncrement($tabname); - if ($drop_seq) $sql[] = $drop_seq; + $sql = ADODB_DataDict::dropTableSQL($tabname); + $drop_seq = $this->_dropAutoIncrement($tabname); + if ($drop_seq) { + $sql[] = $drop_seq; + } return $sql; } // return string must begin with space - function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned) + function _createSuffix($fname, &$ftype, $fnotnull, $fdefault, $fautoinc, $fconstraint, $funsigned) { if ($fautoinc) { $ftype = 'SERIAL'; @@ -397,31 +395,31 @@ class ADODB2_postgres extends ADODB_DataDict { // search for a sequence for the given table (asumes the seqence-name contains the table-name!) // if yes return sql to drop it // this is still necessary if postgres < 7.3 or the SERIAL was created on an earlier version!!! - function _DropAutoIncrement($tabname) + function _dropAutoIncrement($tabname) { $tabname = $this->connection->quote('%'.$tabname.'%'); - $seq = $this->connection->GetOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'"); + $seq = $this->connection->getOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'"); // check if a tables depends on the sequence and it therefore can't and don't need to be dropped separately - if (!$seq || $this->connection->GetOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) { - return False; + if (!$seq || $this->connection->getOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) { + return false; } return "DROP SEQUENCE ".$seq; } - function RenameTableSQL($tabname,$newname) + function renameTableSQL($tabname, $newname) { if (!empty($this->schema)) { - $rename_from = $this->TableName($tabname); + $rename_from = $this->tableName($tabname); $schema_save = $this->schema; $this->schema = false; - $rename_to = $this->TableName($newname); + $rename_to = $this->tableName($newname); $this->schema = $schema_save; return array (sprintf($this->renameTable, $rename_from, $rename_to)); } - return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname))); + return array (sprintf($this->renameTable, $this->tableName($tabname), $this->tableName($newname))); } /* @@ -457,17 +455,18 @@ CREATE [ UNIQUE ] INDEX index_name ON table [ USING acc_method ] ( func_name( column [, ... ]) [ ops_name ] ) [ WHERE predicate ] */ - function _IndexSQL($idxname, $tabname, $flds, $idxoptions) + function _indexSQL($idxname, $tabname, $flds, $idxoptions) { $sql = array(); if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) { $sql[] = sprintf ($this->dropIndex, $idxname, $tabname); - if ( isset($idxoptions['DROP']) ) + if ( isset($idxoptions['DROP']) ) { return $sql; + } } - if ( empty ($flds) ) { + if (empty($flds)) { return $sql; } @@ -475,21 +474,24 @@ CREATE [ UNIQUE ] INDEX index_name ON table $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' '; - if (isset($idxoptions['HASH'])) + if (isset($idxoptions['HASH'])) { $s .= 'USING HASH '; - - if ( isset($idxoptions[$this->upperName]) ) + } + + if (isset($idxoptions[$this->upperName])) { $s .= $idxoptions[$this->upperName]; - - if ( is_array($flds) ) - $flds = implode(', ',$flds); + } + + if (is_array($flds)) { + $flds = implode(', ', $flds); + } $s .= '(' . $flds . ')'; $sql[] = $s; return $sql; } - function _GetSize($ftype, $ty, $fsize, $fprec, $options=false) + function _getSize($ftype, $ty, $fsize, $fprec, $options=false) { if (strlen($fsize) && $ty != 'X' && $ty != 'B' && $ty != 'I' && strpos($ftype,'(') === false) { $ftype .= "(".$fsize; @@ -500,16 +502,12 @@ CREATE [ UNIQUE ] INDEX index_name ON table /* * Handle additional options */ - if (is_array($options)) - { - foreach($options as $type=>$value) - { - switch ($type) - { + if (is_array($options)) { + foreach($options as $type=>$value) { + switch ($type) { case 'ENUM': - $ftype .= '(' . $value . ')'; - break; - + $ftype .= '(' . $value . ')'; + break; default: } } @@ -517,41 +515,45 @@ CREATE [ UNIQUE ] INDEX index_name ON table return $ftype; } - function ChangeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false){ + function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false) + { global $ADODB_FETCH_MODE; - parent::ChangeTableSQL($tablename, $flds); + parent::changeTableSQL($tablename, $flds); $save = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; - if ($this->connection->fetchMode !== false) - $savem = $this->connection->SetFetchMode(false); + if ($this->connection->fetchMode !== false) { + $savem = $this->connection->setFetchMode(false); + } // check table exists $save_handler = $this->connection->raiseErrorFn; $this->connection->raiseErrorFn = ''; - $cols = $this->MetaColumns($tablename); + $cols = $this->metaColumns($tablename); $this->connection->raiseErrorFn = $save_handler; - if (isset($savem)) - $this->connection->SetFetchMode($savem); + if (isset($savem)) { + $this->connection->setFetchMode($savem); + } $ADODB_FETCH_MODE = $save; $sqlResult=array(); if ( empty($cols)) { - $sqlResult=$this->CreateTableSQL($tablename, $flds, $tableoptions); + $sqlResult=$this->createTableSQL($tablename, $flds, $tableoptions); } else { - $sqlResultAdd = $this->AddColumnSQL($tablename, $flds); - $sqlResultAlter = $this->AlterColumnSQL($tablename, $flds, '', $tableoptions); + $sqlResultAdd = $this->addColumnSQL($tablename, $flds); + $sqlResultAlter = $this->alterColumnSQL($tablename, $flds, '', $tableoptions); $sqlResult = array_merge((array)$sqlResultAdd, (array)$sqlResultAlter); if ($dropOldFlds) { // already exists, alter table instead - list($lines,$pkey,$idxs) = $this->_GenFields($flds); + list($lines,$pkey,$idxs) = $this->_genFields($flds); // genfields can return FALSE at times - if ($lines == null) + if ($lines == null) { $lines = array(); - $alter = 'ALTER TABLE ' . $this->TableName($tablename); - foreach ( $cols as $id => $v ){ - if ( !isset($lines[$id]) ){ + } + $alter = 'ALTER TABLE ' . $this->tableName($tablename); + foreach ( $cols as $id => $v ) { + if ( !isset($lines[$id]) ) { $sqlResult[] = $alter . $this->dropCol . ' ' . $v->name; } } @@ -560,4 +562,4 @@ CREATE [ UNIQUE ] INDEX index_name ON table } return $sqlResult; } -} +} // end class diff --git a/lib/adodb/datadict/datadict-sapdb.inc.php b/lib/adodb/datadict/datadict-sapdb.inc.php index 392d174c065..20c16aa6c50 100644 --- a/lib/adodb/datadict/datadict-sapdb.inc.php +++ b/lib/adodb/datadict/datadict-sapdb.inc.php @@ -1,17 +1,23 @@ GetOne('select SCOPE_IDENTITY()'); } diff --git a/lib/adodb/drivers/adodb-ads.inc.php b/lib/adodb/drivers/adodb-ads.inc.php index c87f5e25661..b9d4adb522f 100644 --- a/lib/adodb/drivers/adodb-ads.inc.php +++ b/lib/adodb/drivers/adodb-ads.inc.php @@ -1,20 +1,29 @@ _insertid; } diff --git a/lib/adodb/drivers/adodb-db2.inc.php b/lib/adodb/drivers/adodb-db2.inc.php index 6618c87aade..8f616fa6f82 100644 --- a/lib/adodb/drivers/adodb-db2.inc.php +++ b/lib/adodb/drivers/adodb-db2.inc.php @@ -1,36 +1,40 @@ doDB2Connect($argDSN, $argUsername, $argPassword, $argDatabasename); } - + public function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) { return $this->doDB2Connect($argDSN, $argUsername, $argPassword, $argDatabasename,true); } - + private function doDB2Connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persistent=false) { global $php_errormsg; @@ -115,26 +119,26 @@ class ADODB_db2 extends ADOConnection { ADOConnection::outp("DB2 extension not installed."); return null; } - - $connectionParameters = $this->unpackParameters($argDSN, - $argUsername, - $argPassword, - $argDatabasename); - + + $connectionParameters = $this->unpackParameters($argDSN, + $argUsername, + $argPassword, + $argDatabasename); + if ($connectionParameters == null) { /* - * Error thrown + * Error thrown */ return null; } - + $argDSN = $connectionParameters['dsn']; $argUsername = $connectionParameters['uid']; $argPassword = $connectionParameters['pwd']; $argDatabasename = $connectionParameters['database']; $useCataloguedConnection = $connectionParameters['catalogue']; - + if ($this->debug){ if ($useCataloguedConnection){ $connectMessage = "Catalogued connection using parameters: "; @@ -143,13 +147,13 @@ class ADODB_db2 extends ADOConnection { $connectMessage .= "PWD=$argPassword"; } else - { + { $connectMessage = "Uncatalogued connection using DSN: $argDSN"; } ADOConnection::outp($connectMessage); - } + } /* - * This needs to be set before the connect(). + * This needs to be set before the connect(). */ ini_set('ibm_db2.binmode', $this->binmode); @@ -157,7 +161,7 @@ class ADODB_db2 extends ADOConnection { $db2Function = 'db2_pconnect'; else $db2Function = 'db2_connect'; - + /* * We need to flatten out the connectionParameters */ @@ -169,29 +173,29 @@ class ADODB_db2 extends ADOConnection { foreach($p as $k=>$v) $db2Options[$k] = $v; } - + if ($useCataloguedConnection) $this->_connectionID = $db2Function($argDatabasename, - $argUsername, - $argPassword, - $db2Options); + $argUsername, + $argPassword, + $db2Options); else $this->_connectionID = $db2Function($argDSN, - null, - null, - $db2Options); - + null, + null, + $db2Options); + $php_errormsg = ''; $this->_errorMsg = @db2_conn_errormsg(); - + if ($this->_connectionID && $this->connectStmt) $this->execute($this->connectStmt); return $this->_connectionID != false; - - } - + + } + /** * Validates and preprocesses the passed parameters for consistency * @@ -204,23 +208,23 @@ class ADODB_db2 extends ADOConnection { */ private function unpackParameters($argDSN, $argUsername, $argPassword, $argDatabasename) { - + global $php_errormsg; - + $connectionParameters = array('dsn'=>'', 'uid'=>'', 'pwd'=>'', 'database'=>'', 'catalogue'=>true ); - + /* * Uou can either connect to a catalogued connection - * with a database name e.g. 'SAMPLE' - * or an uncatalogued connection with a DSN like connection + * with a database name e.g. 'SAMPLE' + * or an uncatalogued connection with a DSN like connection * DATABASE=database;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=username;PWD=password; */ - + if (!$argDSN && !$argDatabasename) { $errorMessage = 'Supply either catalogued or uncatalogued connection parameters'; @@ -229,14 +233,14 @@ class ADODB_db2 extends ADOConnection { ADOConnection::outp($errorMessage); return null; } - + $useCataloguedConnection = true; $schemaName = ''; - + if ($argDSN && $argDatabasename) { /* - * If a catalogued connection if provided, + * If a catalogued connection if provided, * as well as user and password * that will take priority */ @@ -247,7 +251,7 @@ class ADODB_db2 extends ADOConnection { $errorMessage.= 'password and database, DSN connection '; $errorMessage.= 'parameters were discarded'; ADOConnection::outp($errorMessage); - + } $argDSN = ''; } @@ -262,7 +266,7 @@ class ADODB_db2 extends ADOConnection { return null; } } - + if (!$this->isDsn($argDSN) && $this->isDsn($argDatabasename)) { /* @@ -272,11 +276,11 @@ class ADODB_db2 extends ADOConnection { $argDsn = $argDatabasename; $argDatabasenME = $temp; } - + if ($this->isDsn($argDSN)) { - - if (!preg_match('/uid=/i',$argDSN) + + if (!preg_match('/uid=/i',$argDSN) || !preg_match('/pwd=/i',$argDSN)) { $errorMessage = 'For uncatalogued connections, provide '; @@ -286,11 +290,11 @@ class ADODB_db2 extends ADOConnection { ADOConnection::outp($errorMessage); return null; } - + if (preg_match('/database=/i',$argDSN)) { if ($argDatabasename) - { + { $argDatabasename = ''; if ($this->debug) { @@ -300,19 +304,19 @@ class ADODB_db2 extends ADOConnection { $errorMessage.= 'name was discarded'; ADOConnection::outp($errorMessage); } - } + } $useCataloguedConnection = false; - - } + + } elseif ($argDatabasename) { $this->databaseName = $argDatabasename; $argDSN .= ';database=' . $argDatabasename; $argDatabasename = ''; $useCataloguedConnection = false; - - } - else + + } + else { $errorMessage = 'Uncatalogued connection parameters '; $errorMessage.= 'must contain a database= argument'; @@ -322,44 +326,44 @@ class ADODB_db2 extends ADOConnection { return null; } } - + if ($argDSN && !$argDatabasename && $useCataloguedConnection) { $argDatabasename = $argDSN; $argDSN = ''; } - - if ($useCataloguedConnection - && (!$argDatabasename + + if ($useCataloguedConnection + && (!$argDatabasename || !$argUsername || !$argPassword)) { - + $errorMessage = 'For catalogued connections, provide '; $errorMessage.= 'database, username and password'; $this->_errorMsg = $errorMessage; if ($this->debug) ADOConnection::outp($errorMessage); return null; - + } - + if ($argDatabasename) $this->databaseName = $argDatabasename; elseif (!$this->databaseName) $this->databaseName = $this->getDatabasenameFromDsn($argDSN); - - + + $connectionParameters = array('dsn'=>$argDSN, 'uid'=>$argUsername, 'pwd'=>$argPassword, 'database'=>$argDatabasename, 'catalogue'=>$useCataloguedConnection ); - + return $connectionParameters; - + } /** @@ -375,7 +379,7 @@ class ADODB_db2 extends ADOConnection { return true; return false; } - + /** * Gets the database name from the DSN @@ -385,14 +389,14 @@ class ADODB_db2 extends ADOConnection { * @return string */ private function getDatabasenameFromDsn($dsnString){ - + $dsnArray = preg_split('/[;=]+/',$dsnString); $dbIndex = array_search('database',$dsnArray); - + return $dsnArray[$dbIndex + 1]; - } - - + } + + /** * format and return date string in database timestamp format * @@ -483,7 +487,7 @@ class ADODB_db2 extends ADOConnection { function serverInfo() { - $sql = "SELECT service_level, fixpack_num + $sql = "SELECT service_level, fixpack_num FROM TABLE(sysproc.env_get_inst_info()) AS INSTANCEINFO"; $row = $this->GetRow($sql); @@ -502,11 +506,11 @@ class ADODB_db2 extends ADOConnection { function createSequence($seqname='adodbseq',$start=1) { - if (empty($this->_genSeqSQL)) + if (empty($this->_genSeqSQL)) return false; - + $ok = $this->execute(sprintf($this->_genSeqSQL,$seqname,$start)); - if (!$ok) + if (!$ok) return false; return true; } @@ -520,60 +524,60 @@ class ADODB_db2 extends ADOConnection { function selectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false,$secs2cache=0) { $nrows = (integer) $nrows; - + if ($offset <= 0) { - if ($nrows >= 0) + if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY "; - + $rs = $this->execute($sql,$inputArr); - - } + + } else { if ($offset > 0 && $nrows < 0); - - else + + else { $nrows += $offset; $sql .= " FETCH FIRST $nrows ROWS ONLY "; } - + /* * DB2 has no native support for mid table offset */ $rs = ADOConnection::selectLimit($sql,$nrows,$offset,$inputArr); - + } - + return $rs; } - + function errorMsg() { - if ($this->_errorMsg !== false) + if ($this->_errorMsg !== false) return $this->_errorMsg; - - if (empty($this->_connectionID)) + + if (empty($this->_connectionID)) return @db2_conn_errormsg(); - + return @db2_conn_errormsg($this->_connectionID); } function errorNo() { - if ($this->_errorCode !== false) + if ($this->_errorCode !== false) return $this->_errorCode; - - if (empty($this->_connectionID)) + + if (empty($this->_connectionID)) $e = @db2_conn_error(); - - else + + else $e = @db2_conn_error($this->_connectionID); - + return $e; } @@ -581,15 +585,15 @@ class ADODB_db2 extends ADOConnection { function beginTrans() { - if (!$this->hasTransactions) + if (!$this->hasTransactions) return false; - if ($this->transOff) + if ($this->transOff) return true; - + $this->transCnt += 1; - + $this->_autocommit = false; - + return db2_autocommit($this->_connectionID,false); } @@ -597,13 +601,13 @@ class ADODB_db2 extends ADOConnection { { if ($this->transOff) return true; - - if (!$ok) + + if (!$ok) return $this->RollbackTrans(); - + if ($this->transCnt) $this->transCnt -= 1; - + $this->_autocommit = true; $ret = @db2_commit($this->_connectionID); @db2_autocommit($this->_connectionID,true); @@ -621,27 +625,27 @@ class ADODB_db2 extends ADOConnection { } /** - * Return a list of Primary Keys for a specified table - * - * We don't use db2_statistics as the function does not seem to play - * well with mixed case table names - * - * @param string $table - * @param bool $primary (optional) only return primary keys - * @param bool $owner (optional) not used in this driver - * - * @return string[] Array of indexes - */ + * Return a list of Primary Keys for a specified table + * + * We don't use db2_statistics as the function does not seem to play + * well with mixed case table names + * + * @param string $table + * @param bool $primary (optional) only return primary keys + * @param bool $owner (optional) not used in this driver + * + * @return string[] Array of indexes + */ public function metaPrimaryKeys($table,$owner=false) { - + $primaryKeys = array(); - + global $ADODB_FETCH_MODE; $schema = ''; $this->_findschema($table,$schema); - + $table = $this->getTableCasedValue($table); $savem = $ADODB_FETCH_MODE; @@ -649,23 +653,23 @@ class ADODB_db2 extends ADOConnection { $this->setFetchMode(ADODB_FETCH_NUM); - $sql = "SELECT * + $sql = "SELECT * FROM syscat.indexes WHERE tabname='$table'"; - + $rows = $this->getAll($sql); - + $this->setFetchMode($savem); $ADODB_FETCH_MODE = $savem; if (empty($rows)) return false; - + foreach ($rows as $r) { if ($r[7] != 'P') continue; - + $cols = explode('+',$r[6]); foreach ($cols as $colIndex=>$col) { @@ -691,7 +695,7 @@ class ADODB_db2 extends ADOConnection { */ public function metaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE ) { - + global $ADODB_FETCH_MODE; $schema = ''; @@ -699,59 +703,59 @@ class ADODB_db2 extends ADOConnection { $savem = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - + $this->setFetchMode(ADODB_FETCH_NUM); - + $sql = "SELECT SUBSTR(tabname,1,20) table_name, SUBSTR(constname,1,20) fk_name, SUBSTR(REFTABNAME,1,12) parent_table, SUBSTR(refkeyname,1,20) pk_orig_table, - fk_colnames - FROM syscat.references + fk_colnames + FROM syscat.references WHERE tabname = '$table'"; - + $results = $this->getAll($sql); - + $ADODB_FETCH_MODE = $savem; $this->setFetchMode($savem); if (empty($results)) return false; - + $foreignKeys = array(); - + foreach ($results as $r) { $parentTable = trim($this->getMetaCasedValue($r[2])); $keyName = trim($this->getMetaCasedValue($r[1])); $foreignKeys[$parentTable] = $keyName; } - + return $foreignKeys; } /** - * Returns a list of tables - * - * @param string $ttype (optional) - * @param string $schema (optional) - * @param string $mask (optional) - * - * @return array - */ + * Returns a list of tables + * + * @param string $ttype (optional) + * @param string $schema (optional) + * @param string $mask (optional) + * + * @return array + */ public function metaTables($ttype=false,$schema=false,$mask=false) { - + global $ADODB_FETCH_MODE; $savem = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - + /* * Values for TABLE_TYPE * --------------------------- - * ALIAS, HIERARCHY TABLE, INOPERATIVE VIEW, NICKNAME, - * MATERIALIZED QUERY TABLE, SYSTEM TABLE, TABLE, + * ALIAS, HIERARCHY TABLE, INOPERATIVE VIEW, NICKNAME, + * MATERIALIZED QUERY TABLE, SYSTEM TABLE, TABLE, * TYPED TABLE, TYPED VIEW, and VIEW * * If $ttype passed as '', match 'TABLE' and 'VIEW' @@ -762,90 +766,90 @@ class ADODB_db2 extends ADOConnection { if ($ttype) { /* * @todo We could do valid type checking or array type - */ + */ if ($ttype == 'V') $ttype = 'VIEW'; if ($ttype == 'T') $ttype = 'TABLE'; } - + if (!$schema) $schema = '%'; - + if (!$mask) $mask = '%'; - + $qid = @db2_tables($this->_connectionID,NULL,$schema,$mask,$ttype); $rs = new ADORecordSet_db2($qid); - + $ADODB_FETCH_MODE = $savem; - + if (!$rs) return false; - + $arr = $rs->getArray(); - + $rs->Close(); - + $tableList = array(); /* * Array items * --------------------------------- - * 0 TABLE_CAT The catalog that contains the table. + * 0 TABLE_CAT The catalog that contains the table. * The value is NULL if this table does not have catalogs. * 1 TABLE_SCHEM Name of the schema that contains the table. * 2 TABLE_NAME Name of the table. * 3 TABLE_TYPE Table type identifier for the table. * 4 REMARKS Description of the table. */ - - for ($i=0; $i < sizeof($arr); $i++) + + for ($i=0; $i < sizeof($arr); $i++) { - + $tableRow = $arr[$i]; $tableName = $tableRow[2]; $tableType = $tableRow[3]; - - if (!$tableName) + + if (!$tableName) continue; - + if ($ttype == '' && (strcmp($tableType,'TABLE') <> 0 && strcmp($tableType,'VIEW') <> 0)) continue; - + /* * Set metacasing if required */ $tableName = $this->getMetaCasedValue($tableName); - + /* - * If we requested a schema, we prepend the schema + * If we requested a schema, we prepend the schema name to the table name */ if (strcmp($schema,'%') <> 0) $tableName = $schema . '.' . $tableName; - + $tableList[] = $tableName; - + } return $tableList; } - - /** - * Return a list of indexes for a specified table + + /** + * Return a list of indexes for a specified table * * We don't use db2_statistics as the function does not seem to play * well with mixed case table names - * - * @param string $table - * @param bool $primary (optional) only return primary keys - * @param bool $owner (optional) not used in this driver - * - * @return string[] Array of indexes - */ - public function metaIndexes($table, $primary = false, $owner = false) { - + * + * @param string $table + * @param bool $primary (optional) only return primary keys + * @param bool $owner (optional) not used in this driver + * + * @return string[] Array of indexes + */ + public function metaIndexes($table, $primary = false, $owner = false) { + global $ADODB_FETCH_MODE; /* Array( @@ -854,51 +858,51 @@ class ADODB_db2 extends ADOConnection { * [columns] => Array( * [0] => firstcol * [1] => nextcol - * [2] => etc........ + * [2] => etc........ * ) * ) * ) */ $indices = array(); $primaryKeyName = ''; - + $table = $this->getTableCasedValue($table); - + $savem = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; $this->setFetchMode(ADODB_FETCH_NUM); - $sql = "SELECT * + $sql = "SELECT * FROM syscat.indexes WHERE tabname='$table'"; - + $rows = $this->getAll($sql); - + $this->setFetchMode($savem); $ADODB_FETCH_MODE = $savem; - + if (empty($rows)) return false; - foreach ($rows as $r) + foreach ($rows as $r) { - + $primaryIndex = $r[7] == 'P'?1:0; if (!$primary) /* - * Primary key not requested, ignore that one + * Primary key not requested, ignore that one */ if ($r[7] == 'P') continue; - + $indexName = $this->getMetaCasedValue($r[1]); if (!isset($indices[$indexName])) { $unique = ($r[7] == 'U')?1:0; $indices[$indexName] = array('unique'=>$unique, 'primary'=>$primaryIndex, - 'columns'=>array() + 'columns'=>array() ); } $cols = explode('+',$r[6]); @@ -909,50 +913,50 @@ class ADODB_db2 extends ADOConnection { $columnName = $this->getMetaCasedValue($col); $indices[$indexName]['columns'][] = $columnName; } - + } - + return $indices; - - } - + + } + /** * List procedures or functions in an array. * - * We interrogate syscat.routines instead of calling the PHP + * We interrogate syscat.routines instead of calling the PHP * function procedures because ADOdb requires the type of procedure * this is not available in the php function * * @param string $procedureNamePattern (optional) * @param string $catalog (optional) * @param string $schemaPattern (optional) - + * @return array of procedures on current database. * */ public function metaProcedures($procedureNamePattern = null, $catalog = null, $schemaPattern = null) { - - + + global $ADODB_FETCH_MODE; - + $metaProcedures = array(); $procedureSQL = ''; $catalogSQL = ''; $schemaSQL = ''; - + $savem = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - + if ($procedureNamePattern) $procedureSQL = "AND ROUTINENAME LIKE " . strtoupper($this->qstr($procedureNamePattern)); - + if ($catalog) $catalogSQL = "AND OWNER=" . strtoupper($this->qstr($catalog)); - + if ($schemaPattern) $schemaSQL = "AND ROUTINESCHEMA LIKE {$this->qstr($schemaPattern)}"; - - + + $fields = " ROUTINENAME, CASE ROUTINETYPE @@ -962,23 +966,23 @@ class ADODB_db2 extends ADOConnection { END AS ROUTINETYPE_NAME, ROUTINESCHEMA, REMARKS"; - + $SQL = "SELECT $fields - FROM syscat.routines + FROM syscat.routines WHERE OWNER IS NOT NULL $procedureSQL $catalogSQL $schemaSQL ORDER BY ROUTINENAME "; - + $result = $this->execute($SQL); - + $ADODB_FETCH_MODE = $savem; - + if (!$result) return false; - + while ($r = $result->fetchRow()){ $procedureName = $this->getMetaCasedValue($r[0]); $schemaName = $this->getMetaCasedValue($r[2]); @@ -986,13 +990,13 @@ class ADODB_db2 extends ADOConnection { 'catalog' => '', 'schema' => $schemaName, 'remarks' => $r[3] - ); + ); } - + return $metaProcedures; - + } - + /** * Lists databases. Because instances are independent, we only know about * the current database name @@ -1000,15 +1004,15 @@ class ADODB_db2 extends ADOConnection { * @return string[] */ public function metaDatabases(){ - + $dbName = $this->getMetaCasedValue($this->databaseName); - + return (array)$dbName; - + } - - - + + + /* See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2datetime_data_type_changes.asp @@ -1081,16 +1085,16 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 public function metaColumns($table, $normalize=true) { global $ADODB_FETCH_MODE; - + $savem = $ADODB_FETCH_MODE; $schema = '%'; $this->_findschema($table,$schema); $table = $this->getTableCasedValue($table); - $colname = "%"; - $qid = db2_columns($this->_connectionID, null, $schema, $table, $colname); + $colname = "%"; + $qid = db2_columns($this->_connectionID, null, $schema, $table, $colname); if (empty($qid)) - { + { if ($this->debug) { $errorMessage = @db2_conn_errormsg($this->_connectionID); @@ -1101,9 +1105,9 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 $rs = new ADORecordSet_db2($qid); - if (!$rs) + if (!$rs) return false; - + $rs->_fetch(); $retarr = array(); @@ -1122,25 +1126,25 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 9 RADIX 10 NULLABLE 11 REMARKS - 12 Column Default - 13 SQL Data Type - 14 SQL DateTime SubType - 15 Max length in Octets - 16 Ordinal Position - 17 Is NULLABLE + 12 Column Default + 13 SQL Data Type + 14 SQL DateTime SubType + 15 Max length in Octets + 16 Ordinal Position + 17 Is NULLABLE */ - while (!$rs->EOF) + while (!$rs->EOF) { - if ($rs->fields[2] == $table) + if ($rs->fields[2] == $table) { - + $fld = new ADOFieldObject(); $fld->name = $rs->fields[3]; $fld->type = $this->DB2Types($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 - + if ($fld->type == 'C' or $fld->type == 'X') { if ($rs->fields[4] <= -95) // UNICODE $fld->max_length = $rs->fields[7]/2; @@ -1148,42 +1152,42 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 $fld->max_length = $rs->fields[7]; } else $fld->max_length = $rs->fields[7]; - + $fld->not_null = !empty($rs->fields[10]); $fld->scale = $rs->fields[8]; $fld->primary_key = false; - + //$columnName = $this->getMetaCasedValue($fld->name); $columnName = strtoupper($fld->name); $retarr[$columnName] = $fld; - - } + + } else if (sizeof($retarr)>0) break; - + $rs->MoveNext(); - + } - + $rs->Close(); - if (empty($retarr)) + if (empty($retarr)) $retarr = false; - /* + /* * Now we find out if the column is part of a primary key */ - + $qid = @db2_primary_keys($this->_connectionID, "", $schema, $table); - if (empty($qid)) + if (empty($qid)) return false; $rs = new ADORecordSet_db2($qid); if (!$rs) - { + { $ADODB_FETCH_MODE = $savem; return $retarr; - } + } $rs->_fetch(); /* @@ -1196,29 +1200,29 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 5 PK_NAME */ while (!$rs->EOF) { - if (strtoupper(trim($rs->fields[2])) == $table + if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { $retarr[strtoupper($rs->fields[3])]->primary_key = true; - } + } else if (sizeof($retarr)>0) break; - + $rs->MoveNext(); } $rs->Close(); $ADODB_FETCH_MODE = $savem; - if (empty($retarr)) + if (empty($retarr)) return false; - + /* * If the fetch mode is numeric, return as numeric array */ if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr = array_values($retarr); - + return $retarr; } @@ -1233,9 +1237,9 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 * @return mixed[] */ function prepareSp($procedureName,$parameters=false) { - + global $ADODB_FETCH_MODE; - + $this->storedProcedureParameters = array('name'=>'', 'resource'=>false, 'in'=>array(), @@ -1243,36 +1247,36 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 'index'=>array(), 'parameters'=>array(), 'keyvalue' => array()); - + //$procedureName = strtoupper($procedureName); //$procedureName = $this->getTableCasedValue($procedureName); $savem = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - + $qid = db2_procedures($this->_connectionID, NULL , '%' , $procedureName ); - + $ADODB_FETCH_MODE = $savem; - + if (!$qid) { if ($this->debug) ADOConnection::outp(sprintf('No Procedure of name %s available',$procedureName)); return false; } - - - + + + $this->storedProcedureParameters['name'] = $procedureName; /* - * Now we know we have a valid procedure name, lets see if it requires + * Now we know we have a valid procedure name, lets see if it requires * parameters */ $savem = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; - + $qid = db2_procedure_columns($this->_connectionID, NULL , '%' , $procedureName , NULL ); - + $ADODB_FETCH_MODE = $savem; if (!$qid) @@ -1282,9 +1286,9 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 return false; } $rs = new ADORecordSet_db2($qid); - if (!$rs) + if (!$rs) return false; - + $preparedStatement = 'CALL %s(%s)'; $parameterMarkers = array(); while (!$rs->EOF) @@ -1301,12 +1305,12 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 { case DB2_PARAM_IN: case DB2_PARAM_INOUT: - $this->storedProcedureParameters['in'][$parameterName] = ''; + $this->storedProcedureParameters['in'][$parameterName] = ''; break; case DB2_PARAM_INOUT: case DB2_PARAM_OUT: - $this->storedProcedureParameters['out'][$parameterName] = ''; - break; + $this->storedProcedureParameters['out'][$parameterName] = ''; + break; } $this->storedProcedureParameters['index'][$parameterName] = $ordinalPosition; $this->storedProcedureParameters['parameters'][$ordinalPosition] = $rs->fields; @@ -1315,95 +1319,95 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 } $parameterCount = count($this->storedProcedureParameters['index']); $parameterMarkers = array_fill(0,$parameterCount,'?'); - + /* * We now know how many parameters to bind to the stored procedure */ $parameterList = implode(',',$parameterMarkers); - + $sql = sprintf($preparedStatement,$procedureName,$parameterList); - + $spResource = @db2_prepare($this->_connectionID,$sql); - + if (!$spResource) { $errorMessage = @db2_conn_errormsg($this->_connectionID); $this->_errorMsg = $errorMessage; - + if ($this->debug) ADOConnection::outp($errorMessage); - + return false; } - + $this->storedProcedureParameters['resource'] = $spResource; - + if ($this->debug) { - + ADOConnection::outp('The following parameters will be used in the SP call'); ADOConnection::outp(print_r($this->storedProcedureParameters)); } /* - * We now have a stored parameter resource + * We now have a stored parameter resource * to bind to. The spResource and sql that is returned are * not usable, its for dummy compatibility. Everything - * will be handled by the storedProcedureParameters + * will be handled by the storedProcedureParameters * array */ return array($sql,$spResource); - + } - - private function storedProcedureParameter(&$stmt, - &$var, - $name, - $isOutput=false, - $maxLen=4000, + + private function storedProcedureParameter(&$stmt, + &$var, + $name, + $isOutput=false, + $maxLen=4000, $type=false) { - - + + $name = strtoupper($name); - + /* * Must exist in the list of parameter names for the type */ - if ($isOutput + if ($isOutput && !isset( $this->storedProcedureParameters['out'][$name])) { $errorMessage = sprintf('%s is not a valid OUT parameter name',$name); - + $this->_errorMsg = $errorMessage; if ($this->debug) ADOConnection::outp($errorMessage); return false; } - - if (!$isOutput + + if (!$isOutput && !isset( $this->storedProcedureParameters['in'][$name])) { $errorMessage = sprintf('%s is not a valid IN parameter name',$name); - + $this->_errorMsg = $errorMessage; if ($this->debug) ADOConnection::outp($errorMessage); return false; } - + /* * We will use these values to bind to when we execute * the query */ $this->storedProcedureParameters['keyvalue'][$name] = &$var; - + return true; - + } - + /** - * Executes a prepared stored procedure. - * + * Executes a prepared stored procedure. + * * The function uses the previously accumulated information and * resources in the $storedProcedureParameters array * @@ -1411,22 +1415,22 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 */ private function executeStoredProcedure() { - + /* * Get the previously built resource */ $stmtid = $this->storedProcedureParameters['resource']; - + /* * Bind our variables to the DB2 procedure */ foreach ($this->storedProcedureParameters['keyvalue'] as $spName=>$spValue){ - + /* * Get the ordinal position, required for binding */ $ordinalPosition = $this->storedProcedureParameters['index'][$spName]; - + /* * Get the db2 column dictionary for the parameter */ @@ -1435,51 +1439,51 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 $dataType = $columnDictionary[5]; $precision = $columnDictionary[10]; $scale = $columnDictionary[9]; - - $ok = @db2_bind_param ($this->storedProcedureParameters['resource'], - $ordinalPosition , + + $ok = @db2_bind_param ($this->storedProcedureParameters['resource'], + $ordinalPosition , $spName, $parameterType, $dataType, $precision, $scale ); - + if (!$ok) { $this->_errorMsg = @db2_stmt_errormsg(); $this->_errorCode = @db2_stmt_error(); - if ($this->debug) - ADOConnection::outp($this->_errorMsg); + if ($this->debug) + ADOConnection::outp($this->_errorMsg); return false; } - + if ($this->debug) - ADOConnection::outp("Correctly Bound parameter $spName to procedure"); - + ADOConnection::outp("Correctly Bound parameter $spName to procedure"); + /* - * Build a variable in the current environment that matches + * Build a variable in the current environment that matches * the parameter name */ ${$spName} = $spValue; - + } - + /* * All bound, execute */ - - if (!@db2_execute($stmtid)) + + if (!@db2_execute($stmtid)) { $this->_errorMsg = @db2_stmt_errormsg(); $this->_errorCode = @db2_stmt_error(); - - if ($this->debug) - ADOConnection::outp($this->_errorMsg); + + if ($this->debug) + ADOConnection::outp($this->_errorMsg); return false; } - + /* * We now take the changed parameters back into the * stored procedures array where we can query them later @@ -1495,32 +1499,32 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 $spValue = ${$spName}; $this->storedProcedureParameters['keyvalue'][$spName] = $spValue; } - + return $stmtid; } - + /** - * - * Accepts an input or output parameter to bind to either a stored - * or prepared statements. For DB2, this should not be called as an - * API. always wrap with inParameter and outParameter - * - * @param mixed[] $stmt Statement returned by Prepare() or PrepareSP(). - * @param mixed $var PHP variable to bind to. Can set to null (for isNull support). - * @param string $name Name of stored procedure variable name to bind to. - * @param int $isOutput optional) Indicates direction of parameter - * 0/false=IN 1=OUT 2= IN/OUT - * This is ignored for Stored Procedures - * @param int $maxLen (optional)Holds an maximum length of the variable. - * This is ignored for Stored Procedures - * @param int $type (optional) The data type of $var. - * This is ignored for Stored Procedures - * - * @return bool Success of the operation - */ + * + * Accepts an input or output parameter to bind to either a stored + * or prepared statements. For DB2, this should not be called as an + * API. always wrap with inParameter and outParameter + * + * @param mixed[] $stmt Statement returned by Prepare() or PrepareSP(). + * @param mixed $var PHP variable to bind to. Can set to null (for isNull support). + * @param string $name Name of stored procedure variable name to bind to. + * @param int $isOutput optional) Indicates direction of parameter + * 0/false=IN 1=OUT 2= IN/OUT + * This is ignored for Stored Procedures + * @param int $maxLen (optional)Holds an maximum length of the variable. + * This is ignored for Stored Procedures + * @param int $type (optional) The data type of $var. + * This is ignored for Stored Procedures + * + * @return bool Success of the operation + */ public function parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false) { - + /* * If the $stmt is the name of a stored procedure we are * setting up, we will process it one way, otherwise @@ -1531,35 +1535,35 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 if ($this->debug) ADOConnection::outp("Adding parameter to stored procedure"); if ($stmt[1] == $this->storedProcedureParameters['resource']) - return $this->storedProcedureParameter($stmt[1], - $var, - $name, - $isOutput, + return $this->storedProcedureParameter($stmt[1], + $var, + $name, + $isOutput, $maxLen, $type); - + } - + /* * We are going to add a parameter to a prepared statement */ if ($this->debug) ADOConnection::outp("Adding parameter to prepared statement"); } - - + + /** - * Prepares a prepared SQL statement, not used for stored procedures - * - * @param string $sql - * - * @return mixed - */ + * Prepares a prepared SQL statement, not used for stored procedures + * + * @param string $sql + * + * @return mixed + */ function prepare($sql) { - + if (! $this->_bindInputArray) return $sql; // no binding - + $stmt = @db2_prepare($this->_connectionID,$sql); if (!$stmt) { // we don't know whether db2 driver is parsing prepared stmts, so just return sql @@ -1569,52 +1573,49 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 } /** - * Executes a query - * - * @param mixed $sql - * @param mixed $inputarr An optional array of parameters - * - * @return mixed either the queryID or false - */ + * Executes a query + * + * @param mixed $sql + * @param mixed $inputarr An optional array of parameters + * + * @return mixed either the queryID or false + */ function _query(&$sql,$inputarr=false) { - - GLOBAL $php_errormsg; - + + GLOBAL $php_errormsg; + if (isset($php_errormsg)) $php_errormsg = ''; $this->_error = ''; $db2Options = array(); /* - * Use DB2 Internal case handling for best speed - */ + * Use DB2 Internal case handling for best speed + */ switch(ADODB_ASSOC_CASE) { - case ADODB_ASSOC_CASE_UPPER: - $db2Options = array('db2_attr_case'=>DB2_CASE_UPPER); - $setOption = @db2_set_option($this->_connectionID,$db2Options,1); - break; - + case ADODB_ASSOC_CASE_UPPER: + $db2Options = array('db2_attr_case'=>DB2_CASE_UPPER); + $setOption = @db2_set_option($this->_connectionID,$db2Options,1); + break; + case ADODB_ASSOC_CASE_LOWER: - $db2Options = array('db2_attr_case'=>DB2_CASE_LOWER); - $setOption = @db2_set_option($this->_connectionID,$db2Options,1); - break; - + $db2Options = array('db2_attr_case'=>DB2_CASE_LOWER); + $setOption = @db2_set_option($this->_connectionID,$db2Options,1); + break; + default: - $db2Options = array('db2_attr_case'=>DB2_CASE_NATURAL); - $setOption = @db2_set_option($this->_connectionID,$db2Options,1); - } - - $db2Options = array('db2_attr_case'=>DB2_CASE_LOWER); - $setOption = @db2_set_option($this->_connectionID,$db2Options,1); - - if ($inputarr) + $db2Options = array('db2_attr_case'=>DB2_CASE_NATURAL); + $setOption = @db2_set_option($this->_connectionID,$db2Options,1); + } + + if ($inputarr) { if (is_array($sql)) { $stmtid = $sql[1]; - } + } else { $stmtid = @db2_prepare($this->_connectionID,$sql); @@ -1630,28 +1631,28 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 { $this->_errorMsg = @db2_stmt_errormsg(); $this->_errorCode = @db2_stmt_error(); - if ($this->debug) - ADOConnection::outp($this->_errorMsg); + if ($this->debug) + ADOConnection::outp($this->_errorMsg); return false; } - } + } else if (is_array($sql)) { - + /* * Either a prepared statement or a stored procedure */ - + if (is_array($this->storedProcedureParameters) && is_resource($this->storedProcedureParameters['resource'] - )) + )) /* * This is all handled in the separate method for * readability */ return $this->executeStoredProcedure(); - + /* * First, we prepare the statement */ @@ -1680,23 +1681,23 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 return false; } } - - if (!@db2_execute($stmtid)) + + if (!@db2_execute($stmtid)) { $this->_errorMsg = @db2_stmt_errormsg(); $this->_errorCode = @db2_stmt_error(); - if ($this->debug) - ADOConnection::outp($this->_errorMsg); + if ($this->debug) + ADOConnection::outp($this->_errorMsg); return false; } - + return $stmtid; } else { $stmtid = @db2_exec($this->_connectionID,$sql); - } + } $this->_lastAffectedRows = 0; if ($stmtid) { @@ -1704,22 +1705,22 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 { $this->_lastAffectedRows = db2_num_rows($stmtid); $stmtid = true; - } - else + } + else { $this->_lastAffectedRows = 0; } $this->_errorMsg = ''; $this->_errorCode = 0; - + } else { - + $this->_errorMsg = @db2_stmt_errormsg(); $this->_errorCode = @db2_stmt_error(); - + } return $stmtid; } @@ -1750,21 +1751,21 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 { return $this->_lastAffectedRows; } - + /** - * Gets a meta cased parameter - * - * Receives an input variable to be processed per the metaCasing - * rule, and returns the same value, processed - * - * @param string $value - * - * @return string - */ + * Gets a meta cased parameter + * + * Receives an input variable to be processed per the metaCasing + * rule, and returns the same value, processed + * + * @param string $value + * + * @return string + */ final public function getMetaCasedValue($value) { global $ADODB_ASSOC_CASE; - + switch($ADODB_ASSOC_CASE) { case ADODB_ASSOC_CASE_LOWER: @@ -1776,48 +1777,48 @@ See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2 } return $value; } - - + + const TABLECASE_LOWER = 0; - const TABLECASE_UPPER = 1; - const TABLECASE_DEFAULT = 2; - - /* + const TABLECASE_UPPER = 1; + const TABLECASE_DEFAULT = 2; + + /** * Controls the casing of the table provided to the meta functions */ private $tableCase = 2; - + /** - * Sets the table case parameter - * - * @param int $caseOption - * @return null - */ + * Sets the table case parameter + * + * @param int $caseOption + * @return null + */ final public function setTableCasing($caseOption) { $this->tableCase = $caseOption; } - + /** - * Gets the table casing parameter - * - * @return int $caseOption - */ + * Gets the table casing parameter + * + * @return int $caseOption + */ final public function getTableCasing() { return $this->tableCase; } - + /** - * Gets a table cased parameter - * - * Receives an input variable to be processed per the tableCasing - * rule, and returns the same value, processed - * - * @param string $value - * - * @return string - */ + * Gets a table cased parameter + * + * Receives an input variable to be processed per the tableCasing + * rule, and returns the same value, processed + * + * @param string $value + * + * @return string + */ final public function getTableCasedValue($value) { switch($this->tableCase) @@ -1864,11 +1865,11 @@ class ADORecordSet_db2 extends ADORecordSet { $o->name = @db2_field_name($this->_queryID,$offset); $o->type = @db2_field_type($this->_queryID,$offset); $o->max_length = @db2_field_width($this->_queryID,$offset); - + /* - if (ADODB_ASSOC_CASE == 0) + if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name); - else if (ADODB_ASSOC_CASE == 1) + else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name); */ return $o; @@ -1877,11 +1878,11 @@ class ADORecordSet_db2 extends ADORecordSet { /* 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++) { @@ -1898,12 +1899,12 @@ class ADORecordSet_db2 extends ADORecordSet { { global $ADODB_COUNTRECS; $this->_numOfRows = ($ADODB_COUNTRECS) ? @db2_num_rows($this->_queryID) : -1; - + $this->_numOfFields = @db2_num_fields($this->_queryID); - + // some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0 - - if ($this->_numOfRows == 0) + + if ($this->_numOfRows == 0) $this->_numOfRows = -1; } @@ -1918,7 +1919,7 @@ class ADORecordSet_db2 extends ADORecordSet { $rs = $this->GetArray($nrows); return $rs; } - + $this->Move($offset); @@ -1928,7 +1929,7 @@ class ADORecordSet_db2 extends ADORecordSet { $results[$cnt++] = $this->fields; $this->MoveNext(); } - + return $results; } @@ -1936,25 +1937,25 @@ class ADORecordSet_db2 extends ADORecordSet { { if ($this->EOF || $this->_numOfRows == 0) return false; - + $this->_currentRow++; - + $this->processCoreFetch(); return $this->processMoveRecord(); - + } - - private function processCoreFetch() - { - switch ($this->fetchMode){ + + private function processCoreFetch() + { + switch ($this->fetchMode){ case ADODB_FETCH_ASSOC: - + /* * Associative array */ $this->fields = @db2_fetch_assoc($this->_queryID); break; - + case ADODB_FETCH_BOTH: /* * Fetch both numeric and Associative array @@ -1968,24 +1969,24 @@ class ADORecordSet_db2 extends ADORecordSet { $this->fields = @db2_fetch_array($this->_queryID); break; } - } + } private function processMoveRecord() - { + { if (!$this->fields){ $this->EOF = true; return false; } - + return true; } - - function _fetch() + + function _fetch() { - $this->processCoreFetch(); - if ($this->fields) + $this->processCoreFetch(); + if ($this->fields) return true; - + $this->fields = false; return false; } @@ -1998,11 +1999,11 @@ class ADORecordSet_db2 extends ADORecordSet { $this->_errorMsg = @db2_stmt_errormsg($this->_queryId); $this->_errorCode = @db2_stmt_error(); - if ($this->debug) - ADOConnection::outp($this->_errorMsg); + if ($this->debug) + ADOConnection::outp($this->_errorMsg); return false; } - + } } diff --git a/lib/adodb/drivers/adodb-db2oci.inc.php b/lib/adodb/drivers/adodb-db2oci.inc.php index ab3bc406c94..eea63d94c69 100644 --- a/lib/adodb/drivers/adodb-db2oci.inc.php +++ b/lib/adodb/drivers/adodb-db2oci.inc.php @@ -1,17 +1,27 @@ . - Set tabs to 8. -*/ +/** + * Frontbase driver. + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + * @author Frank M. Kromann + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -25,7 +35,7 @@ class ADODB_fbsql extends ADOConnection { var $fmtTimeStamp = "'Y-m-d H:i:s'"; var $hasLimit = false; - function _insertid() + protected function _insertID($table = '', $column = '') { return fbsql_insert_id($this->_connectionID); } diff --git a/lib/adodb/drivers/adodb-firebird.inc.php b/lib/adodb/drivers/adodb-firebird.inc.php index f125563158e..2fafbe4fcee 100644 --- a/lib/adodb/drivers/adodb-firebird.inc.php +++ b/lib/adodb/drivers/adodb-firebird.inc.php @@ -1,18 +1,25 @@ - changed transaction handling and added experimental blob stuff - - Docs to interbase at the website - http://www.synectics.co.za/php3/tutorial/IB_PHP3_API.html - - To use gen_id(), see - http://www.volny.cz/iprenosil/interbase/ip_ib_code.htm#_code_creategen - - $rs = $conn->Execute('select gen_id(adodb,1) from rdb$database'); - $id = $rs->fields[0]; - $conn->Execute("insert into table (id, col1,...) values ($id, $val1,...)"); -*/ +/** + * Interbase driver. + * + * Requires interbase client. Works on Windows and Unix. + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); diff --git a/lib/adodb/drivers/adodb-informix.inc.php b/lib/adodb/drivers/adodb-informix.inc.php index 07f4e2831dc..8e99137cb29 100644 --- a/lib/adodb/drivers/adodb-informix.inc.php +++ b/lib/adodb/drivers/adodb-informix.inc.php @@ -1,19 +1,27 @@ - -*/ +/** + * Informix driver. + * + * @deprecated + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + * @author Mitchell T. Young + * @author Samuel Carriere + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -83,7 +90,7 @@ class ADODB_informix72 extends ADOConnection { - function _insertid() + protected function _insertID($table = '', $column = '') { $sqlca =ifx_getsqlca($this->lastQuery); return @$sqlca["sqlerrd1"]; diff --git a/lib/adodb/drivers/adodb-ldap.inc.php b/lib/adodb/drivers/adodb-ldap.inc.php index 1337314bfb9..323b35856bf 100644 --- a/lib/adodb/drivers/adodb-ldap.inc.php +++ b/lib/adodb/drivers/adodb-ldap.inc.php @@ -1,20 +1,26 @@ + */ // security - hide paths if (!defined('ADODB_DIR')) die(); diff --git a/lib/adodb/drivers/adodb-mssql.inc.php b/lib/adodb/drivers/adodb-mssql.inc.php index be20620ebfa..3de3f8d33ce 100644 --- a/lib/adodb/drivers/adodb-mssql.inc.php +++ b/lib/adodb/drivers/adodb-mssql.inc.php @@ -1,21 +1,25 @@ this($v); $params .= "@P$i=N" . $inputVar; - + } else if (is_integer($v)) { $decl .= "@P$i INT"; $params .= "@P$i=".$v; @@ -815,7 +819,7 @@ order by constraint_name, referenced_table_name, keyno"; return $rez; } - + /** * Returns a substring of a varchar type field diff --git a/lib/adodb/drivers/adodb-mssql_n.inc.php b/lib/adodb/drivers/adodb-mssql_n.inc.php index b8c650f1235..236c1546af5 100644 --- a/lib/adodb/drivers/adodb-mssql_n.inc.php +++ b/lib/adodb/drivers/adodb-mssql_n.inc.php @@ -1,47 +1,27 @@ hasInsertID = $enable; + $this->lastInsID = false; + } + + /** + * Get the last value inserted into an IDENTITY column. + * + * The value will actually be set in {@see _query()} when executing an + * INSERT statement, but only if the connection's $hasInsertId property + * is true; this can be set with {@see enableLastInsertId()}. + * + * @inheritDoc + */ + protected function _insertID($table = '', $column = '') { - $rez = sqlsrv_query($this->_connectionID,$this->identitySQL); - sqlsrv_fetch($rez); - $this->lastInsertID = sqlsrv_get_field($rez, 0); - return $this->lastInsertID; + return $this->lastInsID; } function _affectedrows() @@ -278,22 +298,25 @@ class ADODB_mssqlnative extends ADOConnection { // Format date column in sql string given an input format that understands Y M D function SQLDate($fmt, $col=false) { - if (!$col) $col = $this->sysTimeStamp; + if (!$col) { + $col = $this->sysTimeStamp; + } $s = ''; $ConvertableFmt=array( - "m/d/Y"=>101,"m/d/y"=>101 // US - ,"Y.m.d"=>102,"y/m/d"=>102 // ANSI - ,"d/m/Y"=>103,"d/m/y"=>103 // French /english - ,"d.m.Y"=>104,"d.m.y"=>104 // German - ,"d-m-Y"=>105,"d-m-y"=>105 // Italian - ,"m-d-Y"=>110,"m-d-y"=>110 // US Dash - ,"Y/m/d"=>111,"y/m/d"=>111 // Japan - ,"Ymd"=>112,"ymd"=>112 // ISO - ,"H:i:s"=>108 // Time + "m/d/Y"=>101, "m/d/y"=>101 // US + ,"Y.m.d"=>102, "y.m.d"=>102 // ANSI + ,"d/m/Y"=>103, "d/m/y"=>103 // French /english + ,"d.m.Y"=>104, "d.m.y"=>104 // German + ,"d-m-Y"=>105, "d-m-y"=>105 // Italian + ,"m-d-Y"=>110, "m-d-y"=>110 // US Dash + ,"Y/m/d"=>111, "y/m/d"=>111 // Japan + ,"Ymd"=>112, "ymd"=>112 // ISO + ,"H:i:s"=>108 // Time ); - if(key_exists($fmt,$ConvertableFmt)) - return "convert (varchar ,$col,".$ConvertableFmt[$fmt].")"; + if (key_exists($fmt,$ConvertableFmt)) { + return "convert (varchar ,$col," . $ConvertableFmt[$fmt] . ")"; + } $len = strlen($fmt); for ($i=0; $i < $len; $i++) { @@ -439,9 +462,9 @@ class ADODB_mssqlnative extends ADOConnection { function ErrorNo() { $err = sqlsrv_errors(SQLSRV_ERR_ALL); - if ($err && $err[0]) + if ($err && $err[0]) return $err[0]['code']; - else + else return 0; } @@ -454,13 +477,13 @@ class ADODB_mssqlnative extends ADOConnection { ADOConnection::outp('Microsoft SQL Server native driver (mssqlnative) not installed'); return null; } - + if (!empty($this->port)) /* - * Port uses a comma + * Port uses a comma */ $argHostname .= ",".$this->port; - + $connectionInfo = $this->connectionInfo; $connectionInfo["Database"] = $argDatabasename; if ((string)$argUsername != '' || (string)$argPassword != '') @@ -471,12 +494,12 @@ class ADODB_mssqlnative extends ADOConnection { */ $connectionInfo["UID"] = $argUsername; $connectionInfo["PWD"] = $argPassword; - + if ($this->debug) ADOConnection::outp('userid or password supplied, attempting connection with SQL Server Authentication'); - + } - else + else { /* * If they don't pass either value, we won't add them to the @@ -484,11 +507,11 @@ class ADODB_mssqlnative extends ADOConnection { * to use windows authentication */ if ($this->debug) - + ADOConnection::outp('No userid or password supplied, attempting connection with Windows Authentication'); } - - + + /* * Now merge in the passed connection parameters setting */ @@ -501,7 +524,7 @@ class ADODB_mssqlnative extends ADOConnection { if ($this->debug) ADOConnection::outp("connecting to host: $argHostname params: ".var_export($connectionInfo,true)); if(!($this->_connectionID = @sqlsrv_connect($argHostname,$connectionInfo))) { - if ($this->debug) + if ($this->debug) ADOConnection::outp( 'Connection Failed: '.print_r( sqlsrv_errors(), true)); return false; } @@ -518,6 +541,7 @@ class ADODB_mssqlnative extends ADOConnection { return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename); } + function Prepare($sql) { return $sql; // prepare does not work properly with bind parameters as bind parameters are managed by sqlsrv_prepare! @@ -575,38 +599,69 @@ class ADODB_mssqlnative extends ADOConnection { return $this->Execute($sql) != false; } - // returns query ID if successful, otherwise false - function _query($sql,$inputarr=false) + /** + * Execute a query. + * + * If executing an INSERT statement and $hasInsertId is true, will set + * $lastInsId. + * + * @param string $sql + * @param array $inputarr + * @return resource|false Query Id if successful, otherwise false + */ + function _query($sql, $inputarr = false) { $this->_errorMsg = false; - if (is_array($sql)) + if (is_array($sql)) { $sql = $sql[1]; - - $insert = false; - // handle native driver flaw for retrieving the last insert ID - if(preg_match('/^\W*insert[\s\w()[\]",.]+values\s*\((?:[^;\']|\'\'|(?:(?:\'\')*\'[^\']+\'(?:\'\')*))*;?$/i', $sql)) { - $insert = true; - $sql .= '; '.$this->identitySQL; // select scope_identity() } - 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 - */ + + // Handle native driver flaw for retrieving the last insert ID + if ($this->hasInsertID) { + // Check if it's an INSERT statement + $retrieveLastInsertID = preg_match( + '/^\W*insert[\s\w()[\]",.]+values\s*\((?:[^;\']|\'\'|(?:(?:\'\')*\'[^\']+\'(?:\'\')*))*;?$/i', + $sql + ); + if ($retrieveLastInsertID) { + // Append the identity SQL, so it is executed in the same + // scope as the insert query. + $sql .= '; ' . $this->identitySQL; + } + } else { + $retrieveLastInsertID = false; + } + + if ($inputarr) { + // Ensure that the input array is indexed numerically, 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); + $rez = sqlsrv_query($this->_connectionID, $sql); } - if ($this->debug) ADOConnection::outp("
running query: ".var_export($sql,true)."
input array: ".var_export($inputarr,true)."
result: ".var_export($rez,true)); + if ($this->debug) { + ADOConnection::outp("
running query: " . var_export($sql, true) + . "
input array: " . var_export($inputarr, true) + . "
result: " . var_export($rez, true) + ); + } - if(!$rez) + $this->lastInsID = false; + if (!$rez) { $rez = false; - + } elseif ($retrieveLastInsertID) { + // Get the inserted id from the last result + // Note: loop is required as server may return more than one row, + // e.g. if triggers are involved (see #41) + while (sqlsrv_next_result($rez)) { + sqlsrv_fetch($rez); + $this->lastInsID = sqlsrv_get_field($rez, 0, SQLSRV_PHPTYPE_INT); + } + } return $rez; } @@ -623,7 +678,7 @@ class ADODB_mssqlnative extends ADOConnection { return $rez; } - + function MetaIndexes($table,$primary=false, $owner = false) { $table = $this->qstr($table); @@ -711,7 +766,7 @@ class ADODB_mssqlnative extends ADOConnection { function MetaDatabases() { $this->SelectDB("master"); - $rs =& $this->Execute($this->metaDatabasesSQL); + $rs = $this->Execute($this->metaDatabasesSQL); $rows = $rs->GetRows(); $ret = array(); for($i=0;$iqstr($procedureNamePattern)); - + if ($catalog) $catalogSQL = "AND SPECIFIC_SCHEMA=" . strtoupper($this->qstr($catalog)); - + if ($schemaPattern) $schemaSQL = "AND ROUTINE_SCHEMA LIKE {$this->qstr($schemaPattern)}"; - - + $fields = " ROUTINE_NAME,ROUTINE_TYPE,ROUTINE_SCHEMA,ROUTINE_CATALOG"; - + $SQL = "SELECT $fields - FROM {$this->database}.information_schema.routines - WHERE 1=1 - $procedureSQL - $catalogSQL - $schemaSQL - ORDER BY ROUTINE_NAME - "; - + FROM {$this->database}.information_schema.routines + WHERE 1=1 + $procedureSQL + $catalogSQL + $schemaSQL + ORDER BY ROUTINE_NAME + "; + $result = $this->execute($SQL); - + if (!$result) return false; while ($r = $result->fetchRow()){ - if (!isset($r[0])) /* * Convert to numeric */ $r = array_values($r); - + $procedureName = $r[0]; $schemaName = $r[2]; $routineCatalog= $r[3]; @@ -952,13 +1004,11 @@ class ADODB_mssqlnative extends ADOConnection { 'schema' => $schemaName, 'remarks' => '', ); - } - + return $metaProcedures; - } - + } /*-------------------------------------------------------------------------------------- @@ -972,13 +1022,8 @@ 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 + /** + * @var bool True if we have retrieved the fields metadata */ private $fieldObjectsRetrieved = false; @@ -987,7 +1032,6 @@ class ADORecordset_mssqlnative extends ADORecordSet { */ private $fieldObjectsIndex = array(); - /* * Cross references the dateTime objects for faster decoding */ @@ -1075,9 +1119,9 @@ class ADORecordset_mssqlnative extends ADORecordSet { * Too early */ return; - if ($this->fetchMode != ADODB_FETCH_NUM) + if ($this->fetchMode != ADODB_FETCH_NUM) return $this->fields[$colname]; - + if (!$this->bind) { $this->bind = array(); for ($i=0; $i < $this->_numOfFields; $i++) { @@ -1098,26 +1142,23 @@ class ADORecordset_mssqlnative extends ADORecordSet { * the next field that wasn't yet retrieved by fetchField() * is retrieved. * - * $param int $fieldOffset (optional default=-1 for all + * @param int $fieldOffset (optional default=-1 for all * @return mixed an ADOFieldObject, or array of objects */ private function _fetchField($fieldOffset = -1) { - if ($this->fieldObjectsRetrieved){ - if ($this->fieldObjects) { - /* - * Already got the information - */ - if ($fieldOffset == -1) - return $this->fieldObjects; - else - return $this->fieldObjects[$fieldOffset]; - } - else - /* - * No metadata available - */ + if ($this->fieldObjectsRetrieved) { + if ($this->fieldObjectsCache) { + // Already got the information + if ($fieldOffset == -1) { + return $this->fieldObjectsCache; + } else { + return $this->fieldObjectsCache[$fieldOffset]; + } + } else { + // No metadata available return false; + } } $this->fieldObjectsRetrieved = true; @@ -1127,36 +1168,28 @@ class ADORecordset_mssqlnative extends ADORecordSet { */ $fieldMetaData = sqlsrv_field_metadata($this->_queryID); - if (!$fieldMetaData) - /* - * Not a statement that gives us metaData - */ + if (!$fieldMetaData) { + // Not a statement that gives us metaData return false; + } $this->_numOfFields = count($fieldMetaData); - foreach ($fieldMetaData as $key=>$value) - { - + foreach ($fieldMetaData as $key=>$value) { $fld = new ADOFieldObject; - /* - * Caution - keys are case-sensitive, must respect - * casing of values - */ - + // 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->fieldObjectsCache[$key] = $fld; $this->fieldObjectsIndex[$fld->name] = $key; - } - if ($fieldOffset == -1) - return $this->fieldObjects; + if ($fieldOffset == -1) { + return $this->fieldObjectsCache; + } - return $this->fieldObjects[$fieldOffset]; + return $this->fieldObjectsCache[$fieldOffset]; } /* @@ -1173,7 +1206,7 @@ class ADORecordset_mssqlnative extends ADORecordSet { */ function fetchField($fieldOffset = -1) { - return $this->fieldObjects[$fieldOffset]; + return $this->fieldObjectsCache[$fieldOffset]; } function _seek($row) @@ -1243,7 +1276,7 @@ class ADORecordset_mssqlnative extends ADORecordSet { $this->_queryID = false; return $rez; } - + return true; } diff --git a/lib/adodb/drivers/adodb-mssqlpo.inc.php b/lib/adodb/drivers/adodb-mssqlpo.inc.php index 86f69d87d7c..f2d2f6fbd4a 100644 --- a/lib/adodb/drivers/adodb-mssqlpo.inc.php +++ b/lib/adodb/drivers/adodb-mssqlpo.inc.php @@ -1,29 +1,27 @@ charSet !== $charset_name) { - $ok = @mysql_set_charset($charset_name,$this->_connectionID); + if ($this->charSet !== $charset) { + $ok = @mysql_set_charset($charset,$this->_connectionID); if ($ok) { - $this->charSet = $charset_name; + $this->charSet = $charset; return true; } return false; @@ -273,7 +280,7 @@ class ADODB_mysql extends ADOConnection { return "'" . str_replace("'", $this->replaceQuote, $s) . "'"; } - function _insertid() + protected function _insertID($table = '', $column = '') { return ADOConnection::GetOne('SELECT LAST_INSERT_ID()'); //return mysql_insert_id($this->_connectionID); @@ -481,23 +488,23 @@ class ADODB_mysql extends ADOConnection { // returns true or false function _connect($argHostname, $argUsername, $argPassword, $argDatabasename) { - if (!empty($this->port)) + if (!empty($this->port)) $argHostname .= ":".$this->port; - $this->_connectionID = + $this->_connectionID = mysql_connect($argHostname, $argUsername, $argPassword, $this->forceNewConnect, $this->clientFlags ); - - if ($this->_connectionID === false) + + if ($this->_connectionID === false) return false; - if ($argDatabasename) + if ($argDatabasename) return $this->SelectDB($argDatabasename); - + return true; } @@ -506,17 +513,17 @@ class ADODB_mysql extends ADOConnection { { if (!empty($this->port)) $argHostname .= ":".$this->port; - $this->_connectionID = + $this->_connectionID = mysql_pconnect($argHostname, $argUsername, $argPassword, $this->clientFlags); - - if ($this->_connectionID === false) + + if ($this->_connectionID === false) return false; - if ($this->autoRollback) + if ($this->autoRollback) $this->RollbackTrans(); - if ($argDatabasename) + if ($argDatabasename) return $this->SelectDB($argDatabasename); return true; } diff --git a/lib/adodb/drivers/adodb-mysqli.inc.php b/lib/adodb/drivers/adodb-mysqli.inc.php index f9f16f750a7..160f5fa3406 100644 --- a/lib/adodb/drivers/adodb-mysqli.inc.php +++ b/lib/adodb/drivers/adodb-mysqli.inc.php @@ -1,23 +1,28 @@ execute("SET SESSION TRANSACTION ".$transaction_mode); } + /** + * Adds a parameter to the connection string. + * + * Parameter must be one of the the constants listed in mysqli_options(). + * @see https://www.php.net/manual/en/mysqli.options.php + * + * @param int $parameter The parameter to set + * @param string $value The value of the parameter + * + * @example, for mssqlnative driver ('CharacterSet','UTF-8') + * @return bool + */ + public function setConnectionParameter($parameter, $value) { + if(!is_numeric($parameter)) { + $this->outp_throw("Invalid connection parameter '$parameter'", __METHOD__); + return false; + } + $this->connectionParameters[$parameter] = $value; + return true; + } + /** * Connect to a database. * @@ -139,13 +183,15 @@ class ADODB_mysqli extends ADOConnection { 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); + // Now merge in the standard connection parameters setting + foreach ($this->connectionParameters as $parameter => $value) { + // Make sure parameter is numeric before calling mysqli_options() + // that to avoid Warning (or TypeError exception on PHP 8). + if (!is_numeric($parameter) + || !mysqli_options($this->_connectionID, $parameter, $value) + ) { + $this->outp_throw("Invalid connection parameter '$parameter'", __METHOD__); + } } //https://php.net/manual/en/mysqli.persistconns.php @@ -377,9 +423,9 @@ class ADODB_mysqli extends ADOConnection { /** * Return the AUTO_INCREMENT id of the last row that has been inserted or updated in a table. * - * @return int|string + * @inheritDoc */ - function _insertid() + protected function _insertID($table = '', $column = '') { // mysqli_insert_id does not return the last_insert_id if called after // execution of a stored procedure so we execute this instead. @@ -406,6 +452,12 @@ class ADODB_mysqli extends ADOConnection { */ function _affectedrows() { + if ($this->isSelectStatement) { + // Affected rows works fine against selects, returning + // the rowcount, but ADOdb does not do that. + return false; + } + $result = @mysqli_affected_rows($this->_connectionID); if ($result == -1) { if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->errorMsg()); @@ -864,15 +916,15 @@ class ADODB_mysqli extends ADOConnection { * Return assoc array where key is column name, value is column type * [1] => int unsigned */ - - $SQL = "SELECT column_name, column_type - FROM information_schema.columns - WHERE table_schema='{$this->databaseName}' + + $SQL = "SELECT column_name, column_type + FROM information_schema.columns + WHERE table_schema='{$this->databaseName}' AND table_name='$table'"; - + $schemaArray = $this->getAssoc($SQL); $schemaArray = array_change_key_case($schemaArray,CASE_LOWER); - + $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table)); if (isset($savem)) $this->SetFetchMode($savem); $ADODB_FETCH_MODE = $save; @@ -884,7 +936,7 @@ class ADODB_mysqli extends ADOConnection { $fld = new ADOFieldObject(); $fld->name = $rs->fields[0]; $type = $rs->fields[1]; - + /* * Type from information_schema returns * the same format in V8 mysql as V5 @@ -910,7 +962,7 @@ class ADODB_mysqli extends ADOConnection { $fld->type = $type; $fld->max_length = -1; } - + $fld->not_null = ($rs->fields[2] != 'YES'); $fld->primary_key = ($rs->fields[3] == 'PRI'); $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false); @@ -1096,8 +1148,10 @@ class ADODB_mysqli extends ADOConnection { } } else { $rs = mysqli_query($this->_connectionID, $sql, $ADODB_COUNTRECS ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT); - - if ($rs) return $rs; + if ($rs) { + $this->isSelectStatement = is_object($rs); + return $rs; + } } if($this->debug) @@ -1173,46 +1227,29 @@ class ADODB_mysqli extends ADOConnection { return 4294967295; } - /** - * Get the name of the character set the client connection is using now. - * - * @return string|bool The name of the character set, or false if it can't be determined. - */ - function GetCharSet() + function getCharSet() { - //we will use ADO's builtin property charSet - if (!method_exists($this->_connectionID,'character_set_name')) + if (!$this->_connectionID || !method_exists($this->_connectionID,'character_set_name')) { return false; - - $this->charSet = @$this->_connectionID->character_set_name(); - if (!$this->charSet) { - return false; - } else { - return $this->charSet; } + + $this->charSet = $this->_connectionID->character_set_name(); + return $this->charSet ?: false; } - /** - * Sets the character set for database connections (limited databases). - * - * @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:setcharset - * - * @param string $charset_name The character set to switch to. - * - * @return bool True if the character set was changed successfully, otherwise false. - */ - function SetCharSet($charset_name) + function setCharSet($charset) { - if (!method_exists($this->_connectionID,'set_charset')) { + if (!$this->_connectionID || !method_exists($this->_connectionID,'set_charset')) { return false; } - if ($this->charSet !== $charset_name) { - $if = @$this->_connectionID->set_charset($charset_name); - return ($if === true & $this->getCharSet() == $charset_name); - } else { - return true; + if ($this->charSet !== $charset) { + if (!$this->_connectionID->set_charset($charset)) { + return false; + } + $this->getCharSet(); } + return true; } } diff --git a/lib/adodb/drivers/adodb-mysqlpo.inc.php b/lib/adodb/drivers/adodb-mysqlpo.inc.php index a1f797e07c9..8aa7779ad46 100644 --- a/lib/adodb/drivers/adodb-mysqlpo.inc.php +++ b/lib/adodb/drivers/adodb-mysqlpo.inc.php @@ -1,24 +1,30 @@ - - 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. - - Requires mysql client. Works on Windows and Unix. -*/ +/** + * Portable MySQL driver + * + * @deprecated + * + * 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. + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); diff --git a/lib/adodb/drivers/adodb-mysqlt.inc.php b/lib/adodb/drivers/adodb-mysqlt.inc.php index fd1fa3c57f8..cccd93f8d34 100644 --- a/lib/adodb/drivers/adodb-mysqlt.inc.php +++ b/lib/adodb/drivers/adodb-mysqlt.inc.php @@ -1,21 +1,30 @@ + */ - First cut at the Netezza Driver by Josh Eldridge joshuae74#hotmail.com - Based on the previous postgres drivers. - http://www.netezza.com/ - Major Additions/Changes: - MetaDatabasesSQL, MetaTablesSQL, MetaColumnsSQL - Note: You have to have admin privileges to access the system tables - Removed non-working keys code (Netezza has no concept of keys) - Fixed the way data types and lengths are returned in MetaColumns() - as well as added the default lengths for certain types - Updated public variables for Netezza - Still need to remove blob functions, as Netezza doesn't support blob -*/ // security - hide paths if (!defined('ADODB_DIR')) die(); diff --git a/lib/adodb/drivers/adodb-oci8.inc.php b/lib/adodb/drivers/adodb-oci8.inc.php index 866b229185f..e541b6b6a0a 100644 --- a/lib/adodb/drivers/adodb-oci8.inc.php +++ b/lib/adodb/drivers/adodb-oci8.inc.php @@ -1,20 +1,25 @@ - - 13 Nov 2000 jlim - removed all ora_* references. -*/ +/** + * FileDescription + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + * @author John Lim + * @author George Fourlanos + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -106,12 +111,12 @@ END; * Legacy compatibility for sequence names for emulated auto-increments */ public $useCompactAutoIncrements = false; - + /* * Defines the schema name for emulated auto-increment columns */ public $schema = false; - + /* * Defines the prefix for emulated auto-increment columns */ @@ -313,33 +318,32 @@ END; { return " NVL($field, $ifNull) "; // if Oracle } - - function _insertid($tabname,$column='') + + protected function _insertID($table = '', $column = '') { - - if (!$this->seqField) + + if (!$this->seqField) return false; - - if ($this->schema) + if ($this->schema) { - $t = strpos($tabname,'.'); - if ($t !== false) - $tab = substr($tabname,$t+1); - else - $tab = $tabname; - + $t = strpos($table,'.'); + if ($t !== false) + $tab = substr($table,$t+1); + else + $tab = $table; + if ($this->useCompactAutoIncrements) $tab = sprintf('%u',crc32(strtolower($tab))); - + $seqname = $this->schema.'.'.$this->seqPrefix.$tab; - } - else + } + else { if ($this->useCompactAutoIncrements) - $tabname = sprintf('%u',crc32(strtolower($tabname))); - - $seqname = $this->seqPrefix.$tabname; + $table = sprintf('%u',crc32(strtolower($table))); + + $seqname = $this->seqPrefix.$table; } if (strlen($seqname) > 30) @@ -347,7 +351,7 @@ END; * We cannot successfully identify the sequence */ return false; - + return $this->getOne("SELECT $seqname.currval FROM dual"); } @@ -1598,7 +1602,7 @@ class ADORecordset_oci8 extends ADORecordSet { $this->adodbFetchMode = $mode; $this->_queryID = $queryID; } - + /** * Overrides the core destructor method as that causes problems here * diff --git a/lib/adodb/drivers/adodb-oci805.inc.php b/lib/adodb/drivers/adodb-oci805.inc.php index 38f9c79aa0a..01958282c8f 100644 --- a/lib/adodb/drivers/adodb-oci805.inc.php +++ b/lib/adodb/drivers/adodb-oci805.inc.php @@ -1,18 +1,27 @@ - - Should some emulation of RecordCount() be implemented? - -*/ +/** + * Portable version of Oracle oci8 driver + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * Portable version of oci8 driver, to make it more similar to other database + * drivers. The main differences are + * 1. that the OCI_ASSOC names are in lowercase instead of uppercase. + * 2. bind variables are mapped using ? instead of : + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); diff --git a/lib/adodb/drivers/adodb-oci8quercus.inc.php b/lib/adodb/drivers/adodb-oci8quercus.inc.php index d2b5117b48b..f9312c9d718 100644 --- a/lib/adodb/drivers/adodb-oci8quercus.inc.php +++ b/lib/adodb/drivers/adodb-oci8quercus.inc.php @@ -1,23 +1,23 @@ - - Should some emulation of RecordCount() be implemented? - -*/ +/** + * Oracle "quercus" driver. + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); diff --git a/lib/adodb/drivers/adodb-odbc.inc.php b/lib/adodb/drivers/adodb-odbc.inc.php index 69c573caa83..a9705e2d80c 100644 --- a/lib/adodb/drivers/adodb-odbc.inc.php +++ b/lib/adodb/drivers/adodb-odbc.inc.php @@ -1,17 +1,24 @@ curMode = SQL_CUR_USE_ODBC; -$db->Connect($dsn, $userid, $pwd); - - - -USING CLI INTERFACE -=================== - -I have had reports that the $host and $database params have to be reversed in -Connect() when using the CLI interface. From Halmai Csongor csongor.halmai#nexum.hu: - -> The symptom is that if I change the database engine from postgres or any other to DB2 then the following -> connection command becomes wrong despite being described this version to be correct in the docs. -> -> $connection_object->Connect( $DATABASE_HOST, $DATABASE_AUTH_USER_NAME, $DATABASE_AUTH_PASSWORD, $DATABASE_NAME ) -> -> In case of DB2 I had to swap the first and last arguments in order to connect properly. - - -System Error 5 -============== -IF you get a System Error 5 when trying to Connect/Load, it could be a permission problem. Give the user connecting -to DB2 full rights to the DB2 SQLLIB directory, and place the user in the DBUSERS group. -*/ +/** + * DB2 driver via ODBC + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -131,7 +62,7 @@ class ADODB_ODBC_DB2 extends ADODB_odbc { return array('description'=>'DB2 ODBC driver', 'version'=>$vers); } - function _insertid() + protected function _insertID($table = '', $column = '') { return $this->GetOne($this->identitySQL); } diff --git a/lib/adodb/drivers/adodb-odbc_mssql.inc.php b/lib/adodb/drivers/adodb-odbc_mssql.inc.php index 19fdd604bef..37185aac32d 100644 --- a/lib/adodb/drivers/adodb-odbc_mssql.inc.php +++ b/lib/adodb/drivers/adodb-odbc_mssql.inc.php @@ -1,18 +1,23 @@ +/** + * ODBTP driver + * + * @deprecated will be removed in ADOdb version 6 + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + * @author stefan bogdan + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -76,7 +87,7 @@ class ADODB_odbtp extends ADOConnection{ } */ - function _insertid() + protected function _insertID($table = '', $column = '') { // SCOPE_IDENTITY() // Returns the last IDENTITY value inserted into an IDENTITY column in diff --git a/lib/adodb/drivers/adodb-odbtp_unicode.inc.php b/lib/adodb/drivers/adodb-odbtp_unicode.inc.php index 4ad997bb71a..190c3ab5ea0 100644 --- a/lib/adodb/drivers/adodb-odbtp_unicode.inc.php +++ b/lib/adodb/drivers/adodb-odbtp_unicode.inc.php @@ -1,30 +1,36 @@ +/** + * ODBTP Unicode driver. + * + * @deprecated will be removed in ADOdb version 6 + * + * Because the ODBTP server sends and reads UNICODE text data using UTF-8 + * encoding, the following HTML meta tag must be included within the HTML + * head section of every HTML form and script page: + * + * Also, all SQL query strings must be submitted as UTF-8 encoded text. + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + * @author Robert Twitty + */ // security - hide paths if (!defined('ADODB_DIR')) die(); -/* - Because the ODBTP server sends and reads UNICODE text data using UTF-8 - encoding, the following HTML meta tag must be included within the HTML - head section of every HTML form and script page: - - - - Also, all SQL query strings must be submitted as UTF-8 encoded text. -*/ - if (!defined('_ADODB_ODBTP_LAYER')) { include_once(ADODB_DIR."/drivers/adodb-odbtp.inc.php"); } diff --git a/lib/adodb/drivers/adodb-oracle.inc.php b/lib/adodb/drivers/adodb-oracle.inc.php index d8d68b08d75..1a2735b1474 100644 --- a/lib/adodb/drivers/adodb-oracle.inc.php +++ b/lib/adodb/drivers/adodb-oracle.inc.php @@ -1,18 +1,25 @@ pdoParameters[\PDO::ATTR_PERSISTENT] = true; - } - + } + try { $this->_connectionID = new \PDO($argDSN, $argUsername, $argPassword, $this->pdoParameters); } catch (Exception $e) { @@ -197,7 +197,7 @@ class ADODB_pdo extends ADOConnection { $this->_connectionID->setAttribute($k,$v); } } - + $class = 'ADODB_pdo_'.$this->dsnType; //$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true); switch($this->dsnType) { @@ -273,10 +273,10 @@ class ADODB_pdo extends ADOConnection { return $this->_driver->MetaColumns($table,$normalize); } - public function metaIndexes($table,$normalize=true) + public function metaIndexes($table,$normalize=true,$owner=false) { if (method_exists($this->_driver,'metaIndexes')) - return $this->_driver->metaIndexes($table,$normalize); + return $this->_driver->metaIndexes($table,$normalize,$owner); } /** @@ -559,12 +559,16 @@ class ADODB_pdo extends ADOConnection { } else { $stmt = $this->_connectionID->prepare($sql); } - + if ($stmt) { if ($this->_driver instanceof ADODB_pdo) { $this->_driver->debug = $this->debug; } if ($inputarr) { + /* + * inputarr must be numeric + */ + $inputarr = array_values($inputarr); $ok = $stmt->execute($inputarr); } else { @@ -605,13 +609,10 @@ class ADODB_pdo extends ADOConnection { function _affectedrows() { - if(method_exists($this->_driver, '_affectedrows')) - return $this->_driver->_affectedrows(); - return ($this->_stmt) ? $this->_stmt->rowCount() : 0; } - function _insertid() + protected function _insertID($table = '', $column = '') { return ($this->_connectionID) ? $this->_connectionID->lastInsertId() : 0; } @@ -829,22 +830,22 @@ class ADORecordSet_pdo extends ADORecordSet { } //adodb_pr($arr); $o->name = $arr['name']; - if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") + if (isset($arr['sqlsrv:decl_type']) && $arr['sqlsrv:decl_type'] <> "null") { /* * If the database is SQL server, use the native built-ins */ $o->type = $arr['sqlsrv:decl_type']; } - elseif (isset($arr['native_type']) && $arr['native_type'] <> "null") + elseif (isset($arr['native_type']) && $arr['native_type'] <> "null") { $o->type = $arr['native_type']; } - else + else { $o->type = adodb_pdo_type($arr['pdo_type']); } - + $o->max_length = $arr['len']; $o->precision = $arr['precision']; diff --git a/lib/adodb/drivers/adodb-pdo_dblib.inc.php b/lib/adodb/drivers/adodb-pdo_dblib.inc.php index 1a688dca1a8..aae561bf591 100644 --- a/lib/adodb/drivers/adodb-pdo_dblib.inc.php +++ b/lib/adodb/drivers/adodb-pdo_dblib.inc.php @@ -2,13 +2,21 @@ /** * ADOdb PDO dblib driver. * - * Released under both BSD license and Lesser GPL library license. - * Whenever there is any discrepancy between the two licenses, the BSD license - * will take precedence. + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. * - * @version v5.21.0 2021-02-27 - * @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved. - * @copyright (c) 2019 Damien Regad, Mark Newnham and the ADOdb community + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2019 Damien Regad, Mark Newnham and the ADOdb community */ class ADODB_pdo_dblib extends ADODB_pdo diff --git a/lib/adodb/drivers/adodb-pdo_firebird.inc.php b/lib/adodb/drivers/adodb-pdo_firebird.inc.php index cd7b4c73d45..0ee5e02b6c9 100644 --- a/lib/adodb/drivers/adodb-pdo_firebird.inc.php +++ b/lib/adodb/drivers/adodb-pdo_firebird.inc.php @@ -1,19 +1,24 @@ fetchMode !== FALSE) { + $savem = $this->setFetchMode(FALSE); + } + + // get index details + $rs = $this->execute(sprintf('SHOW INDEXES FROM %s',$table)); + + // restore fetchmode + if (isset($savem)) { + $this->setFetchMode($savem); + } + $ADODB_FETCH_MODE = $save; + + if (!is_object($rs)) { + return $false; + } + + $indexes = array (); + + // parse index data into array + while ($row = $rs->fetchRow()) { + if ($primary == FALSE AND $row[2] == 'PRIMARY') { + continue; + } + + if (!isset($indexes[$row[2]])) { + $indexes[$row[2]] = array( + 'unique' => ($row[1] == 0), + 'columns' => array() + ); + } + + $indexes[$row[2]]['columns'][$row[3] - 1] = $row[4]; + } + + // sort columns by order in the index + foreach ( array_keys ($indexes) as $index ) + { + ksort ($indexes[$index]['columns']); + } + + return $indexes; + } function Concat() { diff --git a/lib/adodb/drivers/adodb-pdo_oci.inc.php b/lib/adodb/drivers/adodb-pdo_oci.inc.php index 8bbdf42f579..9a05ee6a9cb 100644 --- a/lib/adodb/drivers/adodb-pdo_oci.inc.php +++ b/lib/adodb/drivers/adodb-pdo_oci.inc.php @@ -1,16 +1,23 @@ + * @author Sid Dunayer + */ class ADODB_pdo_sqlite extends ADODB_pdo { var $metaTablesSQL = "SELECT name FROM sqlite_master WHERE type='table'"; diff --git a/lib/adodb/drivers/adodb-pdo_sqlsrv.inc.php b/lib/adodb/drivers/adodb-pdo_sqlsrv.inc.php index ba5180ecef4..ed73f3a247f 100644 --- a/lib/adodb/drivers/adodb-pdo_sqlsrv.inc.php +++ b/lib/adodb/drivers/adodb-pdo_sqlsrv.inc.php @@ -1,8 +1,25 @@ - jlim - changed concat operator to || and data types to MetaType to match documented pgsql types - see http://www.postgresql.org/devel-corner/docs/postgres/datatype.htm - 22 Nov 2000 jlim - added changes to FetchField() and MetaTables() contributed by "raser" - 27 Nov 2000 jlim - added changes to _connect/_pconnect from ideas by "Lennie" - 15 Dec 2000 jlim - added changes suggested by Additional code changes by "Eric G. Werk" egw@netguide.dk. - 31 Jan 2002 jlim - finally installed postgresql. testing - 01 Mar 2001 jlim - Freek Dijkstra changes, also support for text type - - See http://www.varlena.com/varlena/GeneralBits/47.php - - -- What indexes are on my table? - select * from pg_indexes where tablename = 'tablename'; - - -- What triggers are on my table? - select c.relname as "Table", t.tgname as "Trigger Name", - t.tgconstrname as "Constraint Name", t.tgenabled as "Enabled", - t.tgisconstraint as "Is Constraint", cc.relname as "Referenced Table", - p.proname as "Function Name" - from pg_trigger t, pg_class c, pg_class cc, pg_proc p - where t.tgfoid = p.oid and t.tgrelid = c.oid - and t.tgconstrrelid = cc.oid - and c.relname = 'tablename'; - - -- What constraints are on my table? - select r.relname as "Table", c.conname as "Constraint Name", - contype as "Constraint Type", conkey as "Key Columns", - confkey as "Foreign Columns", consrc as "Source" - from pg_class r, pg_constraint c - where r.oid = c.conrelid - and relname = 'tablename'; - -*/ +/** + * ADOdb PostgreSQL 6.4 driver + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); -function adodb_addslashes($s) -{ - $len = strlen($s); - if ($len == 0) return "''"; - if (strncmp($s,"'",1) === 0 && substr($s,$len-1) == "'") return $s; // already quoted - - return "'".addslashes($s)."'"; -} - class ADODB_postgres64 extends ADOConnection{ var $databaseType = 'postgres64'; var $dataProvider = 'postgres'; @@ -183,8 +149,10 @@ class ADODB_postgres64 extends ADOConnection{ * Using a OID as a unique identifier is not generally wise. * Unless you are very careful, you might end up with a tuple having * a different OID if a database must be reloaded. + * + * @inheritDoc */ - function _insertid($table,$column) + protected function _insertID($table = '', $column = '') { if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false; $oid = pg_last_oid($this->_resultid); @@ -705,35 +673,57 @@ class ADODB_postgres64 extends ADOConnection{ return $indexes; } - // returns true or false - // - // examples: - // $db->Connect("host=host1 user=user1 password=secret port=4341"); - // $db->Connect('host1','user1','secret'); - function _connect($str,$user='',$pwd='',$db='',$ctype=0) + /** + * Connect to a database. + * + * Examples: + * $db->Connect("host=host1 user=user1 password=secret port=4341"); + * $db->Connect('host1:4341', 'user1', 'secret'); + * + * @param string $str pg_connect() Connection string or Hostname[:port] + * @param string $user (Optional) The username to connect as. + * @param string $pwd (Optional) The password to connect with. + * @param string $db (Optional) The name of the database to start in when connected. + * @param int $ctype Connection type + * @return bool|null True if connected successfully, false if connection failed, or + * null if the PostgreSQL extension is not loaded. + */ + function _connect($str, $user='', $pwd='', $db='', $ctype=0) { - if (!function_exists('pg_connect')) return null; + if (!function_exists('pg_connect')) { + return null; + } $this->_errorMsg = false; + // If $user, $pwd and $db are all null, then $str is a pg_connect() + // connection string. Otherwise we expect it to be a hostname, + // with optional port separated by ':' if ($user || $pwd || $db) { - $user = adodb_addslashes($user); - $pwd = adodb_addslashes($pwd); - if (strlen($db) == 0) $db = 'template1'; - $db = adodb_addslashes($db); - if ($str) { - $host = explode(":", $str); - if ($host[0]) $str = "host=".adodb_addslashes($host[0]); - else $str = ''; - if (isset($host[1])) $str .= " port=$host[1]"; - else if (!empty($this->port)) $str .= " port=".$this->port; + // Hostname & port + if ($str) { + $host = explode(':', $str); + if ($host[0]) { + $conn['host'] = $host[0]; + } + if (isset($host[1])) { + $conn['port'] = (int)$host[1]; + } elseif (!empty($this->port)) { + $conn['port'] = $this->port; + } } - if ($user) $str .= " user=".$user; - if ($pwd) $str .= " password=".$pwd; - if ($db) $str .= " dbname=".$db; - } + $conn['user'] = $user; + $conn['password'] = $pwd; + // @TODO not sure why we default to 'template1', pg_connect() uses the username when dbname is empty + $conn['dbname'] = $db ?: 'template1'; - //if ($user) $linea = "user=$user host=$linea password=$pwd dbname=$db port=5432"; + // Generate connection string + $str = ''; + foreach ($conn as $param => $value) { + // Escaping single quotes and backslashes per pg_connect() documentation + $str .= $param . "='" . addcslashes($value, "'\\") . "' "; + } + } if ($ctype === 1) { // persistent $this->_connectionID = pg_pconnect($str); @@ -761,11 +751,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', '>=')) { - $version = pg_version($this->connectionID); - if (version_compare($info['client'], '9.2', '<')) { - $this->Execute('set bytea_output=escape'); - } + if (!empty($this->connection->noBlobs) + && version_compare($info['version'], '9.0', '>=') + && version_compare($info['client'], '9.2', '<') + ) { + $this->Execute('set bytea_output=escape'); } return true; @@ -876,7 +866,7 @@ class ADODB_postgres64 extends ADOConnection{ if ($this->_errorMsg !== false) { return $this->_errorMsg; } - + if (!empty($this->_resultid)) { $this->_errorMsg = @pg_result_error($this->_resultid); if ($this->_errorMsg) { @@ -974,10 +964,9 @@ class ADORecordSet_postgres64 extends ADORecordSet{ return $row; } - - function _initrs() + function _initRS() { - global $ADODB_COUNTRECS; + global $ADODB_COUNTRECS; $qid = $this->_queryID; $this->_numOfRows = ($ADODB_COUNTRECS)? @pg_num_rows($qid):-1; $this->_numOfFields = @pg_num_fields($qid); @@ -992,10 +981,11 @@ class ADORecordSet_postgres64 extends ADORecordSet{ } } - /* Use associative array to get fields array */ - function Fields($colname) + function fields($colname) { - if ($this->fetchMode != PGSQL_NUM) return @$this->fields[$colname]; + if ($this->fetchMode != PGSQL_NUM) { + return @$this->fields[$colname]; + } if (!$this->bind) { $this->bind = array(); @@ -1007,14 +997,14 @@ class ADORecordSet_postgres64 extends ADORecordSet{ return $this->fields[$this->bind[strtoupper($colname)]]; } - function FetchField($off = 0) + function fetchField($fieldOffset = 0) { // offsets begin at 0 - $o= new ADOFieldObject(); - $o->name = @pg_field_name($this->_queryID,$off); - $o->type = @pg_field_type($this->_queryID,$off); - $o->max_length = @pg_field_size($this->_queryID,$off); + $o = new ADOFieldObject(); + $o->name = @pg_field_name($this->_queryID, $fieldOffset); + $o->type = @pg_field_type($this->_queryID, $fieldOffset); + $o->max_length = @pg_field_size($this->_queryID, $fieldOffset); return $o; } diff --git a/lib/adodb/drivers/adodb-postgres7.inc.php b/lib/adodb/drivers/adodb-postgres7.inc.php index 6de6c1c6ceb..59174f67884 100644 --- a/lib/adodb/drivers/adodb-postgres7.inc.php +++ b/lib/adodb/drivers/adodb-postgres7.inc.php @@ -1,17 +1,23 @@ charSet = @pg_client_encoding($this->_connectionID); - if (!$this->charSet) { + if (!$this->_connectionID) { return false; - } else { - return $this->charSet; } + $this->charSet = pg_client_encoding($this->_connectionID); + return $this->charSet ?: false; } - // SetCharSet - switch the client encoding - function SetCharSet($charset_name) + /** + * Sets the client-side character set (encoding). + * + * Allows managing client encoding - very important if the database and + * the output target (i.e. HTML) don't match; for instance, you may have a + * UNICODE database and server your pages as WIN1251, etc. + * + * Supported on PostgreSQL 7.0 and above. Available charsets depend on + * PostgreSQL version and the distribution's compile flags. + * + * @param string $charset The character set to switch to. + * + * @return bool True if the character set was changed successfully, false otherwise. + */ + function setCharSet($charset) { - $this->GetCharSet(); - if ($this->charSet !== $charset_name) { - $if = pg_set_client_encoding($this->_connectionID, $charset_name); - if ($if == "0" & $this->GetCharSet() == $charset_name) { - return true; - } else return false; - } else return true; + if ($this->charSet !== $charset) { + if (!$this->_connectionID || pg_set_client_encoding($this->_connectionID, $charset) != 0) { + return false; + } + $this->getCharSet(); + } + return true; } } diff --git a/lib/adodb/drivers/adodb-postgres8.inc.php b/lib/adodb/drivers/adodb-postgres8.inc.php index 6f5859ad76c..37c2aae1413 100644 --- a/lib/adodb/drivers/adodb-postgres8.inc.php +++ b/lib/adodb/drivers/adodb-postgres8.inc.php @@ -1,15 +1,23 @@ GetOne("SELECT lastval()") diff --git a/lib/adodb/drivers/adodb-postgres9.inc.php b/lib/adodb/drivers/adodb-postgres9.inc.php index add6521d71d..fb9c6785e74 100644 --- a/lib/adodb/drivers/adodb-postgres9.inc.php +++ b/lib/adodb/drivers/adodb-postgres9.inc.php @@ -1,15 +1,23 @@ GetOne("SELECT $table.CURRVAL FROM DUAL"); } diff --git a/lib/adodb/drivers/adodb-sqlanywhere.inc.php b/lib/adodb/drivers/adodb-sqlanywhere.inc.php index ca54175646b..88897af9267 100644 --- a/lib/adodb/drivers/adodb-sqlanywhere.inc.php +++ b/lib/adodb/drivers/adodb-sqlanywhere.inc.php @@ -1,47 +1,23 @@ create_blobvar($blobVarName); - - b) load blob var from file. $filename must be complete path - - $dbcon->load_blobvar_from_file($blobVarName, $filename); - - c) Use the $blobVarName in SQL insert or update statement in the values - clause: - - $recordSet = $dbconn->Execute('INSERT INTO tabname (idcol, blobcol) ' - . - 'VALUES (\'test\', ' . $blobVarName . ')'); - - instead of loading blob from a file, you can also load from - an unformatted (raw) blob variable: - $dbcon->load_blobvar_from_var($blobVarName, $varName); - - d) drop blob variable on db server to free up resources: - $dbconn->drop_blobvar($blobVarName); - - Sybase_SQLAnywhere data driver. Requires ODBC. - -*/ +/** + * SAP SQL Anywhere driver (previously Sybase SQL Anywhere) + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -54,13 +30,15 @@ if (!defined('ADODB_SYBASE_SQLANYWHERE')){ define('ADODB_SYBASE_SQLANYWHERE',1); - class ADODB_sqlanywhere extends ADODB_odbc { - var $databaseType = "sqlanywhere"; - var $hasInsertID = true; + class ADODB_sqlanywhere extends ADODB_odbc + { + var $databaseType = "sqlanywhere"; + var $hasInsertID = true; - function _insertid() { - return $this->GetOne('select @@identity'); - } + protected function _insertID($table = '', $column = '') + { + return $this->GetOne('select @@identity'); + } function create_blobvar($blobVarName) { $this->Execute("create variable $blobVarName long binary"); diff --git a/lib/adodb/drivers/adodb-sqlite.inc.php b/lib/adodb/drivers/adodb-sqlite.inc.php index 70376afc434..0711f1dde1c 100644 --- a/lib/adodb/drivers/adodb-sqlite.inc.php +++ b/lib/adodb/drivers/adodb-sqlite.inc.php @@ -1,21 +1,27 @@ hasInsertID = true; } - function _insertid() + protected function _insertID($table = '', $column = '') { return sqlite_last_insert_rowid($this->_connectionID); } diff --git a/lib/adodb/drivers/adodb-sqlite3.inc.php b/lib/adodb/drivers/adodb-sqlite3.inc.php index 6fd7d31848a..548727d8bce 100644 --- a/lib/adodb/drivers/adodb-sqlite3.inc.php +++ b/lib/adodb/drivers/adodb-sqlite3.inc.php @@ -1,21 +1,25 @@ hasInsertID = true; } - function _insertid() + protected function _insertID($table = '', $column = '') { return $this->_connectionID->lastInsertRowID(); } @@ -417,7 +421,7 @@ class ADODB_sqlite3 extends ADOConnection { { return $this->_connectionID->close(); } - + function metaIndexes($table, $primary = FALSE, $owner = false) { $false = false; @@ -428,9 +432,9 @@ class ADODB_sqlite3 extends ADOConnection { if ($this->fetchMode !== FALSE) { $savem = $this->SetFetchMode(FALSE); } - + $pragmaData = array(); - + /* * If we want the primary key, we must extract * it from the table statement, and the pragma @@ -442,22 +446,22 @@ class ADODB_sqlite3 extends ADOConnection { ); $pragmaData = $this->getAll($sql); } - + /* * Exclude the empty entry for the primary index */ $sqlite = "SELECT name,sql - FROM sqlite_master - WHERE type='index' + FROM sqlite_master + WHERE type='index' AND sql IS NOT NULL AND LOWER(tbl_name)='%s'"; - + $SQL = sprintf($sqlite, strtolower($table) ); - + $rs = $this->execute($SQL); - + if (!is_object($rs)) { if (isset($savem)) { $this->SetFetchMode($savem); @@ -467,10 +471,10 @@ class ADODB_sqlite3 extends ADOConnection { } $indexes = array (); - - while ($row = $rs->FetchRow()) + + while ($row = $rs->FetchRow()) { - + if (!isset($indexes[$row[0]])) { $indexes[$row[0]] = array( 'unique' => preg_match("/unique/i",$row[1]), @@ -485,26 +489,26 @@ class ADODB_sqlite3 extends ADOConnection { preg_match_all('/\((.*)\)/',$row[1],$indexExpression); $indexes[$row[0]]['columns'] = array_map('trim',explode(',',$indexExpression[1][0])); } - + if (isset($savem)) { $this->SetFetchMode($savem); $ADODB_FETCH_MODE = $save; } - + /* * If we want primary, add it here */ if ($primary){ - + /* * Check the previously retrieved pragma to search * with a closure */ $pkIndexData = array('unique'=>1,'columns'=>array()); - + $pkCallBack = function ($value, $key) use (&$pkIndexData) { - + /* * As we iterate the elements check for pk index and sort */ @@ -514,7 +518,7 @@ class ADODB_sqlite3 extends ADOConnection { ksort($pkIndexData['columns']); } }; - + array_walk($pragmaData,$pkCallBack); /* @@ -524,7 +528,7 @@ class ADODB_sqlite3 extends ADOConnection { if (count($pkIndexData['columns']) > 0) $indexes['PRIMARY'] = $pkIndexData; } - + return $indexes; } diff --git a/lib/adodb/drivers/adodb-sqlitepo.inc.php b/lib/adodb/drivers/adodb-sqlitepo.inc.php index 4b56cbe0616..cb69ff9e965 100644 --- a/lib/adodb/drivers/adodb-sqlitepo.inc.php +++ b/lib/adodb/drivers/adodb-sqlitepo.inc.php @@ -1,23 +1,31 @@ + */ if (!defined('ADODB_DIR')) die(); diff --git a/lib/adodb/drivers/adodb-sybase.inc.php b/lib/adodb/drivers/adodb-sybase.inc.php index 12cb7f05590..b8db0747970 100644 --- a/lib/adodb/drivers/adodb-sybase.inc.php +++ b/lib/adodb/drivers/adodb-sybase.inc.php @@ -1,21 +1,24 @@ + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -44,11 +47,15 @@ class ADODB_sybase extends ADOConnection { var $port; - // might require begintrans -- committrans - function _insertid() + /** + * might require begintrans -- committrans + * @inheritDoc + */ + protected function _insertID($table = '', $column = '') { return $this->GetOne('select @@identity'); } + // might require begintrans -- committrans function _affectedrows() { diff --git a/lib/adodb/drivers/adodb-sybase_ase.inc.php b/lib/adodb/drivers/adodb-sybase_ase.inc.php index 8490e8fb468..d301ba99616 100644 --- a/lib/adodb/drivers/adodb-sybase_ase.inc.php +++ b/lib/adodb/drivers/adodb-sybase_ase.inc.php @@ -1,17 +1,24 @@ + */ require_once ADODB_DIR."/drivers/adodb-sybase.inc.php"; diff --git a/lib/adodb/drivers/adodb-text.inc.php b/lib/adodb/drivers/adodb-text.inc.php index cd43500ae48..77ad06a0ba0 100644 --- a/lib/adodb/drivers/adodb-text.inc.php +++ b/lib/adodb/drivers/adodb-text.inc.php @@ -1,63 +1,25 @@ Connect($array,[$types],[$colnames]); - - Parameter $array is the 2 dimensional array of data. The first row can contain the - column names. If column names is not defined in first row, you MUST define $colnames, - the 3rd parameter. - - Parameter $types is optional. If defined, it should contain an array matching - the number of columns in $array, with each element matching the correct type defined - by MetaType: (B,C,I,L,N). If undefined, we will probe for $this->_proberows rows - to guess the type. Only C,I and N are recognised. - - Parameter $colnames is optional. If defined, it is an array that contains the - column names of $array. If undefined, we assume the first row of $array holds the - column names. - - The Execute() function will return a recordset. The recordset works like a normal recordset. - We have partial support for SQL parsing. We process the SQL using the following rules: - - 1. SQL order by's always work for the first column ordered. Subsequent cols are ignored - - 2. All operations take place on the same table. No joins possible. In fact the FROM clause - is ignored! You can use any name for the table. - - 3. To simplify code, all columns are returned, except when selecting 1 column - - $rs = $db->Execute('select col1,col2 from table'); // sql ignored, will generate all cols - - We special case handling of 1 column because it is used in filter popups - - $rs = $db->Execute('select col1 from table'); - // sql accepted and processed -- any table name is accepted - - $rs = $db->Execute('select distinct col1 from table'); - // sql accepted and processed - -4. Where clauses are ignored, but searching with the 3rd parameter of Execute is permitted. - This has to use PHP syntax and we will eval() it. You can even use PHP functions. - - $rs = $db->Execute('select * from table',false,"\$COL1='abc' and $\COL2=3") - // the 3rd param is searched -- make sure that $COL1 is a legal column name - // and all column names must be in upper case. - -4. Group by, having, other clauses are ignored - -5. Expression columns, min(), max() are ignored - -6. All data is readonly. Only SELECTs permitted. -*/ +/** + * ADOdb Plain Text driver + * + * @deprecated + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // security - hide paths if (!defined('ADODB_DIR')) die(); @@ -97,11 +59,6 @@ class ADODB_text extends ADOConnection { return sizeof($this->_origarray); } - function _insertid() - { - return false; - } - function _affectedrows() { return false; diff --git a/lib/adodb/drivers/adodb-vfp.inc.php b/lib/adodb/drivers/adodb-vfp.inc.php index 7369510e073..bb4351683ad 100644 --- a/lib/adodb/drivers/adodb-vfp.inc.php +++ b/lib/adodb/drivers/adodb-vfp.inc.php @@ -1,17 +1,25 @@ -*/ +/** + * RecordSet to HTML Table + * + * Convert a recordset to a html table. Multiple tables are generated + * if the number of rows is > $gSQLBlockRows. This is because + * web browsers normally require the whole table to be downloaded + * before it can be rendered, so we break the output into several + * smaller, faster rendering tables. + * + * This file is part of ADOdb, a Database Abstraction Layer library for PHP. + * + * @package ADOdb + * @link https://adodb.org Project's web site and documentation + * @link https://github.com/ADOdb/ADOdb Source code and issue tracker + * + * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause + * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, + * any later version. This means you can use it in proprietary products. + * See the LICENSE.md file distributed with this source code for details. + * @license BSD-3-Clause + * @license LGPL-2.1-or-later + * + * @copyright 2000-2013 John Lim + * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community + */ // specific code for tohtml GLOBAL $gSQLMaxRows,$gSQLBlockRows,$ADODB_ROUND; @@ -17,14 +32,6 @@ $ADODB_ROUND=4; // rounding $gSQLMaxRows = 1000; // max no of rows to download $gSQLBlockRows=20; // max no of rows per table block -// RecordSet to HTML Table -//------------------------------------------------------------ -// Convert a recordset to a html table. Multiple tables are generated -// if the number of rows is > $gSQLBlockRows. This is because -// web browsers normally require the whole table to be downloaded -// before it can be rendered, so we break the output into several -// smaller faster rendering tables. -// // $rs: the recordset // $ztabhtml: the table tag attributes (optional) // $zheaderarray: contains the replacement strings for the headers (optional) From 0023f6377216f18403d35f39bcf09bee6d784e88 Mon Sep 17 00:00:00 2001 From: Amaia Anabitarte Date: Tue, 1 Feb 2022 17:12:43 +0100 Subject: [PATCH 2/2] MDL-73664 lib: Set Moodle files after ADODB upgrade --- lib/adodb/adodb-iterator.inc.php | 26 -------------------------- lib/adodb/adodb-php4.inc.php | 16 ---------------- lib/adodb/lang/adodb-en.inc.php | 19 +++++++++++++++++++ lib/adodb/readme_moodle.txt | 11 ++++------- lib/thirdpartylibs.xml | 2 +- 5 files changed, 24 insertions(+), 50 deletions(-) delete mode 100644 lib/adodb/adodb-iterator.inc.php delete mode 100644 lib/adodb/adodb-php4.inc.php diff --git a/lib/adodb/adodb-iterator.inc.php b/lib/adodb/adodb-iterator.inc.php deleted file mode 100644 index b5c9133d87b..00000000000 --- a/lib/adodb/adodb-iterator.inc.php +++ /dev/null @@ -1,26 +0,0 @@ -Execute("select * from adoxyz"); - foreach($rs as $k => $v) { - echo $k; print_r($v); echo "
"; - } - - - Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2 - - - Moved to adodb.inc.php to improve performance. - */ diff --git a/lib/adodb/adodb-php4.inc.php b/lib/adodb/adodb-php4.inc.php deleted file mode 100644 index eea5818b28f..00000000000 --- a/lib/adodb/adodb-php4.inc.php +++ /dev/null @@ -1,16 +0,0 @@ - 'en', diff --git a/lib/adodb/readme_moodle.txt b/lib/adodb/readme_moodle.txt index fcbbf05e35f..26b872986cb 100644 --- a/lib/adodb/readme_moodle.txt +++ b/lib/adodb/readme_moodle.txt @@ -1,4 +1,4 @@ -Description of ADOdb v5.21.0 library import into Moodle 3.11 and up +Description of ADOdb v5.21.4 library import into Moodle 4.0 and up Source: https://github.com/ADOdb/ADOdb @@ -14,15 +14,12 @@ Removed: * lang/* everything but adodb-en.inc.php (originally because they were not utf-8, now because of not used) * nbproject/ (if present) * pear/ - * replicate/ - * scripts/ + * replicate/ (if present) + * scripts/ (if present) * server.php * session/ - * tests/ + * tests/ (if present) Added: * index.html - prevent directory browsing on misconfigured servers * readme_moodle.txt - this file ;-) - -Our changes (to be checked on next update if they are already applied upstream):: - * https://github.com/ADOdb/ADOdb/issues/711 diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml index 4e1bef9172b..329c2978979 100644 --- a/lib/thirdpartylibs.xml +++ b/lib/thirdpartylibs.xml @@ -4,7 +4,7 @@ adodb AdoDB BSD/LGPL - 5.21.0 + 5.21.4 3-Clause/2.1+