summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--adodb-active-record.inc.php105
-rw-r--r--adodb-lib.inc.php75
-rw-r--r--adodb.inc.php33
-rw-r--r--composer.json4
-rw-r--r--docs/changelog.md49
-rw-r--r--drivers/adodb-mssqlnative.inc.php109
-rw-r--r--drivers/adodb-mysqli.inc.php22
-rw-r--r--drivers/adodb-odbc_mssql2012.inc.php10
-rw-r--r--drivers/adodb-postgres64.inc.php14
-rw-r--r--drivers/adodb-sqlite.inc.php23
-rw-r--r--tests/LibTest.php72
-rw-r--r--tests/testsessions.php12
12 files changed, 308 insertions, 220 deletions
diff --git a/adodb-active-record.inc.php b/adodb-active-record.inc.php
index 3c418bf8..8f3b0053 100644
--- a/adodb-active-record.inc.php
+++ b/adodb-active-record.inc.php
@@ -19,6 +19,8 @@
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
+include_once(ADODB_DIR.'/adodb-lib.inc.php');
+
global $_ADODB_ACTIVE_DBS;
global $ADODB_ACTIVE_CACHESECS; // set to true to enable caching of metadata such as field info
global $ACTIVE_RECORD_SAFETY; // set to false to disable safety checks
@@ -74,10 +76,9 @@ function ADODB_SetDatabaseAdapter(&$db, $index=false)
class ADODB_Active_Record {
static $_changeNames = true; // dynamically pluralize table names
- /*
- * Optional parameter that duplicates the ADODB_QUOTE_FIELDNAMES
- */
- static $_quoteNames = false;
+
+ /** @var bool|string Allows override of global $ADODB_QUOTE_FIELDNAMES */
+ public $_quoteNames;
static $_foreignSuffix = '_id'; //
var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat]
@@ -117,7 +118,12 @@ class ADODB_Active_Record {
// php5 constructor
function __construct($table = false, $pkeyarr=false, $db=false)
{
- global $_ADODB_ACTIVE_DBS;
+ global $_ADODB_ACTIVE_DBS, $ADODB_QUOTE_FIELDNAMES;
+
+ // Set the local override for field quoting, only if not defined yet
+ if (!isset($this->_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/adodb-lib.inc.php b/adodb-lib.inc.php
index c1d935ab..ced5e126 100644
--- a/adodb-lib.inc.php
+++ b/adodb-lib.inc.php
@@ -673,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;
@@ -722,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])
@@ -862,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 = '';
@@ -913,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);
/********************************************************/
diff --git a/adodb.inc.php b/adodb.inc.php
index 15a3da97..ea971b8a 100644
--- a/adodb.inc.php
+++ b/adodb.inc.php
@@ -198,7 +198,7 @@ if (!defined('_ADODB_LAYER')) {
/**
* ADODB version as a string.
*/
- $ADODB_vers = 'v5.21.1-dev Unreleased';
+ $ADODB_vers = 'v5.22.0-dev Unreleased';
/**
* Determines whether recordset->RecordCount() is used.
@@ -3829,7 +3829,8 @@ class ADORecordSet implements IteratorAggregate {
*/
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 */
@@ -3848,6 +3849,12 @@ class ADORecordSet implements IteratorAggregate {
/**
+ * @var ADOFieldObject[] Field metadata cache
+ * @see fieldTypesArray()
+ */
+ protected $fieldObjectsCache;
+
+ /**
* Constructor
*
* @param resource|int $queryID Query ID returned by ADOConnection->_query()
@@ -4679,15 +4686,16 @@ class ADORecordSet implements IteratorAggregate {
}
/**
- * Get Field metadata for of a specific column.
+ * Get a Field's metadata from database.
+ *
+ * Must be defined by child class.
*
- * @param fieldoffset is the column position to access(0-based).
+ * @param int $fieldOffset
*
- * @return ADOFieldObject|false for that column, or false.
+ * @return ADOFieldObject|false
*/
- function fetchField($fieldoffset = -1) {
- // must be defined by child class
-
+ function fetchField($fieldOffset)
+ {
return false;
}
@@ -4697,13 +4705,12 @@ class ADORecordSet implements IteratorAggregate {
* @return ADOFieldObject[]
*/
function fieldTypesArray() {
- static $arr = array();
- if (empty($arr)) {
- for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) {
- $arr[] = $this->FetchField($i);
+ if (empty($this->fieldObjectsCache)) {
+ for ($i = 0; $i < $this->_numOfFields; $i++) {
+ $this->fieldObjectsCache[] = $this->fetchField($i);
}
}
- return $arr;
+ return $this->fieldObjectsCache;
}
/**
diff --git a/composer.json b/composer.json
index 133210ee..807866b6 100644
--- a/composer.json
+++ b/composer.json
@@ -30,6 +30,10 @@
"php" : "^5.5.9 || ^7.0 || ^8.0"
},
+ "require-dev" : {
+ "phpunit/phpunit": "^8.5"
+ },
+
"autoload" : {
"files" : ["adodb.inc.php"]
}
diff --git a/docs/changelog.md b/docs/changelog.md
index bf6f274e..2a934c67 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -47,14 +47,57 @@ Older changelogs:
[#635](https://github.com/ADOdb/ADOdb/issues/635)
-## [5.21.1] - Unreleased
+## [5.21.1] - 2021-08-15
+
+### Changed
+
+- Standardized source code file headers
+ [#728](https://github.com/ADOdb/ADOdb/issues/728)
+- Code cleanup: PHPDoc, code style, whitespace, etc.
+ [#691](https://github.com/ADOdb/ADOdb/issues/691)
+ (and others)
### Fixed
+- Caching in FieldTypesArray() causes problems
+ [#687](https://github.com/ADOdb/ADOdb/issues/687)
+- setConnectionParameter() method should not be final
+ [#694](https://github.com/ADOdb/ADOdb/issues/694)
+- Final private methods throw warning (PHP 8)
+ [#711](https://github.com/ADOdb/ADOdb/issues/711)
+- Fix record count when executing SQL with subqueries
+ [#715](https://github.com/ADOdb/ADOdb/issues/715)
+- Incorrect handling of $ADODB_QUOTE_FIELDNAMES = true
+ [#721](https://github.com/ADOdb/ADOdb/issues/721)
+- db2: fix columns always returned in lowercase
+ [#719](https://github.com/ADOdb/ADOdb/issues/719)
+- PDO: Bind parameters fail if sent in associative array
+ [#705](https://github.com/ADOdb/ADOdb/issues/705)
+- mssql: _insertid() doesn't work anymore
+ [#692](https://github.com/ADOdb/ADOdb/issues/692)
- mssql: PHP warnings in dropColumnSQL()
[#696](https://github.com/ADOdb/ADOdb/issues/696)
+- mssql: duplicate key in SQLDate convert formats
+ [#748](https://github.com/ADOdb/ADOdb/issues/748)
+- mysql: affected_rows() returns number instead of false
+ [#604](https://github.com/ADOdb/ADOdb/issues/604)
- mysql: TypeError when calling get/setChangeSet on unset connection (PHP 8)
[#686](https://github.com/ADOdb/ADOdb/issues/686)
+- mysql: TypeError when calling setConnectionParameter() with non-numeric value (PHP 8)
+ [#693](https://github.com/ADOdb/ADOdb/issues/693)
+- pdo: Affected_Rows() throws Notice and returns 0 when rows affected
+ [#733](https://github.com/ADOdb/ADOdb/issues/733)
+- pgsql: sub-selects require aliasing
+ [#736](https://github.com/ADOdb/ADOdb/issues/736)
+- xml: Invalid SQL in extractSchema()
+ [#707](https://github.com/ADOdb/ADOdb/issues/707)
+
+### Removed
+
+- Use of _ADODB_COUNT as workaround for counting in complex queries
+ (introduced in [#88](https://github.com/ADOdb/ADOdb/issues/88))
+ [#715](https://github.com/ADOdb/ADOdb/issues/715)
+
## [5.21.0] - 2021-02-27
@@ -1097,9 +1140,9 @@ Released together with [v4.95](changelog_v4.x.md#495---17-may-2007)
- Adodb5 version,more error checking code now will use exceptions if available.
-[Unreleased]: https://github.com/adodb/adodb/compare/v5.21.0...master
+[Unreleased]: https://github.com/adodb/adodb/compare/v5.21.1...master
-[5.21.1]: https://github.com/adodb/adodb/compare/v5.21.0...hotfix/5.21
+[5.21.1]: https://github.com/adodb/adodb/compare/v5.21.0...v5.21.1
[5.21.0]: https://github.com/adodb/adodb/compare/v5.21.0-rc.1...v5.21.0
[5.21.0-rc.1]: https://github.com/adodb/adodb/compare/v5.21.0-beta.1...v5.21.0-rc.1
[5.21.0-beta.1]: https://github.com/adodb/adodb/compare/v5.20.20...v5.21.0-beta.1
diff --git a/drivers/adodb-mssqlnative.inc.php b/drivers/adodb-mssqlnative.inc.php
index 1852f2c0..6d6a0068 100644
--- a/drivers/adodb-mssqlnative.inc.php
+++ b/drivers/adodb-mssqlnative.inc.php
@@ -298,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++) {
@@ -763,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;$i<count($rows);$i++) {
@@ -1050,13 +1053,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;
@@ -1065,7 +1063,6 @@ class ADORecordset_mssqlnative extends ADORecordSet {
*/
private $fieldObjectsIndex = array();
-
/*
* Cross references the dateTime objects for faster decoding
*/
@@ -1176,47 +1173,55 @@ 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
- * @return ADOFieldObject|ADOFieldObject[]|false
+ * @param int $fieldOffset (optional default=-1 for all
+ * @return mixed an ADOFieldObject, or array of objects
*/
private function _fetchField($fieldOffset = -1)
{
- if (!$this->fieldObjectsRetrieved) {
- // Retrieve all metadata in one go
- $fieldMetaData = sqlsrv_field_metadata($this->_queryID);
- if ($fieldMetaData) {
- $this->_numOfFields = count($fieldMetaData);
- foreach ($fieldMetaData as $key => $value) {
- $fld = new ADOFieldObject;
- // Caution - keys are case-sensitive, must respect casing of values
- $fld->name = $value['Name'];
- $fld->max_length = $value['Size'];
- $fld->column_source = $value['Name'];
- $fld->type = $this->_typeConversion[$value['Type']];
-
- $this->fieldObjects[$key] = $fld;
- $this->fieldObjectsIndex[$fld->name] = $key;
+ if ($this->fieldObjectsRetrieved) {
+ if ($this->fieldObjectsCache) {
+ // Already got the information
+ if ($fieldOffset == -1) {
+ return $this->fieldObjectsCache;
+ } else {
+ return $this->fieldObjectsCache[$fieldOffset];
}
} else {
- $this->_numOfFields = -1;
- $this->fieldObjects = false;
- $this->fieldObjectsIndex = array();
+ // No metadata available
+ return false;
}
- $this->fieldObjectsRetrieved = true;
}
- if ($this->fieldObjects) {
- if ($fieldOffset == -1) {
- return $this->fieldObjects;
- } else {
- return $this->fieldObjects[$fieldOffset];
- }
+ $this->fieldObjectsRetrieved = true;
+ /*
+ * Retrieve all metadata in one go. This is always returned as a
+ * numeric array.
+ */
+ $fieldMetaData = sqlsrv_field_metadata($this->_queryID);
+
+ if (!$fieldMetaData) {
+ // Not a statement that gives us metaData
+ return false;
}
- // No metadata available
- return false;
- }
+ $this->_numOfFields = count($fieldMetaData);
+ foreach ($fieldMetaData as $key=>$value) {
+ $fld = new ADOFieldObject;
+ // Caution - keys are case-sensitive, must respect casing of values
+ $fld->name = $value['Name'];
+ $fld->max_length = $value['Size'];
+ $fld->column_source = $value['Name'];
+ $fld->type = $this->_typeConversion[$value['Type']];
+ $this->fieldObjectsCache[$key] = $fld;
+ $this->fieldObjectsIndex[$fld->name] = $key;
+ }
+ if ($fieldOffset == -1) {
+ return $this->fieldObjectsCache;
+ }
+
+ return $this->fieldObjectsCache[$fieldOffset];
+ }
/*
* Fetchfield copies the oracle method, it loads the field information
@@ -1232,7 +1237,7 @@ class ADORecordset_mssqlnative extends ADORecordSet {
*/
function fetchField($fieldOffset = -1)
{
- return $this->fieldObjects[$fieldOffset];
+ return $this->fieldObjectsCache[$fieldOffset];
}
function _seek($row)
diff --git a/drivers/adodb-mysqli.inc.php b/drivers/adodb-mysqli.inc.php
index 46d53618..f67b663e 100644
--- a/drivers/adodb-mysqli.inc.php
+++ b/drivers/adodb-mysqli.inc.php
@@ -85,6 +85,11 @@ class ADODB_mysqli extends ADOConnection {
private $statementAffectedRows = -1;
/**
+ * @var bool True if the last executed statement is a SELECT {@see _query()}
+ */
+ private $isSelectStatement = false;
+
+ /**
* Sets the isolation level of a transaction.
*
* @link https://adodb.org/dokuwiki/doku.php?id=v5:reference:connection:settransactionmode
@@ -438,9 +443,12 @@ class ADODB_mysqli extends ADOConnection {
*/
function _affectedrows()
{
- if ($this->usingBoundVariables)
- return $this->statementAffectedRows;
-
+ 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());
@@ -1280,7 +1288,7 @@ class ADODB_mysqli extends ADOConnection {
return $mysql_res;
*/
-
+
if ($this->multiQuery) {
$rs = mysqli_multi_query($this->_connectionID, $sql.';');
if ($rs) {
@@ -1289,8 +1297,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)
diff --git a/drivers/adodb-odbc_mssql2012.inc.php b/drivers/adodb-odbc_mssql2012.inc.php
index 9ecaecfa..79fa3251 100644
--- a/drivers/adodb-odbc_mssql2012.inc.php
+++ b/drivers/adodb-odbc_mssql2012.inc.php
@@ -18,16 +18,6 @@
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
-/*
- @version v5.21.1-dev Unreleased
- @copyright (c) 2015 Damien Regad, Mark Newnham and the ADOdb community
- Released under both BSD license and Lesser GPL library license.
- Whenever there is any discrepancy between the two licenses,
- the BSD license will take precedence.
- Set tabs to 4.
-
- Microsoft SQL Server 2012 via ODBC
-*/
if (!defined('ADODB_DIR'))
die();
diff --git a/drivers/adodb-postgres64.inc.php b/drivers/adodb-postgres64.inc.php
index e2fb5c97..23ca0f2c 100644
--- a/drivers/adodb-postgres64.inc.php
+++ b/drivers/adodb-postgres64.inc.php
@@ -951,10 +951,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);
@@ -969,10 +968,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();
@@ -984,7 +984,7 @@ class ADORecordSet_postgres64 extends ADORecordSet{
return $this->fields[$this->bind[strtoupper($colname)]];
}
- function FetchField($off = 0)
+ function fetchField($fieldOffset)
{
// offsets begin at 0
diff --git a/drivers/adodb-sqlite.inc.php b/drivers/adodb-sqlite.inc.php
index 875acef7..0711f1dd 100644
--- a/drivers/adodb-sqlite.inc.php
+++ b/drivers/adodb-sqlite.inc.php
@@ -1,6 +1,10 @@
<?php
/**
- * FileDescription
+ * SQLite driver
+ *
+ * @link https://www.sqlite.org/
+ *
+ * @deprecated Use SQLite3 driver instead
*
* This file is part of ADOdb, a Database Abstraction Layer library for PHP.
*
@@ -18,23 +22,6 @@
* @copyright 2000-2013 John Lim
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
-/*
-@version v5.21.1-dev Unreleased
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
- Released under both BSD license and Lesser GPL library license.
- Whenever there is any discrepancy between the two licenses,
- the BSD license will take precedence.
-
- Latest version is available at https://adodb.org/
-
- SQLite info: http://www.hwaci.com/sw/sqlite/
-
- Install Instructions:
- ====================
- 1. Place this in adodb/drivers
- 2. Rename the file, remove the .txt prefix.
-*/
// security - hide paths
if (!defined('ADODB_DIR')) die();
diff --git a/tests/LibTest.php b/tests/LibTest.php
new file mode 100644
index 00000000..2f02e00e
--- /dev/null
+++ b/tests/LibTest.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Tests cases for adodb-lib.inc.php
+ *
+ * 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
+ */
+
+use PHPUnit\Framework\TestCase;
+
+require_once dirname(__FILE__) . '/../adodb.inc.php';
+require_once dirname(__FILE__) . '/../adodb-lib.inc.php';
+
+/**
+ * Class LibTest.
+ *
+ * Test cases for adodb-lib.inc.php
+ */
+class LibTest extends TestCase
+{
+ /** @var ADOConnection Database connection for tests */
+ private $db;
+
+ public function setUp(): void
+ {
+ $this->db = ADONewConnection('mysqli');
+ }
+
+ /**
+ * Test for {@see _adodb_quote_fieldname()}
+ *
+ * @dataProvider quoteProvider
+ */
+ public function testQuoteFieldNames($method, $field, $expected)
+ {
+ global $ADODB_QUOTE_FIELDNAMES;
+ $ADODB_QUOTE_FIELDNAMES = $method;
+ $this->assertSame($expected, _adodb_quote_fieldname($this->db, $field));
+ }
+
+ /**
+ * Data provider for {@see testQuoteFieldNames()}
+ * @return array
+ */
+ public function quoteProvider()
+ {
+ return [
+ 'No quoting, single-word field name' => [false, 'Field', 'FIELD'],
+ 'No quoting, field name with space' => [false, 'Field Name', '`FIELD NAME`'],
+ 'Quoting `true`' => [true, 'Field', '`FIELD`'],
+ 'Quoting `UPPER`' => ['UPPER', 'Field', '`FIELD`'],
+ 'Quoting `LOWER`' => ['LOWER', 'Field', '`field`'],
+ 'Quoting `NATIVE`' => ['NATIVE', 'Field', '`Field`'],
+ 'Quoting `BRACKETS`' => ['BRACKETS', 'Field', '[FIELD]'],
+ 'Unknown value defaults to UPPER' => ['XXX', 'Field', '`FIELD`'],
+ ];
+ }
+
+}
diff --git a/tests/testsessions.php b/tests/testsessions.php
index 634da61c..2eca41bb 100644
--- a/tests/testsessions.php
+++ b/tests/testsessions.php
@@ -19,18 +19,6 @@
* @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community
*/
-/*
-@version v5.21.1-dev Unreleased
-@copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
-@copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
- Released under both BSD license and Lesser GPL library license.
- Whenever there is any discrepancy between the two licenses,
- the BSD license will take precedence.
- Set tabs to 4 for best viewing.
-
- Latest version is available at https://adodb.org/
-*/
-
function NotifyExpire($ref,$key)
{
print "<p><b>Notify Expiring=$ref, sessionkey=$key</b></p>";