Commit 88a12838 authored by Aaron Wells's avatar Aaron Wells
Browse files

lib/adodb: Updating ADOdb to version 5.18

Bug #1180625

ADOdb 5.18, downloaded form http://sourceforge.net/projects/adodb/files/adodb-php5-only/adodb-518-for-php5/
I've cherry-picked the following Mahara commits onto it:

1. adodb: fix MySQL bug on installing Mahara
This was reported in the forums by Bruce Ellis:
  http://mahara.org/interaction/forum/topic.php?id=131
and corresponds to Eduforge #3159 and LP #547934.
(cherry picked from commit e7029e5f)

2. adodb: RecordSet_postgres7->MoveNext() - remove expensive is_array()
 implicit count() of the array keys/columns. This shaves a good 5%
of the exec time of get_records('config')
(cherry picked from commit 04ef8a3b)

3. adodb: check for Postgres 8.1
See Eduforge #2318 or LP #547951.
(cherry picked from commit c6dfccad)

4. Check for valid columns in adodb postgres64 driver MetaIndexes fn (bug #796102)
Indexes on functions of columns have a 0 in the indkey column of
pg_catalog.pg_index, which doesn't refer to a column.
Don't return any columns for the index, rather than returning an empty
column name.
(cherry picked from commit b87d9961)

5. Bug #841711: ADODB modification: add __wakeup to connection object
This reconnects to the db after wakeup, as resource types cannot be
serialized and unserialized.
This is necessary for unit tests, phpunit backups and restore globals
between each test.
(cherry picked from commit 41707745

)

Change-Id: I888bfc0cfb6acfc58adf1b416580c4b5ddd70732
Signed-off-by: Aaron Wells's avatarAaron Wells <aaronw@catalyst.net.nz>
parent 8e9f8ef3
......@@ -2,13 +2,12 @@ adodb
-----
Source: http://adodb.sourceforge.net/
Version: 5.11
Version: 5.18
Modifications:
- drivers/adodb-mysql.inc.php (24465d23e2ccb3a89629e250a3caab1ee051e90d)
- drivers/adodb-postgres7.inc.php (af59ab96086a319785ed682420d22dbfcbacb9bc)
- adodb/drivers/adodb-postgres64.inc.php (d6d8884fabc598aec58e633a6a1e258cd07b3da1)
- Add check for valid columns in MetaIndexes function of
adodb/drivers/adodb-postgres64.inc.php (see bug #796102)
- adodb/adodb.inc.php add wakeup suppport (see bug #841711)
- fix MySQL bug on installing Mahara (e7029e5fc1fd3329a3a817f26b2ad5c3f61239cf)
- RecordSet_postgres7->MoveNext() - remove expensive is_array() (04ef8a3b9770f93326a2ece31e4089368117faca)
- check for Postgres 8.1 (c6dfccadfae432147fff99fa15b0985dcae7e503)
- Check for valid columns in adodb postgres64 driver MetaIndexes fn (b87d9961020a8d52a2eaf709a9197520b3c6b65b)
- add __wakeup to connection object (417077459037550239fe9b09bd20b50d4c19b57f)
<?php
/*
@version V5.11 5 May 2010 (c) 2000-2010 John Lim (jlim#natsoft.com). All rights reserved.
@version V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
Latest version is available at http://adodb.sourceforge.net
Released under both BSD license and Lesser GPL library license.
......@@ -44,7 +44,7 @@ class ADODB_Active_Table {
// $db = database connection
// $index = name of index - can be associative, for an example see
// http://phplens.com/lens/lensforum/msgs.php?id=17790
// http://phplens.com/lens/lensforum/msgs.php?id=17790
// returns index into $_ADODB_ACTIVE_DBS
function ADODB_SetDatabaseAdapter(&$db, $index=false)
{
......@@ -54,7 +54,7 @@ function ADODB_SetDatabaseAdapter(&$db, $index=false)
if (PHP_VERSION >= 5) {
if ($d->db === $db) return $k;
} else {
if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database)
if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database)
return $k;
}
}
......@@ -65,7 +65,7 @@ function ADODB_SetDatabaseAdapter(&$db, $index=false)
if ($index == false) $index = sizeof($_ADODB_ACTIVE_DBS);
$_ADODB_ACTIVE_DBS[$index] = $obj;
return sizeof($_ADODB_ACTIVE_DBS)-1;
......@@ -75,8 +75,8 @@ function ADODB_SetDatabaseAdapter(&$db, $index=false)
class ADODB_Active_Record {
static $_changeNames = true; // dynamically pluralize table names
static $_quoteNames = false;
static $_foreignSuffix = '_id'; //
static $_foreignSuffix = '_id'; //
var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat]
var $_table; // tablename, if set in class definition then use it as table name
var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat]
......@@ -87,6 +87,8 @@ class ADODB_Active_Record {
var $foreignName; // CFR: class name when in a relationship
var $lockMode = ' for update '; // you might want to change to
static function UseDefaultValues($bool=null)
{
global $ADODB_ACTIVE_DEFVALS;
......@@ -95,12 +97,12 @@ class ADODB_Active_Record {
}
// should be static
static function SetDatabaseAdapter(&$db, $index=false)
static function SetDatabaseAdapter(&$db, $index=false)
{
return ADODB_SetDatabaseAdapter($db, $index);
}
public function __set($name, $value)
{
$name = str_replace(' ', '_', $name);
......@@ -169,9 +171,9 @@ class ADODB_Active_Record {
// Note: There is an assumption here...and it is that the argument's length >= 4
function _singularize($tables)
{
if (!ADODB_Active_Record::$_changeNames) return $table;
$ut = strtoupper($tables);
$len = strlen($tables);
if($ut[$len-1] != 'S')
......@@ -203,14 +205,14 @@ class ADODB_Active_Record {
$table->_hasMany[$foreignRef] = $ar;
# $this->$foreignRef = $this->_hasMany[$foreignRef]; // WATCHME Removed assignment by ref. to please __get()
}
// use when you don't want ADOdb to auto-pluralize tablename
static function TableHasMany($table, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
{
$ar = new ADODB_Active_Record($table);
$ar->hasMany($foreignRef, $foreignKey, $foreignClass);
}
// use when you don't want ADOdb to auto-pluralize tablename
static function TableKeyHasMany($table, $tablePKey, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
{
......@@ -218,8 +220,8 @@ class ADODB_Active_Record {
$ar = new ADODB_Active_Record($table,$tablePKey);
$ar->hasMany($foreignRef, $foreignKey, $foreignClass);
}
// use when you want ADOdb to auto-pluralize tablename for you. Note that the class must already be defined.
// e.g. class Person will generate relationship for table Persons
static function ClassHasMany($parentclass, $foreignRef, $foreignKey = false, $foreignClass = 'ADODB_Active_Record')
......@@ -227,7 +229,7 @@ class ADODB_Active_Record {
$ar = new $parentclass();
$ar->hasMany($foreignRef, $foreignKey, $foreignClass);
}
function belongsTo($foreignRef,$foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
......@@ -238,24 +240,24 @@ class ADODB_Active_Record {
$ar->parentKey = $parentKey;
$ar->UpdateActiveTable();
$ar->foreignKey = ($foreignKey) ? $foreignKey : $foreignRef.ADODB_Active_Record::$_foreignSuffix;
$table =& $this->TableInfo();
$table->_belongsTo[$foreignRef] = $ar;
# $this->$foreignRef = $this->_belongsTo[$foreignRef];
}
static function ClassBelongsTo($class, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
$ar = new $class();
$ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
}
static function TableBelongsTo($table, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
$ar = new ADOdb_Active_Record($table);
$ar->belongsTo($foreignRef, $foreignKey, $parentKey, $parentClass);
}
static function TableKeyBelongsTo($table, $tablePKey, $foreignRef, $foreignKey=false, $parentKey='', $parentClass = 'ADODB_Active_Record')
{
if (!is_array($tablePKey)) $tablePKey = array($tablePKey);
......@@ -266,8 +268,8 @@ class ADODB_Active_Record {
/**
* __get Access properties - used for lazy loading
*
* @param mixed $name
*
* @param mixed $name
* @access protected
* @return mixed
*/
......@@ -275,9 +277,9 @@ class ADODB_Active_Record {
{
return $this->LoadRelations($name, '', -1, -1);
}
/**
* @param string $name
* @param string $name
* @param string $whereOrderBy : eg. ' AND field1 = value ORDER BY field2'
* @param offset
* @param limit
......@@ -289,12 +291,12 @@ class ADODB_Active_Record {
$table = $this->TableInfo();
if ($limit >= 0) $extras['limit'] = $limit;
if ($offset >= 0) $extras['offset'] = $offset;
if (strlen($whereOrderBy))
if (strlen($whereOrderBy))
if (!preg_match('/^[ \n\r]*AND/i',$whereOrderBy))
if (!preg_match('/^[ \n\r]*ORDER[ \n\r]/i',$whereOrderBy))
$whereOrderBy = 'AND '.$whereOrderBy;
if(!empty($table->_belongsTo[$name]))
{
$obj = $table->_belongsTo[$name];
......@@ -305,7 +307,7 @@ class ADODB_Active_Record {
{
if ($obj->parentKey) $key = $obj->parentKey;
else $key = reset($table->keys);
$arrayOfOne = $obj->Find($key.'='.$this->$columnName.' '.$whereOrderBy,false,false,$extras);
if ($arrayOfOne) {
$this->$name = $arrayOfOne[0];
......@@ -314,7 +316,7 @@ class ADODB_Active_Record {
}
}
if(!empty($table->_hasMany[$name]))
{
{
$obj = $table->_hasMany[$name];
$key = reset($table->keys);
$id = @$this->$key;
......@@ -327,7 +329,7 @@ class ADODB_Active_Record {
$this->$name = $objs;
return $objs;
}
return array();
}
//////////////////////////////////
......@@ -347,7 +349,7 @@ class ADODB_Active_Record {
$acttab = $tables[$tableat];
foreach($acttab->flds as $name => $fld) {
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value))
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value))
$this->$name = $fld->default_value;
else
$this->$name = null;
......@@ -364,14 +366,14 @@ class ADODB_Active_Record {
if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) {
// abs(rand()) randomizes deletion, reducing contention to delete/refresh file
// ideally, you should cache at least 32 secs
foreach($acttab->flds as $name => $fld) {
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value))
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value))
$this->$name = $fld->default_value;
else
$this->$name = null;
}
$activedb->tables[$table] = $acttab;
//if ($db->debug) ADOConnection::outp("Reading cached active record file: $fname");
......@@ -388,10 +390,10 @@ class ADODB_Active_Record {
if ($db->fetchMode !== false) $savem = $db->SetFetchMode(false);
$cols = $db->MetaColumns($table);
if (isset($savem)) $db->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if (!$cols) {
$this->Error("Invalid table name: $table",'UpdateActiveTable');
return false;
......@@ -432,7 +434,7 @@ class ADODB_Active_Record {
case 1:
foreach($cols as $name => $fldobj) {
$name = strtoupper($name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value))
$this->$name = $fldobj->default_value;
else
......@@ -447,7 +449,7 @@ class ADODB_Active_Record {
default:
foreach($cols as $name => $fldobj) {
$name = ($fldobj->name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value))
$this->$name = $fldobj->default_value;
else
......@@ -471,7 +473,7 @@ class ADODB_Active_Record {
}
if (isset($activedb->tables[$table])) {
$oldtab = $activedb->tables[$table];
if ($oldtab) $activetab->_belongsTo = $oldtab->_belongsTo;
if ($oldtab) $activetab->_hasMany = $oldtab->_hasMany;
}
......@@ -518,11 +520,11 @@ class ADODB_Active_Record {
return $this->_lasterr;
}
function ErrorNo()
function ErrorNo()
{
if ($this->_dbat < 0) return -9999; // no database connection...
$db = $this->DB();
return (int) $db->ErrorNo();
}
......@@ -551,7 +553,7 @@ class ADODB_Active_Record {
return $table;
}
// I have an ON INSERT trigger on a table that sets other columns in the table.
// So, I find that for myTable, I want to reload an active record after saving it. -- Malcolm Cook
function Reload()
......@@ -562,12 +564,12 @@ class ADODB_Active_Record {
return($this->Load($where));
}
// set a numeric array (using natural table field ordering) as object properties
function Set(&$row)
{
global $ACTIVE_RECORD_SAFETY;
$db = $this->DB();
if (!$row) {
......@@ -595,7 +597,7 @@ class ADODB_Active_Record {
}
else
$keys = array_keys($row);
# <AP>
reset($keys);
$this->_original = array();
......@@ -631,18 +633,18 @@ class ADODB_Active_Record {
switch($t) {
case 'L':
if (strpos($db->databaseType,'postgres') !== false) return $db->qstr($val);
case 'D':
case 'D':
case 'T':
if (empty($val)) return 'null';
case 'B':
case 'B':
case 'N':
case 'C':
case 'X':
if (is_null($val)) return 'null';
if (strlen($val)>1 &&
(strncmp($val,"'",1) != 0 || substr($val,strlen($val)-1,1) != "'")) {
if (strlen($val)>0 &&
(strncmp($val,"'",1) != 0 || substr($val,strlen($val)-1,1) != "'")) {
return $db->qstr($val);
break;
}
......@@ -674,51 +676,58 @@ class ADODB_Active_Record {
if (!$db) $db = $this->DB(); if (!$db) return false;
return $db->nameQuote.$n.$db->nameQuote;
}
//------------------------------------------------------------ Public functions below
function Load($where=null,$bindarr=false)
function Load($where=null,$bindarr=false, $lock = false)
{
global $ADODB_FETCH_MODE;
$db = $this->DB(); if (!$db) return false;
$this->_where = $where;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($db->fetchMode !== false) $savem = $db->SetFetchMode(false);
$qry = "select * from ".$this->_table;
if($where) {
$qry .= ' WHERE '.$where;
}
if ($lock) $qry .= $this->lockMode;
$row = $db->GetRow($qry,$bindarr);
if (isset($savem)) $db->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
return $this->Set($row);
}
function LoadLocked($where=null, $bindarr=false)
{
$this->Load($where,$bindarr,true);
}
# useful for multiple record inserts
# see http://phplens.com/lens/lensforum/msgs.php?id=17795
function Reset()
{
$this->_where=null;
$this->_saved = false;
$this->_lasterr = false;
$this->_saved = false;
$this->_lasterr = false;
$this->_original = false;
$vars=get_object_vars($this);
foreach($vars as $k=>$v){
if(substr($k,0,1)!=='_'){
$this->{$k}=null;
}
if(substr($k,0,1)!=='_'){
$this->{$k}=null;
}
}
$this->foreignName=strtolower(get_class($this));
return true;
}
// false on error
function Save()
{
......@@ -728,7 +737,7 @@ class ADODB_Active_Record {
return $ok;
}
// false on error
function Insert()
{
......@@ -825,9 +834,9 @@ class ADODB_Active_Record {
if (is_null($val) && !empty($fld->auto_increment)) {
continue;
}
if (is_array($val)) continue;
$t = $db->MetaType($fld->type);
$arr[$name] = $this->doquote($db,$val,$t);
$valarr[] = $val;
......@@ -839,7 +848,7 @@ class ADODB_Active_Record {
if ($ADODB_ASSOC_CASE == 0)
foreach($pkey as $k => $v)
$pkey[$k] = strtolower($v);
elseif ($ADODB_ASSOC_CASE == 1)
elseif ($ADODB_ASSOC_CASE == 1)
foreach($pkey as $k => $v)
$pkey[$k] = strtoupper($v);
......@@ -887,7 +896,7 @@ class ADODB_Active_Record {
$val = $this->$name;
$neworig[] = $val;
if (isset($table->keys[$name]) || is_array($val))
if (isset($table->keys[$name]) || is_array($val))
continue;
if (is_null($val)) {
......@@ -900,9 +909,10 @@ class ADODB_Active_Record {
}
}
if (isset($this->_original[$i]) && strcmp($val,$this->_original[$i]) == 0) {
continue;
}
if (isset($this->_original[$i]) && strcmp($val,$this->_original[$i]) == 0) continue;
if (is_null($this->_original[$i]) && is_null($val)) continue;
$valarr[] = $val;
$pairs[] = $this->_QName($name,$db).'='.$db->Param($cnt);
$cnt += 1;
......@@ -933,10 +943,10 @@ function adodb_GetActiveRecordsClass(&$db, $class, $table,$whereOrderBy,$bindarr
{
global $_ADODB_ACTIVE_DBS;
$save = $db->SetFetchMode(ADODB_FETCH_NUM);
$qry = "select * from ".$table;
if (!empty($whereOrderBy))
$qry .= ' WHERE '.$whereOrderBy;
if(isset($extra['limit']))
......@@ -957,13 +967,13 @@ global $_ADODB_ACTIVE_DBS;
$rows = $db->GetAll($qry,$bindarr);
$db->SetFetchMode($save);
$false = false;
if ($rows === false) {
if ($rows === false) {
return $false;
}
if (!class_exists($class)) {
$db->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
......@@ -977,7 +987,7 @@ global $_ADODB_ACTIVE_DBS;
$arrRef = array();
$bTos = array(); // Will store belongTo's indices if any
foreach($rows as $row) {
$obj = new $class($table,$primkeyArr,$db);
if ($obj->ErrorNo()){
$db->_errorMsg = $obj->ErrorMsg();
......@@ -985,7 +995,7 @@ global $_ADODB_ACTIVE_DBS;
}
$obj->Set($row);
$arr[] = $obj;
} // foreach($rows as $row)
} // foreach($rows as $row)
return $arr;
}
......
......@@ -8,7 +8,7 @@ $ADODB_INCLUDED_CSV = 1;
/*
V5.11 5 May 2010 (c) 2000-2010 John Lim (jlim#natsoft.com). All rights reserved.
V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
......@@ -286,7 +286,7 @@ $ADODB_INCLUDED_CSV = 1;
if (fwrite($fd,$contents)) $ok = true;
else $ok = false;
fclose($fd);
if ($ok) {
@chmod($tmpname,0644);
// the tricky moment
......
<?php
/**
V5.11 5 May 2010 (c) 2000-2010 John Lim (jlim#natsoft.com). All rights reserved.
V5.18 3 Sep 2012 (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
......@@ -216,7 +216,7 @@ class ADODB_DataDict {
}
function MetaType($t,$len=-1,$fieldobj=false)
{
{
static $typeMap = array(
'VARCHAR' => 'C',
'VARCHAR2' => 'C',
......@@ -263,7 +263,7 @@ class ADODB_DataDict {
'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
##
'BOOL' => 'L',
'BOOLEAN' => 'L',
'BOOLEAN' => 'L',
'BIT' => 'L',
'L' => 'L',
##
......@@ -296,21 +296,21 @@ class ADODB_DataDict {
'NUM' => 'N',
'NUMERIC' => 'N',
'MONEY' => 'N',
## informix 9.2
'SQLINT' => 'I',
'SQLSERIAL' => 'I',
'SQLSMINT' => 'I',
'SQLSMFLOAT' => 'N',
'SQLFLOAT' => 'N',
'SQLMONEY' => 'N',
'SQLDECIMAL' => 'N',
'SQLDATE' => 'D',
'SQLVCHAR' => 'C',
'SQLCHAR' => 'C',
'SQLDTIME' => 'T',
'SQLINTERVAL' => 'N',
'SQLBYTES' => 'B',
'SQLINT' => 'I',
'SQLSERIAL' => 'I',
'SQLSMINT' => 'I',
'SQLSMFLOAT' => 'N',
'SQLFLOAT' => 'N',
'SQLMONEY' => 'N',
'SQLDECIMAL' => 'N',
'SQLDATE' => 'D',
'SQLVCHAR' => 'C',
'SQLCHAR' => 'C',
'SQLDTIME' => 'T',
'SQLINTERVAL' => 'N',
'SQLBYTES' => 'B',
'SQLTEXT' => 'X',
## informix 10
"SQLINT8" => 'I8',
......@@ -320,7 +320,7 @@ class ADODB_DataDict {
"SQLLVARCHAR" => 'X',
"SQLBOOL" => 'L'
);