From 25be6cfff383bc97883500e875572741641fcea4 Mon Sep 17 00:00:00 2001
From: moodler
Date: Fri, 30 Jan 2004 03:11:47 +0000
Subject: [PATCH] Upgrading ADOdb to 4.11 ... there were lots of little bug
fixes
---
lib/adodb/adodb-csvlib.inc.php | 4 +-
lib/adodb/adodb-datadict.inc.php | 153 +++-
lib/adodb/adodb-error.inc.php | 11 +-
lib/adodb/adodb-errorhandler.inc.php | 13 +-
lib/adodb/adodb-errorpear.inc.php | 2 +-
lib/adodb/adodb-exceptions.inc.php | 77 ++
lib/adodb/adodb-iterator.inc.php | 56 ++
lib/adodb/adodb-lib.inc.php | 205 +++--
lib/adodb/adodb-pager.inc.php | 2 +-
lib/adodb/adodb-pear.inc.php | 4 +-
lib/adodb/adodb-perf.inc.php | 204 ++++-
lib/adodb/adodb-php4.inc.php | 16 +
lib/adodb/adodb-time.inc.php | 29 +-
lib/adodb/adodb.inc.php | 578 ++++++------
lib/adodb/datadict/datadict-access.inc.php | 2 +-
lib/adodb/datadict/datadict-db2.inc.php | 2 +-
lib/adodb/datadict/datadict-generic.inc.php | 2 +-
lib/adodb/datadict/datadict-ibase.inc.php | 2 +-
lib/adodb/datadict/datadict-informix.inc.php | 2 +-
lib/adodb/datadict/datadict-mssql.inc.php | 48 +-
lib/adodb/datadict/datadict-mysql.inc.php | 45 +-
lib/adodb/datadict/datadict-oci8.inc.php | 37 +-
lib/adodb/datadict/datadict-postgres.inc.php | 34 +-
lib/adodb/datadict/datadict-sybase.inc.php | 39 +-
lib/adodb/docs-adodb.htm | 417 +++++++--
lib/adodb/docs-datadict.htm | 52 +-
lib/adodb/docs-perf.htm | 2 +-
lib/adodb/docs-session.htm | 250 +++---
lib/adodb/drivers/adodb-access.inc.php | 2 +-
lib/adodb/drivers/adodb-ado.inc.php | 40 +-
lib/adodb/drivers/adodb-ado_access.inc.php | 2 +-
lib/adodb/drivers/adodb-ado_mssql.inc.php | 5 +-
lib/adodb/drivers/adodb-borland_ibase.inc.php | 2 +-
lib/adodb/drivers/adodb-csv.inc.php | 4 +-
lib/adodb/drivers/adodb-db2.inc.php | 9 +-
lib/adodb/drivers/adodb-fbsql.inc.php | 2 +-
lib/adodb/drivers/adodb-firebird.inc.php | 12 +-
lib/adodb/drivers/adodb-ibase.inc.php | 283 ++++--
lib/adodb/drivers/adodb-informix.inc.php | 2 +-
lib/adodb/drivers/adodb-informix72.inc.php | 16 +-
lib/adodb/drivers/adodb-mssql.inc.php | 17 +-
lib/adodb/drivers/adodb-mssqlpo.inc.php | 2 +-
lib/adodb/drivers/adodb-mysql.inc.php | 104 ++-
lib/adodb/drivers/adodb-mysqli.inc.php | 828 ++++++++++++++++++
lib/adodb/drivers/adodb-mysqlt.inc.php | 2 +-
lib/adodb/drivers/adodb-oci8.inc.php | 63 +-
lib/adodb/drivers/adodb-oci805.inc.php | 2 +-
lib/adodb/drivers/adodb-oci8po.inc.php | 21 +-
lib/adodb/drivers/adodb-odbc.inc.php | 22 +-
lib/adodb/drivers/adodb-odbc_mssql.inc.php | 9 +-
lib/adodb/drivers/adodb-odbc_oracle.inc.php | 2 +-
lib/adodb/drivers/adodb-oracle.inc.php | 2 +-
lib/adodb/drivers/adodb-postgres.inc.php | 2 +-
lib/adodb/drivers/adodb-postgres64.inc.php | 303 ++++---
lib/adodb/drivers/adodb-postgres7.inc.php | 18 +-
lib/adodb/drivers/adodb-proxy.inc.php | 2 +-
lib/adodb/drivers/adodb-sapdb.inc.php | 2 +-
lib/adodb/drivers/adodb-sqlanywhere.inc.php | 2 +-
lib/adodb/drivers/adodb-sqlite.inc.php | 16 +-
lib/adodb/drivers/adodb-sybase.inc.php | 15 +-
lib/adodb/drivers/adodb-vfp.inc.php | 2 +-
lib/adodb/lang/adodb-ca.inc.php | 35 +
lib/adodb/lang/adodb-cn.inc.php | 35 +
lib/adodb/lang/adodb-de.inc.php | 33 +
lib/adodb/lang/adodb-fr.inc.php | 2 +-
lib/adodb/lang/adodb-it.inc.php | 8 +-
lib/adodb/license.txt | 23 +-
lib/adodb/perf/perf-db2.inc.php | 14 +-
lib/adodb/perf/perf-informix.inc.php | 2 +-
lib/adodb/perf/perf-mssql.inc.php | 19 +-
lib/adodb/perf/perf-mysql.inc.php | 27 +-
lib/adodb/perf/perf-oci8.inc.php | 47 +-
lib/adodb/perf/perf-postgres.inc.php | 19 +-
lib/adodb/pivottable.inc.php | 5 +-
lib/adodb/rsfilter.inc.php | 2 +-
lib/adodb/server.php | 2 +-
lib/adodb/session/adodb-compress-bzip2.php | 120 +++
lib/adodb/session/adodb-compress-gzip.php | 94 ++
lib/adodb/session/adodb-cryptsession.php | 25 +
lib/adodb/session/adodb-encrypt-mcrypt.php | 110 +++
lib/adodb/session/adodb-encrypt-md5.php | 38 +
lib/adodb/session/adodb-encrypt-secret.php | 50 ++
lib/adodb/session/adodb-sess.txt | 131 +++
lib/adodb/session/adodb-session-clob.php | 24 +
lib/adodb/session/adodb-session.php | 817 +++++++++++++++++
lib/adodb/session/adodb-sessions.mysql.sql | 16 +
.../session/adodb-sessions.oracle.clob.sql | 15 +
lib/adodb/session/adodb-sessions.oracle.sql | 16 +
lib/adodb/session/crypt.inc.php | 64 ++
lib/adodb/tests/benchmark.php | 2 +-
lib/adodb/tests/client.php | 2 +-
lib/adodb/tests/test-datadict.php | 2 +-
lib/adodb/tests/test-pgblob.php | 35 +
lib/adodb/tests/test-php5.php | 56 ++
lib/adodb/tests/test-xmlschema.php | 2 +-
lib/adodb/tests/test.php | 120 ++-
lib/adodb/tests/test2.php | 2 +-
lib/adodb/tests/test3.php | 52 +-
lib/adodb/tests/test4.php | 3 +-
lib/adodb/tests/test5.php | 2 +-
lib/adodb/tests/test_rs_array.php | 47 +
lib/adodb/tests/testcache.php | 2 +-
lib/adodb/tests/testdatabases.inc.php | 18 +-
lib/adodb/tests/testgenid.php | 2 +-
lib/adodb/tests/testmssql.php | 2 +-
lib/adodb/tests/testoci8.php | 2 +-
lib/adodb/tests/testoci8cursor.php | 71 +-
lib/adodb/tests/testpaging.php | 2 +-
lib/adodb/tests/testpear.php | 2 +-
lib/adodb/tests/testsessions.php | 35 +-
lib/adodb/tests/tmssql.php | 128 +--
lib/adodb/tips_portable_sql.htm | 34 +-
lib/adodb/toexport.inc.php | 5 +-
lib/adodb/tohtml.inc.php | 6 +-
lib/adodb/tute.htm | 580 ++++++------
115 files changed, 5583 insertions(+), 1527 deletions(-)
create mode 100644 lib/adodb/adodb-exceptions.inc.php
create mode 100644 lib/adodb/adodb-iterator.inc.php
create mode 100644 lib/adodb/adodb-php4.inc.php
create mode 100644 lib/adodb/drivers/adodb-mysqli.inc.php
create mode 100644 lib/adodb/lang/adodb-ca.inc.php
create mode 100644 lib/adodb/lang/adodb-cn.inc.php
create mode 100644 lib/adodb/lang/adodb-de.inc.php
create mode 100644 lib/adodb/session/adodb-compress-bzip2.php
create mode 100644 lib/adodb/session/adodb-compress-gzip.php
create mode 100644 lib/adodb/session/adodb-cryptsession.php
create mode 100644 lib/adodb/session/adodb-encrypt-mcrypt.php
create mode 100644 lib/adodb/session/adodb-encrypt-md5.php
create mode 100644 lib/adodb/session/adodb-encrypt-secret.php
create mode 100644 lib/adodb/session/adodb-sess.txt
create mode 100644 lib/adodb/session/adodb-session-clob.php
create mode 100644 lib/adodb/session/adodb-session.php
create mode 100644 lib/adodb/session/adodb-sessions.mysql.sql
create mode 100644 lib/adodb/session/adodb-sessions.oracle.clob.sql
create mode 100644 lib/adodb/session/adodb-sessions.oracle.sql
create mode 100644 lib/adodb/session/crypt.inc.php
create mode 100644 lib/adodb/tests/test-pgblob.php
create mode 100644 lib/adodb/tests/test-php5.php
create mode 100644 lib/adodb/tests/test_rs_array.php
diff --git a/lib/adodb/adodb-csvlib.inc.php b/lib/adodb/adodb-csvlib.inc.php
index ba59b6bcaa8..37c46794ceb 100644
--- a/lib/adodb/adodb-csvlib.inc.php
+++ b/lib/adodb/adodb-csvlib.inc.php
@@ -3,7 +3,7 @@ global $ADODB_INCLUDED_CSV;
$ADODB_INCLUDED_CSV = 1;
/*
- V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
+ V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). 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.
@@ -83,8 +83,8 @@ $ADODB_INCLUDED_CSV = 1;
*/
function &csv2rs($url,&$err,$timeout=0)
{
- $fp = @fopen($url,'r');
$err = false;
+ $fp = @fopen($url,'r');
if (!$fp) {
$err = $url.' file/URL not found';
return false;
diff --git a/lib/adodb/adodb-datadict.inc.php b/lib/adodb/adodb-datadict.inc.php
index 0c73094f245..db9c2016dfa 100644
--- a/lib/adodb/adodb-datadict.inc.php
+++ b/lib/adodb/adodb-datadict.inc.php
@@ -1,7 +1,7 @@
$str
";
$a= Lens_ParseArgs($str);
print "";
print_r($a);
print "
";
}
+
+if (!function_exists('ctype_alnum')) {
+ function ctype_alnum($text) {
+ return preg_match('/^[a-z0-9]*$/i', $text);
+ }
+}
+
//Lens_ParseTest();
/**
Parse arguments, treat "text" (text) and 'text' as quotation marks.
To escape, use "" or '' or ))
+ Will read in "abc def" sans quotes, as: abc def
+ Same with 'abc def'.
+ However if `abc def`, then will read in as `abc def`
+
@param endstmtchar Character that indicates end of statement
@param tokenchars Include the following characters in tokens apart from A-Z and 0-9
@returns 2 dimensional array containing parsed tokens.
@@ -63,7 +74,9 @@ function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
$tokarr[] = $ch;
break;
-
+
+ case '`':
+ if ($intoken) $tokarr[] = $ch;
case '(':
case ')':
case '"':
@@ -98,6 +111,7 @@ function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
$quoted = true;
$intoken = true;
$tokarr = array();
+ if ($ch == '`') $tokarr[] = '`';
}
break;
@@ -143,14 +157,14 @@ function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
class ADODB_DataDict {
var $connection;
var $debug = false;
- var $dropTable = "DROP TABLE %s";
+ var $dropTable = 'DROP TABLE %s';
+ var $dropIndex = 'DROP INDEX %s';
var $addCol = ' ADD';
var $alterCol = ' ALTER COLUMN';
var $dropCol = ' DROP COLUMN';
var $schema = false;
var $serverInfo = array();
var $autoIncrement = false;
- var $quote = '';
var $dataProvider;
var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob
/// in other words, we use a text area for editting.
@@ -170,9 +184,9 @@ class ADODB_DataDict {
return $this->connection->MetaTables();
}
- function &MetaColumns($tab)
+ function &MetaColumns($tab,$schema=false,$upper=true)
{
- return $this->connection->MetaColumns($tab);
+ return $this->connection->MetaColumns($tab,$schema,$upper);
}
function &MetaPrimaryKeys($tab,$owner=false,$intkey=false)
@@ -180,11 +194,34 @@ class ADODB_DataDict {
return $this->connection->MetaPrimaryKeys($tab.$owner,$intkey);
}
+ function &MetaIndexes($table, $primary = false, $owner = false)
+ {
+ return $this->connection->MetaIndexes($table, $primary, $owner);
+ }
+
function MetaType($t,$len=-1,$fieldobj=false)
{
return ADORecordSet::MetaType($t,$len,$fieldobj);
}
+ function NameQuote($name)
+ {
+ if ( !is_object($this->connection) ) {
+ return $name;
+ }
+
+ $replace = $this->connection->nameQuote .'$1'. $this->connection->nameQuote;
+ return preg_replace('/^`([^`]+)`$/', $replace, $name);
+ }
+
+ function TableName($name)
+ {
+ if ( $this->schema ) {
+ return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name);
+ }
+ return $this->NameQuote($name);
+ }
+
// Executes the sql array returned by GetTableSQL and GetIndexSQL
function ExecuteSQLArray($sql, $continueOnError = true)
{
@@ -231,9 +268,12 @@ class ADODB_DataDict {
function CreateDatabase($dbname,$options=false)
{
$options = $this->_Options($options);
- if (!preg_match('/^[a-z0-9A-Z_]*$/',$dbname)) $dbname = $this->quote.$dbname.$this->quote;
- $s = 'CREATE DATABASE '.$dbname;
- if (isset($options[$this->upperName])) $s .= ' '.$options[$this->upperName];
+ $sql = array();
+
+ $s = 'CREATE DATABASE ' . $this->NameQuote($dbname);
+ if (isset($options[$this->upperName]))
+ $s .= ' '.$options[$this->upperName];
+
$sql[] = $s;
return $sql;
}
@@ -243,8 +283,12 @@ class ADODB_DataDict {
*/
function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
- return $this->_IndexSQL($idxname, $tabname, $flds, $this->_Options($idxoptions));
+ return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions));
+ }
+
+ function DropIndexSQL ($idxname, $tabname = NULL)
+ {
+ return array(sprintf($this->dropIndex, $this->NameQuote($idxname)));
}
function SetSchema($schema)
@@ -253,44 +297,44 @@ class ADODB_DataDict {
}
function AddColumnSQL($tabname, $flds)
- {
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
+ {
+ $tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
+ $alter = 'ALTER TABLE ' . $tabname . ' ' . $this->addCol . ' ';
foreach($lines as $v) {
- $sql[] = "ALTER TABLE $tabname $this->addCol $v";
+ $sql[] = $alter . $v;
}
return $sql;
}
function AlterColumnSQL($tabname, $flds)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
+ $tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
-
+ $alter = 'ALTER TABLE ' . $tabname . ' ' . $this->alterCol . ' ';
foreach($lines as $v) {
- $sql[] = "ALTER TABLE $tabname $this->alterCol $v";
+ $sql[] = $alter . $v;
}
return $sql;
}
function DropColumnSQL($tabname, $flds)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
+ $tabname = $this->TableName ($tabname);
if (!is_array($flds)) $flds = explode(',',$flds);
$sql = array();
+ $alter = 'ALTER TABLE ' . $tabname . ' ' . $this->dropCol . ' ';
foreach($flds as $v) {
- $sql[] = "ALTER TABLE $tabname $this->dropCol $v";
+ $sql[] = $alter . $v;
}
return $sql;
}
function DropTableSQL($tabname)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
- $sql[] = sprintf($this->dropTable,$tabname);
- return $sql;
+ return array (sprintf($this->dropTable, $this->TableName($tabname)));
}
/*
@@ -299,11 +343,11 @@ class ADODB_DataDict {
function CreateTableSQL($tabname, $flds, $tableoptions=false)
{
if (!$tableoptions) $tableoptions = array();
-
+
list($lines,$pkey) = $this->_GenFields($flds);
$taboptions = $this->_Options($tableoptions);
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
+ $tabname = $this->TableName ($tabname);
$sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
$tsql = $this->_Triggers($tabname,$taboptions);
@@ -370,7 +414,9 @@ class ADODB_DataDict {
case 'NAME': $fname = $v; break;
case '1':
case 'TYPE': $ty = $v; $ftype = $this->ActualType(strtoupper($v)); break;
- case 'SIZE': $dotat = strpos($v,'.');
+
+ case 'SIZE':
+ $dotat = strpos($v,'.'); if ($dotat === false) $dotat = strpos($v,',');
if ($dotat === false) $fsize = $v;
else {
$fsize = substr($v,0,$dotat);
@@ -399,6 +445,8 @@ class ADODB_DataDict {
return false;
}
+ $fname = $this->NameQuote($fname);
+
if (!strlen($ftype)) {
if ($this->debug) ADOConnection::outp("Undefined TYPE for field '$fname'");
return false;
@@ -456,7 +504,7 @@ class ADODB_DataDict {
{
if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) {
$ftype .= "(".$fsize;
- if ($fprec) $ftype .= ",".$fprec;
+ if (strlen($fprec)) $ftype .= ",".$fprec;
$ftype .= ')';
}
return $ftype;
@@ -475,14 +523,28 @@ class ADODB_DataDict {
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
- if (isset($idxoptions['REPLACE'])) $sql[] = "DROP INDEX $idxname";
- if (isset($idxoptions['UNIQUE'])) $unique = ' UNIQUE';
- else $unique = '';
+ $sql = array();
- if (is_array($flds)) $flds = implode(', ',$flds);
- $s = "CREATE$unique INDEX $idxname ON $tabname ";
- if (isset($idxoptions[$this->upperName])) $s .= $idxoptions[$this->upperName];
- $s .= "($flds)";
+ if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
+ $sql[] = sprintf ($this->dropIndex, $idxname);
+ if ( isset($idxoptions['DROP']) )
+ return $sql;
+ }
+
+ if ( empty ($flds) ) {
+ return $sql;
+ }
+
+ $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
+
+ $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
+
+ if ( isset($idxoptions[$this->upperName]) )
+ $s .= $idxoptions[$this->upperName];
+
+ if ( is_array($flds) )
+ $flds = implode(', ',$flds);
+ $s .= '(' . $flds . ')';
$sql[] = $s;
return $sql;
@@ -497,12 +559,15 @@ class ADODB_DataDict {
{
$sql = array();
- if (isset($tableoptions['REPLACE'])) {
+ if (isset($tableoptions['REPLACE']) || isset ($tableoptions['DROP'])) {
$sql[] = sprintf($this->dropTable,$tabname);
if ($this->autoIncrement) {
- $sInc = $this->_DropAutoIncrement($tabname);
+ $sInc = $this->_DropAutoIncrement($tabname);
if ($sInc) $sql[] = $sInc;
}
+ if ( isset ($tableoptions['DROP']) ) {
+ return $sql;
+ }
}
$s = "CREATE TABLE $tabname (\n";
$s .= implode(",\n", $lines);
@@ -557,15 +622,21 @@ own.
*/
function ChangeTableSQL($tablename, $flds,$tableoptions=false)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tablename;
- else $tabname = $tablename;
+ $tabname = $this->TableName ($tablename);
$conn = &$this->connection;
- if (!$conn) return false;
+ if (!is_object ($conn)) {
+ return false;
+ }
$colarr = &$conn->MetaColumns($tabname);
- if (!$colarr) return $this->CreateTableSQL($tablename,$flds,$tableoptions);
- foreach($colarr as $col) $cols[strtoupper($col->name)] = " ALTER ";
+ if (!$colarr) {
+ return $this->CreateTableSQL($tablename,$flds,$tableoptions);
+ }
+
+ foreach($colarr as $col) {
+ $cols[strtoupper($col->name)] = " ALTER ";
+ }
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
diff --git a/lib/adodb/adodb-error.inc.php b/lib/adodb/adodb-error.inc.php
index 7ecd7bba755..f874caf922c 100644
--- a/lib/adodb/adodb-error.inc.php
+++ b/lib/adodb/adodb-error.inc.php
@@ -1,6 +1,6 @@
DB_ERROR_ALREADY_EXISTS,
'/divide by zero$/' => DB_ERROR_DIVZERO,
'/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER,
- '/ttribute [\"\'].*[\"\'] not found$|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD,
+ '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD,
'/parser: parse error at or near \"/' => DB_ERROR_SYNTAX,
'/referential integrity violation/' => DB_ERROR_CONSTRAINT
);
-
- foreach ($error_regexps as $regexp => $code) {
+ reset($error_regexps);
+ while (list($regexp,$code) = each($error_regexps)) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
@@ -190,6 +190,7 @@ static $MAP = array(
function adodb_error_oci8()
{
static $MAP = array(
+ 1 => DB_ERROR_ALREADY_EXISTS,
900 => DB_ERROR_SYNTAX,
904 => DB_ERROR_NOSUCHFIELD,
923 => DB_ERROR_SYNTAX,
@@ -199,7 +200,7 @@ static $MAP = array(
1722 => DB_ERROR_INVALID_NUMBER,
2289 => DB_ERROR_NOSUCHTABLE,
2291 => DB_ERROR_CONSTRAINT,
- 2449 => DB_ERROR_CONSTRAINT,
+ 2449 => DB_ERROR_CONSTRAINT
);
return $MAP;
diff --git a/lib/adodb/adodb-errorhandler.inc.php b/lib/adodb/adodb-errorhandler.inc.php
index c0489c9ae25..f57263f0c1d 100644
--- a/lib/adodb/adodb-errorhandler.inc.php
+++ b/lib/adodb/adodb-errorhandler.inc.php
@@ -1,9 +1,9 @@
sql = $p1;
+ $this->params = $p2;
+ $s = "$dbms error: [$errno: $errmsg] in $fn(\"$p1\")\n";
+ break;
+
+ case 'PCONNECT':
+ case 'CONNECT':
+ $user = $thisConnection->user;
+ $s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)\n";
+ break;
+ default:
+ $s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n";
+ break;
+ }
+
+ $this->dbms = $dbms;
+ $this->host = $thisConnection->host;
+ $this->database = $thisConnection->database;
+ $this->fn = $fn;
+ $this->msg = $errmsg;
+
+ parent::__construct($s,$errno);
+ }
+}
+
+/**
+* Default Error Handler. This will be called with the following params
+*
+* @param $dbms the RDBMS you are connecting to
+* @param $fn the name of the calling function (in uppercase)
+* @param $errno the native error number from the database
+* @param $errmsg the native error msg from the database
+* @param $p1 $fn specific parameter - see below
+* @param $P2 $fn specific parameter - see below
+*/
+
+function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
+{
+global $ADODB_EXCEPTION;
+
+ if (is_string($ADODB_EXCEPTION)) $errfn = $ADODB_EXCEPTION;
+ else $errfn = 'ADODB_EXCEPTION';
+ throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
+}
+
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/adodb-iterator.inc.php b/lib/adodb/adodb-iterator.inc.php
new file mode 100644
index 00000000000..1817fade304
--- /dev/null
+++ b/lib/adodb/adodb-iterator.inc.php
@@ -0,0 +1,56 @@
+Execute("select * from adoxyz");
+ foreach($rs as $k => $v) {
+ echo $k; print_r($v); echo "
";
+ }
+ */
+
+class ADODB_Iterator implements Iterator {
+
+ private $rs;
+
+ function __construct($rs)
+ {
+ $this->rs = $rs;
+ }
+ function rewind()
+ {
+ $this->rs->MoveFirst();
+ }
+ function hasMore()
+ {
+ return !$this->rs->EOF;
+ }
+ function key()
+ {
+ return $this->rs->_currentRow;
+ }
+ function current()
+ {
+ return $this->rs->fields;
+ }
+ function next()
+ {
+ $this->rs->MoveNext();
+ }
+}
+
+
+class ADODB_BASE_RS implements IteratorAggregate {
+ function getIterator() {
+ return new ADODB_Iterator($this);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/adodb-lib.inc.php b/lib/adodb/adodb-lib.inc.php
index 7720ee12656..1c8d360d519 100644
--- a/lib/adodb/adodb-lib.inc.php
+++ b/lib/adodb/adodb-lib.inc.php
@@ -4,7 +4,7 @@ global $ADODB_INCLUDED_LIB;
$ADODB_INCLUDED_LIB = 1;
/*
-V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
+V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). 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.
@@ -19,7 +19,7 @@ V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights rese
function _array_change_key_case($an_array)
{
if (is_array($an_array)) {
- foreach($an_array as $key => $value)
+ foreach($an_array as $key=>$value)
$new_array[strtoupper($key)] = $value;
return $new_array;
@@ -28,6 +28,75 @@ function _array_change_key_case($an_array)
return $an_array;
}
+function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
+{
+ if (count($fieldArray) == 0) return 0;
+ $first = true;
+ $uSet = '';
+
+ if (!is_array($keyCol)) {
+ $keyCol = array($keyCol);
+ }
+ foreach($fieldArray as $k => $v) {
+ if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
+ $v = $zthis->qstr($v);
+ $fieldArray[$k] = $v;
+ }
+ if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
+
+ if ($first) {
+ $first = false;
+ $uSet = "$k=$v";
+ } else
+ $uSet .= ",$k=$v";
+ }
+
+ $where = false;
+ foreach ($keyCol as $v) {
+ if ($where) $where .= " and $v=$fieldArray[$v]";
+ else $where = "$v=$fieldArray[$v]";
+ }
+
+ if ($uSet && $where) {
+ $update = "UPDATE $table SET $uSet WHERE $where";
+
+ $rs = $zthis->Execute($update);
+ if ($rs) {
+ if ($zthis->poorAffectedRows) {
+ /*
+ The Select count(*) wipes out any errors that the update would have returned.
+ http://phplens.com/lens/lensforum/msgs.php?id=5696
+ */
+ if ($zthis->ErrorNo()<>0) return 0;
+
+ # affected_rows == 0 if update field values identical to old values
+ # for mysql - which is silly.
+
+ $cnt = $zthis->GetOne("select count(*) from $table where $where");
+ if ($cnt > 0) return 1; // record already exists
+ } else
+ if (($zthis->Affected_Rows()>0)) return 1;
+ }
+ }
+ // print "Error=".$this->ErrorNo().'
';
+ $first = true;
+ foreach($fieldArray as $k => $v) {
+ if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
+
+ if ($first) {
+ $first = false;
+ $iCols = "$k";
+ $iVals = "$v";
+ } else {
+ $iCols .= ",$k";
+ $iVals .= ",$v";
+ }
+ }
+ $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
+ $rs = $zthis->Execute($insert);
+ return ($rs) ? 2 : 0;
+}
+
// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
$size=0, $selectAttr='',$compareFields0=true)
@@ -138,9 +207,12 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
if ($qryRecs !== false) return $qryRecs;
}
+ //--------------------------------------------
// query rewrite failed - so try slower way...
+
+ // strip off unneeded ORDER BY
$rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
- $rstest = &$zthis->Execute($rewritesql);
+ $rstest = &$zthis->Execute($rewritesql,$inputarr);
if ($rstest) {
$qryRecs = $rstest->RecordCount();
if ($qryRecs == -1) {
@@ -400,79 +472,78 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false)
$values = '';
$fields = '';
$arrFields = _array_change_key_case($arrFields);
+
if (!$rs) {
- printf(ADODB_BAD_RS,'GetInsertSQL');
- return false;
- }
+ printf(ADODB_BAD_RS,'GetInsertSQL');
+ return false;
+ }
- $fieldInsertedCount = 0;
-
-
- // Loop through all of the fields in the recordset
- for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
+ $fieldInsertedCount = 0;
- // Get the field from the recordset
- $field = $rs->FetchField($i);
- // If the recordset field is one
- // of the fields passed in then process.
- $upperfname = strtoupper($field->name);
- if (adodb_key_exists($upperfname,$arrFields)) {
-
- // Set the counter for the number of fields that will be inserted.
- $fieldInsertedCount++;
+ // Loop through all of the fields in the recordset
+ for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
- // Get the name of the fields to insert
- $fields .= $field->name . ", ";
-
- $mt = $rs->MetaType($field->type);
-
- // "mike" patch and "Ryan Bailey"
- //PostgreSQL uses a 't' or 'f' and therefore needs to be processed as a string ('C') type field.
- if ((strncmp($zthis->databaseType,"postgres",8) === 0) && ($mt == "L")) $mt = "C";
+ // Get the field from the recordset
+ $field = $rs->FetchField($i);
+ // If the recordset field is one
+ // of the fields passed in then process.
+ $upperfname = strtoupper($field->name);
+ if (adodb_key_exists($upperfname,$arrFields)) {
- // Based on the datatype of the field
- // Format the value properly for the database
- if ((defined('ADODB_FORCE_NULLS') && is_null($arrFields[$upperfname])) || $arrFields[$upperfname] === 'null')
- $values .= "null, ";
- else
- switch($mt) {
- case "C":
- case "X":
- case 'B':
- $values .= $zthis->qstr($arrFields[$upperfname],$magicq) . ", ";
- break;
- case "D":
- $values .= $zthis->DBDate($arrFields[$upperfname]) . ", ";
- break;
- case "T":
- $values .= $zthis->DBTimeStamp($arrFields[$upperfname]) . ", ";
- break;
- default:
- $val = $arrFields[$upperfname];
- if (!is_numeric($val)) $val = (float) $val;
- $values .= $val . ", ";
- break;
- };
+ // Set the counter for the number of fields that will be inserted.
+ $fieldInsertedCount++;
+
+ // Get the name of the fields to insert
+ $fields .= $field->name . ", ";
+
+ $mt = $rs->MetaType($field->type);
+
+ // "mike" patch and "Ryan Bailey"
+ //PostgreSQL uses a 't' or 'f' and therefore needs to be processed as a string ('C') type field.
+ if ((strncmp($zthis->databaseType,"postgres",8) === 0) && ($mt == "L")) $mt = "C";
+
+ // Based on the datatype of the field
+ // Format the value properly for the database
+ if ((defined('ADODB_FORCE_NULLS') && is_null($arrFields[$upperfname])) || $arrFields[$upperfname] === 'null')
+ $values .= "null, ";
+ else
+ switch($mt) {
+ case "C":
+ case "X":
+ case 'B':
+ $values .= $zthis->qstr($arrFields[$upperfname],$magicq) . ", ";
+ break;
+ case "D":
+ $values .= $zthis->DBDate($arrFields[$upperfname]) . ", ";
+ break;
+ case "T":
+ $values .= $zthis->DBTimeStamp($arrFields[$upperfname]) . ", ";
+ break;
+ default:
+ $val = $arrFields[$upperfname];
+ if (!is_numeric($val)) $val = (float) $val;
+ $values .= $val . ", ";
+ break;
};
- };
+ };
+ };
- // If there were any inserted fields then build the rest of the insert query.
- if ($fieldInsertedCount > 0) {
- // Get the table name from the existing query.
- preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
+ // If there were any inserted fields then build the rest of the insert query.
+ if ($fieldInsertedCount <= 0) return false;
+
+ // Get the table name from the existing query.
+ preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
- // Strip off the comma and space on the end of both the fields
- // and their values.
- $fields = substr($fields, 0, -2);
- $values = substr($values, 0, -2);
+ // Strip off the comma and space on the end of both the fields
+ // and their values.
+ $fields = substr($fields, 0, -2);
+ $values = substr($values, 0, -2);
- // Append the fields and their values to the insert query.
- $insertSQL = "INSERT INTO " . $tableName[1] . " ( $fields ) VALUES ( $values )";
+ // Append the fields and their values to the insert query.
+ $insertSQL = "INSERT INTO " . $tableName[1] . " ( $fields ) VALUES ( $values )";
- return $insertSQL;
-
- } else {
- return false;
- };
+ return $insertSQL;
}
+
+
?>
\ No newline at end of file
diff --git a/lib/adodb/adodb-pager.inc.php b/lib/adodb/adodb-pager.inc.php
index e96c5497d12..ebff53faf12 100644
--- a/lib/adodb/adodb-pager.inc.php
+++ b/lib/adodb/adodb-pager.inc.php
@@ -1,6 +1,6 @@
PConnect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
else $ok = $obj->Connect($dsninfo['hostspec'], $dsninfo['username'],$dsninfo['password'],$dsninfo['database']);
- if (!$ok) return ADODB_PEAR_Error();
+ if (!$ok) $obj = ADODB_PEAR_Error();
return $obj;
}
diff --git a/lib/adodb/adodb-perf.inc.php b/lib/adodb/adodb-perf.inc.php
index bedd98f8124..9c0efd24d79 100644
--- a/lib/adodb/adodb-perf.inc.php
+++ b/lib/adodb/adodb-perf.inc.php
@@ -1,6 +1,6 @@
fnExecute = false;
$t0 = microtime();
$rs =& $conn->Execute($sql,$inputarr);
@@ -58,8 +60,12 @@ global $HTTP_SERVER_VARS;
$tracer = '';
$errM = '';
$errN = 0;
- $conn->lastInsID = $conn->Insert_ID();
-
+ $dbg = $conn->debug;
+ $conn->debug = false;
+ if (!is_object($rs) || $rs->dataProvider == 'empty')
+ $conn->_affected = $conn->affected_rows(true);
+ $conn->lastInsID = @$conn->Insert_ID();
+ $conn->debug = $dbg;
}
if (isset($HTTP_SERVER_VARS['HTTP_HOST'])) {
$tracer .= '
'.$HTTP_SERVER_VARS['HTTP_HOST'];
@@ -89,7 +95,7 @@ global $HTTP_SERVER_VARS;
$conn->debug = 0;
if ($conn->dataProvider == 'oci8' && $dbT != 'oci8po') {
- $isql = "insert into adodb_logsql values($conn->sysTimeStamp,:b,:c,:d,:e,:f)";
+ $isql = "insert into $perf_table values($conn->sysTimeStamp,:b,:c,:d,:e,:f)";
} else if ($dbT == 'odbc_mssql' || $dbT == 'informix') {
$timer = $arr['f'];
if ($dbT == 'informix') $sql2 = substr($sql2,0,230);
@@ -99,13 +105,12 @@ global $HTTP_SERVER_VARS;
$params = $conn->qstr($arr['d']);
$tracer = $conn->qstr($arr['e']);
- $isql = "insert into adodb_logsql (created,sql0,sql1,params,tracer,timer) values($conn->sysTimeStamp,$sql1,$sql2,$params,$tracer,$timer)";
+ $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values($conn->sysTimeStamp,$sql1,$sql2,$params,$tracer,$timer)";
if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql);
$arr = false;
} else {
- $isql = "insert into adodb_logsql (created,sql0,sql1,params,tracer,timer) values( $conn->sysTimeStamp,?,?,?,?,?)";
+ $isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $conn->sysTimeStamp,?,?,?,?,?)";
}
- $conn->_affected = $conn->affected_rows(true);
$ok = $conn->Execute($isql,$arr);
$conn->debug = $saved;
@@ -118,7 +123,7 @@ global $HTTP_SERVER_VARS;
if ($perf) {
if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr);
} else {
- $ok = $conn->Execute("create table adodb_logsql (
+ $ok = $conn->Execute("create table $perf_table (
created varchar(50),
sql0 varchar(250),
sql1 varchar(4000),
@@ -165,7 +170,18 @@ class adodb_perf {
var $explain = true;
var $helpurl = "LogSQL help";
var $createTableSQL = false;
+ var $maxLength = 2000;
+ // Sets the tablename to be used
+ function table($newtable = false)
+ {
+ static $_table;
+
+ if (!empty($newtable)) $_table = $newtable;
+ if (empty($_table)) $_table = 'adodb_logsql';
+ return $_table;
+ }
+
// returns array with info to calculate CPU Load
function _CPULoad()
{
@@ -285,10 +301,14 @@ Committed_AS: 348732 kB
function Tracer($sql)
{
+ $perf_table = adodb_perf::table();
+ $saveE = $this->conn->fnExecute;
+ $this->conn->fnExecute = false;
+
$sqlq = $this->conn->qstr($sql);
$arr = $this->conn->GetArray(
"select count(*),tracer
- from adodb_logsql where sql1=$sqlq
+ from $perf_table where sql1=$sqlq
group by tracer
order by 1 desc");
$s = '';
@@ -298,11 +318,17 @@ Committed_AS: 348732 kB
$s .= sprintf("%4d",$k[0]).' '.strip_tags($k[1]).'
';
}
}
+ $this->conn->fnExecute = $saveE;
return $s;
}
- function Explain($sql)
- {
+ /*
+ Explain Plan for $sql.
+ If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the
+ actual sql.
+ */
+ function Explain($sql,$partial=false)
+ {
return false;
}
@@ -314,7 +340,8 @@ Committed_AS: 348732 kB
$s = 'Invalid SQL
';
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
- $rs =& $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from adodb_logsql where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
+ $perf_table = adodb_perf::table();
+ $rs =& $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
$this->conn->fnExecute = $saveE;
if ($rs) {
$s .= rs2html($rs,false,false,false,false);
@@ -323,6 +350,7 @@ Committed_AS: 348732 kB
return $s;
}
+
/*
This script identifies the longest running SQL
@@ -331,11 +359,13 @@ Committed_AS: 348732 kB
{
global $ADODB_FETCH_MODE,$HTTP_GET_VARS;
+ $perf_table = adodb_perf::table();
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
if (isset($HTTP_GET_VARS['exps']) && isset($HTTP_GET_VARS['sql'])) {
- echo "".$this->Explain($HTTP_GET_VARS['sql'])."\n";
+ $partial = !empty($HTTP_GET_VARS['part']);
+ echo "".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
}
if (isset($HTTP_GET_VARS['sql'])) return;
@@ -346,7 +376,7 @@ Committed_AS: 348732 kB
//$this->conn->debug=1;
$rs =& $this->conn->SelectLimit(
"select avg(timer) as avg_timer,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
- from adodb_logsql
+ from $perf_table
where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
and (tracer is null or tracer not like 'ERROR:%')
group by sql1
@@ -358,14 +388,19 @@ Committed_AS: 348732 kB
$s = "Suspicious SQL
The following SQL have high average execution times
| Avg Time | Count | SQL | Max | Min |
\n";
+ $max = $this->maxLength;
while (!$rs->EOF) {
- $sql = trim($rs->fields[1]);
-
- $prefix = "";
+ $sql = $rs->fields[1];
+ $raw = urlencode($sql);
+ if (strlen($raw)>$max-100) {
+ $sql2 = substr($sql,0,$max-500);
+ $raw = urlencode($sql2).'&part='.crc32($sql);
+ }
+ $prefix = "";
$suffix = "";
- if ($this->explain == false || strlen($prefix)>2000) {
+ if ($this->explain == false || strlen($prefix)>$max) {
+ $suffix = ' ... String too long for GET parameter: '.strlen($prefix).'';
$prefix = '';
- $suffix = '';
}
$s .= "| ".round($rs->fields[0],6)." | ".$rs->fields[2]." | ".$prefix.htmlspecialchars($sql).$suffix."".
" | ".$rs->fields[3]." | ".$rs->fields[4]." |
";
@@ -401,11 +436,13 @@ Committed_AS: 348732 kB
{
global $HTTP_GET_VARS,$ADODB_FETCH_MODE;
+ $perf_table = adodb_perf::table();
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
if (isset($HTTP_GET_VARS['expe']) && isset($HTTP_GET_VARS['sql'])) {
- echo "".$this->Explain($HTTP_GET_VARS['sql'])."\n";
+ $partial = !empty($HTTP_GET_VARS['part']);
+ echo "".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
}
if (isset($HTTP_GET_VARS['sql'])) return;
@@ -415,7 +452,7 @@ Committed_AS: 348732 kB
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$rs =& $this->conn->SelectLimit(
"select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
- from adodb_logsql
+ from $perf_table
where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
and (tracer is null or tracer not like 'ERROR:%')
group by sql1
@@ -427,12 +464,17 @@ Committed_AS: 348732 kB
$s = "Expensive SQL
Tuning the following SQL will reduce the server load substantially
| Load | Count | SQL | Max | Min |
\n";
+ $max = $this->maxLength;
while (!$rs->EOF) {
$sql = $rs->fields[1];
-
- $prefix = "";
+ $raw = urlencode($sql);
+ if (strlen($raw)>$max-100) {
+ $sql2 = substr($sql,0,$max-500);
+ $raw = urlencode($sql2).'&part='.crc32($sql);
+ }
+ $prefix = "";
$suffix = "";
- if($this->explain == false || strlen($prefix>2000)) {
+ if($this->explain == false || strlen($prefix>$max)) {
$prefix = '';
$suffix = '';
}
@@ -529,8 +571,9 @@ Committed_AS: 348732 kB
function UI($pollsecs=5)
{
- global $HTTP_GET_VARS,$HTTP_SERVER_VARS;
+ global $HTTP_GET_VARS,$HTTP_SERVER_VARS,$HTTP_POST_VARS;
+ $perf_table = adodb_perf::table();
$conn = $this->conn;
$app = $conn->host;
@@ -541,7 +584,7 @@ Committed_AS: 348732 kB
$savelog = $this->conn->LogSQL(false);
$info = $conn->ServerInfo();
if (isset($HTTP_GET_VARS['clearsql'])) {
- $this->conn->Execute('delete from adodb_logsql');
+ $this->conn->Execute('delete from $perf_table');
}
$this->conn->LogSQL($savelog);
@@ -558,6 +601,7 @@ Committed_AS: 348732 kB
if (isset($HTTP_GET_VARS['do'])) $do = $HTTP_GET_VARS['do'];
+ else if (isset($HTTP_POST_VARS['do'])) $do = $HTTP_POST_VARS['do'];
else if (isset($HTTP_GET_VARS['sql'])) $do = 'viewsql';
else $do = 'stats';
@@ -568,11 +612,14 @@ Committed_AS: 348732 kB
if ($do == 'viewsql') $form = " | ";
else $form = " | ";
+ $allowsql = !defined('ADODB_PERF_NO_RUN_SQL');
+
if (empty($HTTP_GET_VARS['hidem']))
echo "";
@@ -581,7 +628,7 @@ Committed_AS: 348732 kB
default:
case 'stats':
echo $this->HealthCheck();
-
+ $this->conn->debug=1;
echo $this->CheckMemory();
break;
case 'poll':
@@ -592,6 +639,12 @@ Committed_AS: 348732 kB
echo "";
$this->Poll($pollsecs);
break;
+
+ case 'dosql':
+ if (!$allowsql) break;
+
+ $this->DoSQLForm();
+ break;
case 'viewsql':
if (empty($HTTP_GET_VARS['hidem']))
echo " Clear SQL Log
";
@@ -747,9 +800,104 @@ Committed_AS: 348732 kB
$this->conn->LogSQL($savelog);
return ($ok) ? true : false;
}
+
+ function DoSQLForm()
+ {
+ global $HTTP_SERVER_VARS,$HTTP_GET_VARS,$HTTP_POST_VARS,$HTTP_SESSION_VARS;
+
+ $HTTP_VARS = array_merge($HTTP_GET_VARS,$HTTP_POST_VARS);
+
+ $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
+ $sql = isset($HTTP_VARS['sql']) ? $HTTP_VARS['sql'] : '';
+
+ if (isset($HTTP_SESSION_VARS['phplens_sqlrows'])) $rows = $HTTP_SESSION_VARS['phplens_sqlrows'];
+ else $rows = 3;
+
+ if (isset($HTTP_VARS['SMALLER'])) {
+ $rows /= 2;
+ if ($rows < 3) $rows = 3;
+ $HTTP_SESSION_VARS['phplens_sqlrows'] = $rows;
+ }
+ if (isset($HTTP_VARS['BIGGER'])) {
+ $rows *= 2;
+ $HTTP_SESSION_VARS['phplens_sqlrows'] = $rows;
+ }
+
+?>
+
+
+
+undomq(trim($sql));
+ if (substr($sql,strlen($sql)-1) === ';') {
+ $print = true;
+ $sqla = $this->SplitSQL($sql);
+ } else {
+ $print = false;
+ $sqla = array($sql);
+ }
+ foreach($sqla as $sqls) {
+
+ if (!$sqls) continue;
+
+ if ($print) {
+ print "".htmlspecialchars($sqls)."
";
+ flush();
+ }
+ $savelog = $this->conn->LogSQL(false);
+ $rs = $this->conn->Execute($sqls);
+ $this->conn->LogSQL($savelog);
+ if ($rs && is_object($rs) && !$rs->EOF) {
+ rs2html($rs);
+ while ($rs->NextRecordSet()) {
+ print "";
+ rs2html($rs);
+ }
+ } else {
+ $e1 = (integer) $this->conn->ErrorNo();
+ $e2 = $this->conn->ErrorMsg();
+ if (($e1) || ($e2)) {
+ if (empty($e1)) $e1 = '-1'; // postgresql fix
+ print ' '.$e1.': '.$e2;
+ } else {
+ print "No Recordset returned
";
+ }
+ }
+ } // foreach
+ }
+
+ function SplitSQL($sql)
+ {
+ $arr = explode(';',$sql);
+ return $arr;
+ }
+
+ function undomq(&$m)
+ {
+ if (get_magic_quotes_gpc()) {
+ // undo the damage
+ $m = str_replace('\\\\','\\',$m);
+ $m = str_replace('\"','"',$m);
+ $m = str_replace('\\\'','\'',$m);
+ }
+ return $m;
+}
}
-
?>
\ No newline at end of file
diff --git a/lib/adodb/adodb-php4.inc.php b/lib/adodb/adodb-php4.inc.php
new file mode 100644
index 00000000000..ef2f55e393f
--- /dev/null
+++ b/lib/adodb/adodb-php4.inc.php
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/lib/adodb/adodb-time.inc.php b/lib/adodb/adodb-time.inc.php
index 5ea9c9eef9a..15545f12fe1 100644
--- a/lib/adodb/adodb-time.inc.php
+++ b/lib/adodb/adodb-time.inc.php
@@ -23,7 +23,7 @@ This library replaces native functions as follows:
date() with adodb_date()
gmdate() with adodb_gmdate()
mktime() with adodb_mktime()
- gmmktime() with adodb_gmmktime()45
+ gmmktime() with adodb_gmmktime()
The parameters are identical, except that adodb_date() accepts a subset
@@ -56,7 +56,7 @@ adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)
COPYRIGHT
(c) 2003 John Lim and released under BSD-style license except for code by jackbbs,
-which includes adodb_mktime, adodb_get_gmt_different, adodb_is_leap_year
+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
=============================================================================
@@ -174,6 +174,9 @@ c. Implement daylight savings, which looks awfully complicated, see
CHANGELOG
+- 26 Oct 2003 0.11
+Because of daylight savings problems (some systems apply daylight savings to
+January!!!), changed adodb_get_gmt_diff() to ignore daylight savings.
- 9 Aug 2003 0.10
Fixed bug with dates after 2038.
@@ -231,7 +234,7 @@ First implementation.
/*
Version Number
*/
-define('ADODB_DATE_VERSION',0.10);
+define('ADODB_DATE_VERSION',0.11);
/*
We check for Windows as only +ve ints are accepted as dates on Windows.
@@ -496,13 +499,13 @@ function adodb_year_digit_check($y)
/**
get local time zone offset from GMT
*/
-function adodb_get_gmt_different()
+function adodb_get_gmt_diff()
{
-static $DIFF;
- if (isset($DIFF)) return $DIFF;
+static $TZ;
+ if (isset($TZ)) return $TZ;
- $DIFF = mktime(0,0,0,1,2,1970) - gmmktime(0,0,0,1,2,1970);
- return $DIFF;
+ $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0);
+ return $TZ;
}
/**
@@ -527,7 +530,7 @@ function adodb_getdate($d=false,$fast=false)
*/
function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
{
- $d = $origd - ($is_gmt ? 0 : adodb_get_gmt_different());
+ $d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff());
$_day_power = 86400;
$_hour_power = 3600;
@@ -709,7 +712,7 @@ function adodb_date($fmt,$d=false,$is_gmt=false)
if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
- $gmt = adodb_get_gmt_different();
+ $gmt = adodb_get_gmt_diff();
$dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
case 'Y': $dates .= $year; break;
@@ -738,9 +741,9 @@ function adodb_date($fmt,$d=false,$is_gmt=false)
// HOUR
case 'Z':
- $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_different(); break;
+ $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break;
case 'O':
- $gmt = ($is_gmt) ? 0 : adodb_get_gmt_different();
+ $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff();
$dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
case 'H':
@@ -820,7 +823,7 @@ function adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false,$is_gmt=false)
return @mktime($hr,$min,$sec,$mon,$day,$year);
}
- $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_different();
+ $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff();
$hr = intval($hr);
$min = intval($min);
diff --git a/lib/adodb/adodb.inc.php b/lib/adodb/adodb.inc.php
index 4f40b6a2af4..46a72684e5c 100644
--- a/lib/adodb/adodb.inc.php
+++ b/lib/adodb/adodb.inc.php
@@ -2,7 +2,7 @@
/*
* Set tabs to 4 for best viewing.
*
- * Latest version is available at http://php.weblogs.com
+ * Latest version is available at http://php.weblogs.com/adodb
*
* This is the main include file for ADOdb.
* Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php
@@ -14,7 +14,7 @@
/**
\mainpage
- @version V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim\@natsoft.com.my). All rights reserved.
+ @version V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim\@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license. You can choose which license
you prefer.
@@ -40,28 +40,6 @@
// CONSTANT DEFINITIONS
//==============================================================================================
- define('ADODB_BAD_RS','Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;
');
-
- define('ADODB_FETCH_DEFAULT',0);
- define('ADODB_FETCH_NUM',1);
- define('ADODB_FETCH_ASSOC',2);
- define('ADODB_FETCH_BOTH',3);
-
- /*
- Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names.
- This currently works only with mssql, odbc, oci8po and ibase derived drivers.
-
- 0 = assoc lowercase field names. $rs->fields['orderid']
- 1 = assoc uppercase field names. $rs->fields['ORDERID']
- 2 = use native-case field names. $rs->fields['OrderID']
- */
- //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
-
- // allow [ ] @ ` and . in table names
- define('ADODB_TABLE_REGEX','([]0-9a-z_\`\.\@\[-]*)');
-
-
- if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10);
/**
* Set ADODB_DIR to the directory where this file resides...
@@ -69,15 +47,12 @@
*/
if (!defined('ADODB_DIR')) define('ADODB_DIR',dirname(__FILE__));
- if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
-
//==============================================================================================
// GLOBAL VARIABLES
//==============================================================================================
GLOBAL
$ADODB_vers, // database version
- $ADODB_Database, // last database driver used
$ADODB_COUNTRECS, // count number of records returned - slows down query
$ADODB_CACHE_DIR, // directory to cache recordsets
$ADODB_EXTENSION, // ADODB extension installed
@@ -88,17 +63,47 @@
// GLOBAL SETUP
//==============================================================================================
- if (strnatcmp(PHP_VERSION,'4.3.0')>=0) {
- define('ADODB_PHPVER',0x4300);
- } else if (strnatcmp(PHP_VERSION,'4.2.0')>=0) {
- define('ADODB_PHPVER',0x4200);
- } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
- define('ADODB_PHPVER',0x4050);
- } else {
- define('ADODB_PHPVER',0x4000);
- }
$ADODB_EXTENSION = defined('ADODB_EXTENSION');
- //if (extension_loaded('dbx')) define('ADODB_DBX',1);
+ if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) {
+
+ define('ADODB_BAD_RS','Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;
');
+
+ // allow [ ] @ ` and . in table names
+ define('ADODB_TABLE_REGEX','([]0-9a-z_\`\.\@\[-]*)');
+
+ // prefetching used by oracle
+ if (!defined('ADODB_PREFETCH_ROWS')) define('ADODB_PREFETCH_ROWS',10);
+
+
+ /*
+ Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names.
+ This currently works only with mssql, odbc, oci8po and ibase derived drivers.
+
+ 0 = assoc lowercase field names. $rs->fields['orderid']
+ 1 = assoc uppercase field names. $rs->fields['ORDERID']
+ 2 = use native-case field names. $rs->fields['OrderID']
+ */
+
+ define('ADODB_FETCH_DEFAULT',0);
+ define('ADODB_FETCH_NUM',1);
+ define('ADODB_FETCH_ASSOC',2);
+ define('ADODB_FETCH_BOTH',3);
+
+ if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100);
+
+ if (strnatcmp(PHP_VERSION,'4.3.0')>=0) {
+ define('ADODB_PHPVER',0x4300);
+ } else if (strnatcmp(PHP_VERSION,'4.2.0')>=0) {
+ define('ADODB_PHPVER',0x4200);
+ } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
+ define('ADODB_PHPVER',0x4050);
+ } else {
+ define('ADODB_PHPVER',0x4000);
+ }
+ }
+
+ //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
+
/**
Accepts $src and $dest arrays, replacing string $data
@@ -121,7 +126,6 @@
{
GLOBAL
$ADODB_vers, // database version
- $ADODB_Database, // last database driver used
$ADODB_COUNTRECS, // count number of records returned - slows down query
$ADODB_CACHE_DIR, // directory to cache recordsets
$ADODB_FETCH_MODE;
@@ -140,22 +144,17 @@
// Initialize random number generator for randomizing cache flushes
srand(((double)microtime())*1000000);
- /**
- * Name of last database driver loaded into memory. Set by ADOLoadCode().
- */
- $ADODB_Database = '';
-
/**
* ADODB version as a string.
*/
- $ADODB_vers = 'V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
+ $ADODB_vers = 'V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
/**
* Determines whether recordset->RecordCount() is used.
* Set to false for highest performance -- RecordCount() will always return -1 then
* for databases that provide "virtual" recordcounts...
*/
- $ADODB_COUNTRECS = true;
+ if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true;
}
@@ -218,11 +217,16 @@
var $debug = false; /// if set to true will output sql statements
var $maxblobsize = 256000; /// maximum size of blobs or large text fields -- some databases die otherwise like foxpro
var $concat_operator = '+'; /// default concat operator -- change to || for Oracle/Interbase
+ var $substr = 'substr'; /// substring operator
+ var $length = 'length'; /// string length operator
+ var $random = 'rand()'; /// random function
+ var $upperCase = false; /// uppercase function
var $fmtDate = "'Y-m-d'"; /// used by DBDate() as the default date format used by the database
var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; /// used by DBTimeStamp as the default timestamp fmt.
var $true = '1'; /// string that represents TRUE for a database
var $false = '0'; /// string that represents FALSE for a database
var $replaceQuote = "\\'"; /// string to use to replace quotes
+ var $nameQuote = '"'; /// string to use to quote identifiers and names
var $charSet=false; /// character set to use - only for interbase
var $metaDatabasesSQL = '';
var $metaTablesSQL = '';
@@ -242,7 +246,6 @@
//--
var $genID = 0; /// sequence id used by GenID();
var $raiseErrorFn = false; /// error function to call
- var $upperCase = false; /// uppercase function to call for searching/where
var $isoDates = false; /// accepts dates in ISO format
var $cacheSecs = 3600; /// cache for 1 hour
var $sysDate = false; /// name of function that returns the current date
@@ -320,7 +323,7 @@
*/
function outp($msg,$newline=true)
{
- global $HTTP_SERVER_VARS;
+ global $HTTP_SERVER_VARS,$ADODB_FLUSH;
if (defined('ADODB_OUTP')) {
$fn = ADODB_OUTP;
@@ -332,7 +335,8 @@
if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) echo $msg;
else echo strip_tags($msg);
- flush();
+ if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // dp not flush if output buffering enabled - useless - thx to Jesse Mullan
+
}
/**
@@ -470,9 +474,9 @@
* if the database does not support prepare.
*
*/
- function PrepareSP($sql)
+ function PrepareSP($sql,$param=false)
{
- return $this->Prepare($sql);
+ return $this->Prepare($sql,$param);
}
/**
@@ -597,6 +601,23 @@
{
return '?';
}
+
+ /*
+ InParameter and OutParameter are self-documenting versions of Parameter().
+ */
+ function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
+ {
+ return $this->Parameter($stmt,$var,$name,false,$maxLen,$type);
+ }
+
+ /*
+ */
+ function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
+ {
+ return $this->Parameter($stmt,$var,$name,true,$maxLen,$type);
+
+ }
+
/*
Usage in oracle
$stmt = $db->Prepare('select * from table where id =:myid and group=:group');
@@ -629,7 +650,6 @@
*/
function StartTrans($errfn = 'ADODB_TransMonitor')
{
-
if ($this->transOff > 0) {
$this->transOff += 1;
return;
@@ -662,8 +682,11 @@
$this->transOff = 0;
if ($this->_transOK && $autoComplete) {
- $this->CommitTrans();
- if ($this->debug) ADOConnection::outp("Smart Commit occurred");
+ if (!$this->CommitTrans()) {
+ $this->_transOK = false;
+ if ($this->debug) ADOConnection::outp("Smart Commit failed");
+ } else
+ if ($this->debug) ADOConnection::outp("Smart Commit occurred");
} else {
$this->RollbackTrans();
if ($this->debug) ADOCOnnection::outp("Smart Rollback occurred");
@@ -717,12 +740,11 @@
if (!is_array($sql) && !$this->_bindInputArray) {
$sqlarr = explode('?',$sql);
-
+
if (!$array_2d) $inputarr = array($inputarr);
- while(list(,$arr) = each($inputarr)) {
+ foreach($inputarr as $arr) {
$sql = ''; $i = 0;
- reset($arr);
- while(list(,$v) = each($arr)) {
+ foreach($arr as $v) {
$sql .= $sqlarr[$i];
// from Ron Baldwin
// Only quote string types
@@ -735,18 +757,17 @@
$i += 1;
}
$sql .= $sqlarr[$i];
+
if ($i+1 != sizeof($sqlarr))
ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql));
-
+
$ret =& $this->_Execute($sql,false);
if (!$ret) return $ret;
- }
-
+ }
} else {
-
if ($array_2d) {
$stmt = $this->Prepare($sql);
- while(list(,$arr) = each($inputarr)) {
+ foreach($inputarr as $arr) {
$ret =& $this->_Execute($stmt,$arr);
if (!$ret) return $ret;
}
@@ -756,7 +777,7 @@
} else {
$ret =& $this->_Execute($sql,false);
}
-
+
return $ret;
}
@@ -765,10 +786,9 @@
// debug version of query
if ($this->debug) {
global $HTTP_SERVER_VARS;
-
$ss = '';
if ($inputarr) {
- foreach ($inputarr as $kk => $vv) {
+ foreach($inputarr as $kk=>$vv) {
if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
$ss .= "($kk=>'$vv') ";
}
@@ -785,7 +805,6 @@
else ADOConnection::outp( "
\n($this->databaseType): ".htmlspecialchars($sqlTxt)." $ss\n
\n",false);
else
ADOConnection::outp( "=----\n($this->databaseType): ".($sqlTxt)." \n-----\n",false);
- flush();
$this->_queryID = $this->_query($sql,$inputarr);
/*
@@ -799,7 +818,6 @@
$err = $this->ErrorNo();
if ($err) {
ADOConnection::outp($err.': '.$emsg);
- flush();
}
}
} else
@@ -807,7 +825,6 @@
$e = $this->ErrorNo();
$m = $this->ErrorMsg();
ADOConnection::outp($e .': '. $m );
- flush();
}
} else {
// non-debug version of query
@@ -859,7 +876,7 @@
if (empty($this->_genSeqSQL)) return false;
return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
}
-
+
function DropSequence($seqname)
{
if (empty($this->_dropSeqSQL)) return false;
@@ -874,7 +891,6 @@
* @param startID if sequence does not exist, start at this ID
* @return 0 if not supported, otherwise a sequence id
*/
-
function GenID($seqname='adodbseq',$startID=1)
{
if (!$this->hasGenID) {
@@ -882,8 +898,11 @@
}
$getnext = sprintf($this->_genIDSQL,$seqname);
+
+ $holdtransOK = $this->_transOK;
$rs = @$this->Execute($getnext);
if (!$rs) {
+ $this->_transOK = $holdtransOK; //if the status was ok before reset
$createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
$rs = $this->Execute($getnext);
}
@@ -898,48 +917,49 @@
/**
* @return the last inserted ID. Not all databases support this.
*/
- function Insert_ID()
- {
- if ($this->_logsql && $this->lastInsID) return $this->lastInsID;
- if ($this->hasInsertID) return $this->_insertid();
- if ($this->debug) ADOConnection::outp( 'Insert_ID error
');
- return false;
+ function Insert_ID()
+ {
+ if ($this->_logsql && $this->lastInsID) return $this->lastInsID;
+ if ($this->hasInsertID) return $this->_insertid();
+ if ($this->debug) {
+ ADOConnection::outp( 'Insert_ID error
');
+ adodb_backtrace();
}
-
-
+ return false;
+ }
+
+
/**
* Portable Insert ID. Pablo Roca
*
* @return the last inserted ID. All databases support this. But aware possible
* problems in multiuser environments. Heavy test this before deploying.
*/
- function PO_Insert_ID($table="", $id="")
- {
- if ($this->hasInsertID){
- return $this->Insert_ID();
- } else {
- return $this->GetOne("SELECT MAX($id) FROM $table");
- }
- }
-
-
- /**
- * @return # rows affected by UPDATE/DELETE
- */
- function Affected_Rows()
- {
- if ($this->hasAffectedRows) {
- if ($this->fnExecute === 'adodb_log_sql') {
-
- if ($this->_logsql && $this->_affected !== false) return $this->_affected;
- }
- $val = $this->_affectedrows();
- return ($val < 0) ? false : $val;
- }
+ function PO_Insert_ID($table="", $id="")
+ {
+ if ($this->hasInsertID){
+ return $this->Insert_ID();
+ } else {
+ return $this->GetOne("SELECT MAX($id) FROM $table");
+ }
+ }
+
+ /**
+ * @return # rows affected by UPDATE/DELETE
+ */
+ function Affected_Rows()
+ {
+ if ($this->hasAffectedRows) {
+ if ($this->fnExecute === 'adodb_log_sql') {
+ if ($this->_logsql && $this->_affected !== false) return $this->_affected;
+ }
+ $val = $this->_affectedrows();
+ return ($val < 0) ? false : $val;
+ }
- if ($this->debug) ADOConnection::outp( 'Affected_Rows error
',false);
- return false;
- }
+ if ($this->debug) ADOConnection::outp( 'Affected_Rows error
',false);
+ return false;
+ }
/**
@@ -987,6 +1007,8 @@
}
}
if (sizeof($p)) return $p;
+ if (function_exists('ADODB_VIEW_PRIMARYKEYS'))
+ return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner);
return false;
}
@@ -1089,6 +1111,19 @@
return $rs;
}
+ /**
+ * Create serializable recordset. Breaks rs link to connection.
+ *
+ * @param rs the recordset to serialize
+ */
+ function &SerializableRS(&$rs)
+ {
+ $rs2 =& $this->_rs2rs($rs);
+ $ignore = false;
+ $rs2->connection =& $ignore;
+
+ return $rs2;
+ }
/**
* Convert database recordset to an array recordset
@@ -1203,6 +1238,7 @@
$rv = false;
$rs = &$this->Execute($sql, $inputarr);
if ($rs) {
+ $rv = array();
if ($trim) {
while (!$rs->EOF) {
$rv[] = trim(reset($rs->fields));
@@ -1311,8 +1347,8 @@
$ADODB_COUNTRECS = $crecs;
if ($rs) {
- $arr = array();
if (!$rs->EOF) $arr = $rs->fields;
+ else $arr = array();
$rs->Close();
return $arr;
}
@@ -1354,76 +1390,10 @@
function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false)
{
- if (count($fieldArray) == 0) return 0;
- $first = true;
- $uSet = '';
+ global $ADODB_INCLUDED_LIB;
+ if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
- if (!is_array($keyCol)) {
- $keyCol = array($keyCol);
- }
- foreach($fieldArray as $k => $v) {
- if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
- $v = $this->qstr($v);
- $fieldArray[$k] = $v;
- }
- if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
-
- if ($first) {
- $first = false;
- $uSet = "$k=$v";
- } else
- $uSet .= ",$k=$v";
- }
-
- $first = true;
- foreach ($keyCol as $v) {
- if ($first) {
- $first = false;
- $where = "$v=$fieldArray[$v]";
- } else {
- $where .= " and $v=$fieldArray[$v]";
- }
- }
-
- if ($uSet) {
- $update = "UPDATE $table SET $uSet WHERE $where";
-
- $rs = $this->Execute($update);
- if ($rs) {
- if ($this->poorAffectedRows) {
- /*
- The Select count(*) wipes out any errors that the update would have returned.
- http://phplens.com/lens/lensforum/msgs.php?id=5696
- */
- if ($this->ErrorNo()<>0) return 0;
-
- # affected_rows == 0 if update field values identical to old values
- # for mysql - which is silly.
-
- $cnt = $this->GetOne("select count(*) from $table where $where");
- if ($cnt > 0) return 1; // record already exists
- } else
- if (($this->Affected_Rows()>0)) return 1;
- }
-
- }
- // print "Error=".$this->ErrorNo().'
';
- $first = true;
- foreach($fieldArray as $k => $v) {
- if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
-
- if ($first) {
- $first = false;
- $iCols = "$k";
- $iVals = "$v";
- } else {
- $iCols .= ",$k";
- $iVals .= ",$v";
- }
- }
- $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
- $rs = $this->Execute($insert);
- return ($rs) ? 2 : 0;
+ return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc);
}
@@ -1451,7 +1421,7 @@
if ($sql === false) $sql = -1;
if ($offset == -1) $offset = false;
// sql, nrows, offset,inputarr
- $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$inputarr,$this->cacheSecs);
+ $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
} else {
if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()");
$rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
@@ -1797,23 +1767,6 @@
}
}
- /*
- * Maximum size of C field
- *
- function CharMax()
- {
- return 255; // make it conservative if not defined
- }
-
-
- /*
- * Maximum size of X field
- *
- function TextMax()
- {
- return 4000; // make it conservative if not defined
- }
- */
/**
* Close Connection
@@ -1934,20 +1887,33 @@
}
+ function _findschema(&$table,&$schema)
+ {
+ if (!$schema && ($at = strpos($table,'.')) !== false) {
+ $schema = substr($table,0,$at);
+ $table = substr($table,$at+1);
+ }
+ }
+
/**
* List columns in a database as an array of ADOFieldObjects.
* See top of file for definition of object.
*
* @param table table name to query
* @param upper uppercase table name (required by some databases)
+ * @schema is optional database schema to use - not supported by all databases.
*
* @return array of ADOFieldObjects for current table.
- */
+ */
function &MetaColumns($table,$upper=true)
{
global $ADODB_FETCH_MODE;
-
+
if (!empty($this->metaColumnsSQL)) {
+
+ $schema = false;
+ $this->_findschema($table,$schema);
+
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
@@ -1978,6 +1944,18 @@
return false;
}
+ /**
+ * List indexes on a table as an array.
+ * @param table table name to query
+ * @param primary include primary keys.
+ *
+ * @return array of indexes on current table.
+ */
+ function &MetaIndexes($table, $primary = false, $owner = false)
+ {
+ return FALSE;
+ }
+
/**
* List columns names in a table as an array.
* @param table table name to query
@@ -2025,7 +2003,7 @@
if (empty($d) && $d !== 0) return 'null';
if (is_string($d) && !is_numeric($d)) {
- if ($d === 'null') return $d;
+ if ($d === 'null' || strncmp($d,"'",1) === 0) return $d;
if ($this->isoDates) return "'$d'";
$d = ADOConnection::UnixDate($d);
}
@@ -2045,12 +2023,14 @@
{
if (empty($ts) && $ts !== 0) return 'null';
- if (is_string($ts) && !is_numeric($ts)) {
- if ($ts === 'null') return $ts;
- if ($this->isoDates) return "'$ts'";
- else $ts = ADOConnection::UnixTimeStamp($ts);
- }
-
+ # strlen(14) allows YYYYMMDDHHMMSS format
+ if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14))
+ return adodb_date($this->fmtTimeStamp,$ts);
+
+ if ($ts === 'null') return $ts;
+ if ($this->isoDates && strlen($ts) !== 14) return "'$ts'";
+
+ $ts = ADOConnection::UnixTimeStamp($ts);
return adodb_date($this->fmtTimeStamp,$ts);
}
@@ -2123,7 +2103,8 @@
*/
function UserTimeStamp($v,$fmt='Y-m-d H:i:s')
{
- if (is_numeric($v)) return adodb_date($fmt,$v);
+ # strlen(14) allows YYYYMMDDHHMMSS format
+ if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v);
$tt = $this->UnixTimeStamp($v);
// $tt == -1 if pre TIMESTAMP_FIRST_YEAR
if (($tt === false || $tt == -1) && $v != false) return $v;
@@ -2263,22 +2244,23 @@
//==============================================================================================
// CLASS ADORecordSet
//==============================================================================================
-
+ if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php');
+ else include_once(ADODB_DIR.'/adodb-iterator.inc.php');
/**
* RecordSet class that represents the dataset returned by the database.
* To keep memory overhead low, this class holds only the current row in memory.
* No prefetching of data is done, so the RecordCount() can return -1 ( which
* means recordcount not known).
*/
- class ADORecordSet {
+ class ADORecordSet extends ADODB_BASE_RS {
/*
* public variables
*/
var $dataProvider = "native";
var $fields = false; /// holds the current row data
var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob
- /// in other words, we use a text area for editting.
+ /// in other words, we use a text area for editing.
var $canSeek = false; /// indicates that seek is supported
var $sql; /// sql text
var $EOF = false; /// Indicates that the current record position is after the last record in a Recordset object.
@@ -2534,7 +2516,7 @@
*/
function UserTimeStamp($v,$fmt='Y-m-d H:i:s')
{
- if (is_numeric($v)) return adodb_date($fmt,$v);
+ if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v);
$tt = $this->UnixTimeStamp($v);
// $tt == -1 if pre TIMESTAMP_FIRST_YEAR
if (($tt === false || $tt == -1) && $v != false) return $v;
@@ -2792,16 +2774,14 @@
*/
function &GetRowAssoc($upper=1)
{
-
+ $record = array();
+ // if (!$this->fields) return $record;
+
if (!$this->bind) {
$this->GetAssocKeys($upper);
}
- $record = array();
- reset($this->bind);
- while(list($k,$v) = each($this->bind)) {
- //echo " $k $v, ";
- //foreach($this->bind as $k => $v) {
+ foreach($this->bind as $k => $v) {
$record[$k] = $this->fields[$v];
}
@@ -3067,6 +3047,7 @@
'TIMESTAMPTZ' => 'T',
'T' => 'T',
##
+ 'BOOL' => 'L',
'BOOLEAN' => 'L',
'BIT' => 'L',
'L' => 'L',
@@ -3122,7 +3103,7 @@
case 'C':
// is the char field is too long, return as text field...
- if (!empty($this->blobSize)) {
+ if ($this->blobSize >= 0) {
if ($len > $this->blobSize) return 'X';
} else if ($len > 250) {
return 'X';
@@ -3185,6 +3166,7 @@
if ($status != false) $this->_atLastPage = $status;
return $this->_atLastPage;
}
+
} // end class ADORecordSet
//==============================================================================================
@@ -3228,7 +3210,7 @@
/**
- * Setup the Array. Later we will have XML-Data and CSV handlers
+ * Setup the array.
*
* @param array is a 2-dimensional array holding the data.
* The first row should hold the column names
@@ -3245,8 +3227,10 @@
if ($colnames) {
$this->_skiprow1 = false;
$this->_colnames = $colnames;
- } else $this->_colnames = $array[0];
-
+ } else {
+ $this->_skiprow1 = true;
+ $this->_colnames = $array[0];
+ }
$this->Init();
}
/**
@@ -3316,7 +3300,9 @@
function _seek($row)
{
- if (sizeof($this->_array) && $row < $this->_numOfRows) {
+ if (sizeof($this->_array) && 0 <= $row && $row < $this->_numOfRows) {
+ $this->_currentRow = $row;
+ if ($this->_skiprow1) $row += 1;
$this->fields = $this->_array[$row];
return true;
}
@@ -3329,11 +3315,11 @@
$this->_currentRow++;
$pos = $this->_currentRow;
- if ($this->_skiprow1) $pos += 1;
if ($this->_numOfRows <= $pos) {
if (!$this->compat) $this->fields = false;
} else {
+ if ($this->_skiprow1) $pos += 1;
$this->fields = $this->_array[$pos];
return true;
}
@@ -3346,13 +3332,12 @@
function _fetch()
{
$pos = $this->_currentRow;
- if ($this->_skiprow1) $pos += 1;
if ($this->_numOfRows <= $pos) {
if (!$this->compat) $this->fields = false;
return false;
}
-
+ if ($this->_skiprow1) $pos += 1;
$this->fields = $this->_array[$pos];
return true;
}
@@ -3369,7 +3354,7 @@
//==============================================================================================
/**
- * Synonym for ADOLoadCode.
+ * Synonym for ADOLoadCode. Private function. Do not use.
*
* @deprecated
*/
@@ -3379,21 +3364,28 @@
}
/**
- * Load the code for a specific database driver
+ * Load the code for a specific database driver. Private function. Do not use.
*/
function ADOLoadCode($dbType)
{
- GLOBAL $ADODB_Database;
+ global $ADODB_LASTDB;
if (!$dbType) return false;
- $ADODB_Database = strtolower($dbType);
- switch ($ADODB_Database) {
- case 'maxsql': $ADODB_Database = 'mysqlt'; break;
+ $db = strtolower($dbType);
+ switch ($db) {
+ case 'maxsql': $db = 'mysqlt'; break;
case 'postgres':
- case 'pgsql': $ADODB_Database = 'postgres7'; break;
+ case 'pgsql': $db = 'postgres7'; break;
}
- // Karsten Kraus
- return @include_once(ADODB_DIR."/drivers/adodb-".$ADODB_Database.".inc.php");
+ $ok = @include_once(ADODB_DIR."/drivers/adodb-".$db.".inc.php");
+ $ADODB_LASTDB = $db;
+
+ if ($ok) return $db;
+
+ $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php";
+ if (file_exists($file)) ADOConnection::outp("Missing file: $file");
+ else ADOConnection::outp("Syntax error in file: $file");
+ return false;
}
/**
@@ -3415,7 +3407,7 @@
*/
function &ADONewConnection($db='')
{
- GLOBAL $ADODB_Database,$ADODB_NEWCONNECTION;
+ GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB;
if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
$errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
@@ -3428,30 +3420,30 @@
}
}
- $rez = true;
- if ($db) {
- if ($ADODB_Database != $db) ADOLoadCode($db);
- } else {
- if (!empty($ADODB_Database)) {
- ADOLoadCode($ADODB_Database);
- } else {
- $rez = false;
- }
- }
+ if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = '';
+ if (empty($db)) $db = $ADODB_LASTDB;
- if (!$rez) {
+ if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db);
+
+ if (!$db) {
if ($errorfn) {
// raise an error
+ $ignore = false;
$errorfn('ADONewConnection', 'ADONewConnection', -998,
"could not load the database driver for '$db",
- $dbtype);
+ $db,false,$ignore);
} else
ADOConnection::outp( "ADONewConnection: Unable to load database driver '$db'
",false);
return false;
}
- $cls = 'ADODB_'.$ADODB_Database;
+ $cls = 'ADODB_'.$db;
+ if (!class_exists($cls)) {
+ adodb_backtrace();
+ return false;
+ }
+
$obj =& new $cls();
if ($errorfn) $obj->raiseErrorFn = $errorfn;
@@ -3515,6 +3507,7 @@
$dict->dataProvider = $conn->dataProvider;
$dict->connection = &$conn;
$dict->upperName = strtoupper($drivername);
+ $dict->quote = $conn->nameQuote;
if (is_resource($conn->_connectionID))
$dict->serverInfo = $conn->ServerInfo();
@@ -3541,8 +3534,6 @@
if (strncmp(PHP_OS,'WIN',3) === 0) {
// skip the decimal place
$mtime = substr(str_replace(' ','_',microtime()),2);
- // unlink will let some latencies develop, so uniqid() is more random
- @unlink($filename);
// getmypid() actually returns 0 on Win98 - never mind!
$tmpname = $filename.uniqid($mtime).getmypid();
if (!($fd = fopen($tmpname,'a'))) return false;
@@ -3550,6 +3541,8 @@
if (!fwrite($fd,$contents)) $ok = false;
fclose($fd);
chmod($tmpname,0644);
+ // the tricky moment
+ @unlink($filename);
if (!@rename($tmpname,$filename)) {
unlink($tmpname);
$ok = false;
@@ -3573,57 +3566,74 @@
return $ok;
}
-
+ /*
+ Perform a print_r, with pre tags for better formatting.
+ */
function adodb_pr($var)
{
- echo " \n";print_r($var);echo "
\n";
+ if (isset($_SERVER['HTTP_USER_AGENT'])) {
+ echo " \n";print_r($var);echo "
\n";
+ } else
+ print_r($var);
}
- function adodb_backtrace($print=true,$levels=9999)
+ /*
+ Perform a stack-crawl and pretty print it.
+
+ @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then).
+ @param levels Number of levels to display
+ */
+ function adodb_backtrace($printOrArr=true,$levels=9999)
{
$s = '';
- if (PHPVERSION() >= 4.3) {
+ if (PHPVERSION() < 4.3) return;
+
+ $html = (isset($_SERVER['HTTP_USER_AGENT']));
+ $fmt = ($html) ? " %% line %4d, file: %s" : "%% line %4d, file: %s";
+
+ $MAXSTRLEN = 64;
+
+ $s = ($html) ? '' : '';
- $MAXSTRLEN = 64;
+ if (is_array($printOrArr)) $traceArr = $printOrArr;
+ else $traceArr = debug_backtrace();
+ array_shift($traceArr);
+ $tabs = sizeof($traceArr)-1;
- $s = '';
- $traceArr = debug_backtrace();
- array_shift($traceArr);
- $tabs = sizeof($traceArr)-1;
+ foreach ($traceArr as $arr) {
+ $levels -= 1;
+ if ($levels < 0) break;
- foreach ($traceArr as $arr) {
- $levels -= 1;
- if ($levels < 0) break;
-
- $args = array();
- for ($i=0; $i < $tabs; $i++) $s .= ' ';
- $tabs -= 1;
- $s .= '';
- if (isset($arr['class'])) $s .= $arr['class'].'.';
- if (isset($arr['args']))
- foreach($arr['args'] as $v) {
- if (is_null($v)) $args[] = 'null';
- else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
- else if (is_object($v)) $args[] = 'Object:'.get_class($v);
- else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
- else {
- $v = (string) @$v;
- $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
- if (strlen($v) > $MAXSTRLEN) $str .= '...';
- $args[] = $str;
- }
+ $args = array();
+ for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' ' : "\t";
+ $tabs -= 1;
+ if ($html) $s .= '';
+ if (isset($arr['class'])) $s .= $arr['class'].'.';
+ if (isset($arr['args']))
+ foreach($arr['args'] as $v) {
+ if (is_null($v)) $args[] = 'null';
+ else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
+ else if (is_object($v)) $args[] = 'Object:'.get_class($v);
+ else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
+ else {
+ $v = (string) @$v;
+ $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
+ if (strlen($v) > $MAXSTRLEN) $str .= '...';
+ $args[] = $str;
}
- $s .= $arr['function'].'('.implode(', ',$args).')';
- $s .= @sprintf(" %% line %4d, file: %s",
- $arr['line'],$arr['file'],$arr['file']);
- $s .= "\n";
- }
- $s .= '';
- if ($print) print $s;
- }
+ }
+ $s .= $arr['function'].'('.implode(', ',$args).')';
+
+
+ $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
+
+ $s .= "\n";
+ }
+ if ($html) $s .= '
';
+ if ($printOrArr) print $s;
+
return $s;
}
-
} // defined
?>
\ No newline at end of file
diff --git a/lib/adodb/datadict/datadict-access.inc.php b/lib/adodb/datadict/datadict-access.inc.php
index 39ba17da1ef..f1760c941ba 100644
--- a/lib/adodb/datadict/datadict-access.inc.php
+++ b/lib/adodb/datadict/datadict-access.inc.php
@@ -1,7 +1,7 @@
schema) $tabname = $this->schema.'.'.$tabname;
+ {
+ $tabname = $this->TableName ($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname $this->addCol";
@@ -82,9 +81,10 @@ class ADODB2_mssql extends ADODB_DataDict {
return $sql;
}
+ /*
function AlterColumnSQL($tabname, $flds)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
+ $tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
foreach($lines as $v) {
@@ -93,13 +93,15 @@ class ADODB2_mssql extends ADODB_DataDict {
return $sql;
}
+ */
function DropColumnSQL($tabname, $flds)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
- if (!is_array($flds)) $flds = explode(',',$flds);
+ $tabname = $this->TableName ($tabname);
+ if (!is_array($flds))
+ $flds = explode(',',$flds);
$f = array();
- $s = "ALTER TABLE $tabname";
+ $s = 'ALTER TABLE ' . $tabname;
foreach($flds as $v) {
$f[] = "\n$this->dropCol $v";
}
@@ -194,15 +196,29 @@ CREATE TABLE
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
- if (isset($idxoptions['REPLACE'])) $sql[] = "DROP INDEX $tabname.$idxname";
- if (isset($idxoptions['UNIQUE'])) $unique = ' UNIQUE';
- else $unique = '';
- if (is_array($flds)) $flds = implode(', ',$flds);
- if (isset($idxoptions['CLUSTERED'])) $clustered = ' CLUSTERED';
- else $clustered = '';
+ $sql = array();
- $s = "CREATE$unique$clustered INDEX $idxname ON $tabname ($flds)";
- if (isset($idxoptions[$this->upperName])) $s .= $idxoptions[$this->upperName];
+ if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
+ $sql[] = sprintf ($this->dropIndex, $tabname . '.' . $idxname);
+ if ( isset($idxoptions['DROP']) )
+ return $sql;
+ }
+
+ if ( empty ($flds) ) {
+ return $sql;
+ }
+
+ $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
+ $clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
+
+ if ( is_array($flds) )
+ $flds = implode(', ',$flds);
+ $s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
+
+ if ( isset($idxoptions[$this->upperName]) )
+ $s .= $idxoptions[$this->upperName];
+
+
$sql[] = $s;
return $sql;
diff --git a/lib/adodb/datadict/datadict-mysql.inc.php b/lib/adodb/datadict/datadict-mysql.inc.php
index 068821a5c74..2eed142e664 100644
--- a/lib/adodb/datadict/datadict-mysql.inc.php
+++ b/lib/adodb/datadict/datadict-mysql.inc.php
@@ -1,7 +1,7 @@
dropIndex, $this->NameQuote($idxname), $this->TableName($tabname)));
+ }
+
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
- //if (isset($idxoptions['REPLACE'])) $sql[] = "DROP INDEX IF EXISTS $idxname";
- if (isset($idxoptions['REPLACE'])) $sql[] = "DROP INDEX $idxname ON $tabname";
- if (isset($idxoptions['FULLTEXT'])) $unique = ' FULLTEXT';
- else if (isset($idxoptions['UNIQUE'])) $unique = ' UNIQUE';
- else $unique = '';
+ $sql = array();
+
+ if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
+ $sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
+ if ( isset($idxoptions['DROP']) )
+ return $sql;
+ }
+
+ if ( empty ($flds) ) {
+ return $sql;
+ }
+
+ if (isset($idxoptions['FULLTEXT'])) {
+ $unique = ' FULLTEXT';
+ } elseif (isset($idxoptions['UNIQUE'])) {
+ $unique = ' UNIQUE';
+ } else {
+ $unique = '';
+ }
+
+ if ( is_array($flds) )
+ $flds = implode(', ',$flds);
+ $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
+
+ if ( isset($idxoptions[$this->upperName]) )
+ $s .= $idxoptions[$this->upperName];
- if (is_array($flds)) $flds = implode(', ',$flds);
- $s = "CREATE$unique INDEX $idxname ON $tabname ($flds)";
- if (isset($idxoptions[$this->upperName])) $s .= $idxoptions[$this->upperName];
$sql[] = $s;
return $sql;
diff --git a/lib/adodb/datadict/datadict-oci8.inc.php b/lib/adodb/datadict/datadict-oci8.inc.php
index 17d71e12eca..e3afdd8067f 100644
--- a/lib/adodb/datadict/datadict-oci8.inc.php
+++ b/lib/adodb/datadict/datadict-oci8.inc.php
@@ -1,7 +1,7 @@
dropIndex, $idxname);
+ if ( isset($idxoptions['DROP']) )
+ return $sql;
+ }
+
+ if ( empty ($flds) ) {
+ return $sql;
+ }
+
if (isset($idxoptions['BITMAP'])) {
$unique = ' BITMAP';
- } else if (isset($idxoptions['UNIQUE']))
+ } elseif (isset($idxoptions['UNIQUE'])) {
$unique = ' UNIQUE';
- else
+ } else {
$unique = '';
+ }
- if (is_array($flds)) $flds = implode(', ',$flds);
- $s = "CREATE$unique INDEX $idxname ON $tabname ($flds)";
- if (isset($idxoptions[$this->upperName])) $s .= $idxoptions[$this->upperName];
- if (isset($idxoptions['oci8'])) $s .= $idxoptions['oci8'];
+ if ( is_array($flds) )
+ $flds = implode(', ',$flds);
+ $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
+
+ if ( isset($idxoptions[$this->upperName]) )
+ $s .= $idxoptions[$this->upperName];
+
+ if (isset($idxoptions['oci8']))
+ $s .= $idxoptions['oci8'];
+
+
$sql[] = $s;
return $sql;
diff --git a/lib/adodb/datadict/datadict-postgres.inc.php b/lib/adodb/datadict/datadict-postgres.inc.php
index 89914501a8f..6279227fe05 100644
--- a/lib/adodb/datadict/datadict-postgres.inc.php
+++ b/lib/adodb/datadict/datadict-postgres.inc.php
@@ -1,7 +1,7 @@
upperName])) $s .= $idxoptions[$this->upperName];
- $s .= "($flds)";
+ if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
+ $sql[] = sprintf ($this->dropIndex, $idxname);
+ if ( isset($idxoptions['DROP']) )
+ return $sql;
+ }
+
+ if ( empty ($flds) ) {
+ return $sql;
+ }
+
+ $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
+
+ $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
+
+ if (isset($idxoptions['HASH']))
+ $s .= 'USING HASH ';
+
+ if ( isset($idxoptions[$this->upperName]) )
+ $s .= $idxoptions[$this->upperName];
+
+ if ( is_array($flds) )
+ $flds = implode(', ',$flds);
+ $s .= '(' . $flds . ')';
$sql[] = $s;
return $sql;
diff --git a/lib/adodb/datadict/datadict-sybase.inc.php b/lib/adodb/datadict/datadict-sybase.inc.php
index 05358121628..37d1874b904 100644
--- a/lib/adodb/datadict/datadict-sybase.inc.php
+++ b/lib/adodb/datadict/datadict-sybase.inc.php
@@ -1,7 +1,7 @@
schema) $tabname = $this->schema.'.'.$tabname;
+ {
+ $tabname = $this->TableName ($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname $this->addCol";
@@ -84,7 +84,7 @@ class ADODB2_sybase extends ADODB_DataDict {
function AlterColumnSQL($tabname, $flds)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
+ $tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
foreach($lines as $v) {
@@ -96,7 +96,7 @@ class ADODB2_sybase extends ADODB_DataDict {
function DropColumnSQL($tabname, $flds)
{
- if ($this->schema) $tabname = $this->schema.'.'.$tabname;
+ $tabname = $this->TableName ($tabname);
if (!is_array($flds)) $flds = explode(',',$flds);
$f = array();
$s = "ALTER TABLE $tabname";
@@ -194,15 +194,28 @@ CREATE TABLE
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
- if (isset($idxoptions['REPLACE'])) $sql[] = "DROP INDEX $tabname.$idxname";
- if (isset($idxoptions['UNIQUE'])) $unique = ' UNIQUE';
- else $unique = '';
- if (is_array($flds)) $flds = implode(', ',$flds);
- if (isset($idxoptions['CLUSTERED'])) $clustered = ' CLUSTERED';
- else $clustered = '';
+ $sql = array();
- $s = "CREATE$unique$clustered INDEX $idxname ON $tabname ($flds)";
- if (isset($idxoptions[$this->upperName])) $s .= $idxoptions[$this->upperName];
+ if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
+ $sql[] = sprintf ($this->dropIndex, $tabname . '.' . $idxname);
+ if ( isset($idxoptions['DROP']) )
+ return $sql;
+ }
+
+ if ( empty ($flds) ) {
+ return $sql;
+ }
+
+ $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
+ $clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
+
+ if ( is_array($flds) )
+ $flds = implode(', ',$flds);
+ $s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
+
+ if ( isset($idxoptions[$this->upperName]) )
+ $s .= $idxoptions[$this->upperName];
+
$sql[] = $s;
return $sql;
diff --git a/lib/adodb/docs-adodb.htm b/lib/adodb/docs-adodb.htm
index ed41f28f899..65b808eb25d 100644
--- a/lib/adodb/docs-adodb.htm
+++ b/lib/adodb/docs-adodb.htm
@@ -11,7 +11,7 @@
ADOdb Library for PHP
-V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com)
+V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim#natsoft.com)
This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products.
Useful ADOdb links: Download Other Docs
@@ -21,12 +21,16 @@
How People are using ADOdb
Feature Requests and Bug Reports
Installation
- Initializing Code and Connection Examples
- Hacking ADOdb Safely
- ADONewConnection
+ Minimum Install
+ Initializing Code and Connection Examples
+ ADONewConnection
NewADOConnection
+ High Speed ADOdb - tuning tips
+ Hacking and Modifying ADOdb Safely
+ PHP5 Features
+ foreach iterators exceptions
Supported Databases
- Tutorial
+ Tutorials
Example 1: Select
Example 2: Advanced Select
Example 3: Insert
@@ -45,7 +49,7 @@
Caching
Pivot Tables
REFERENCE
-
Variables: $ADODB_COUNTRECS
+ Variables: $ADODB_COUNTRECS $ADODB_ANSI_PADDING_OFF
$ADODB_CACHE_DIR $ADODB_FETCH_MODE
$ADODB_LANG
Constants: ADODB_ASSOC_CASE
@@ -56,7 +60,8 @@
Executing SQL: Execute CacheExecute
SelectLimit CacheSelectLimit
Param Prepare PrepareSP
- Parameter
+ InParameter OutParameter
+
GetOne
CacheGetOne GetRow CacheGetRow
GetAll CacheGetAll GetCol
@@ -65,9 +70,11 @@
ExecuteCursor
(oci8 only)
Generates SQL strings: GetUpdateSQL GetInsertSQL
- Concat IfNull substr Param
+ Concat IfNull length random substr
+ qstr Param
OffsetDate SQLDate
- DBDate DBTimeStamp
+ DBDate DBTimeStamp
+
Blobs: UpdateBlob UpdateClob
UpdateBlobFile BlobEncode
BlobDecode
@@ -78,11 +85,11 @@
BeginTrans CommitTrans
RollbackTrans
Fetching Data: SetFetchMode
- Strings: concat qstr quote substr
+ Strings: concat length qstr quote substr
Dates: DBDate DBTimeStamp UnixDate
UnixTimeStamp OffsetDate
SQLDate
- Row Management: Affected_Rows Insert_ID
+ Row Management: Affected_Rows Insert_ID RowLock
GenID CreateSequence DropSequence
Error Handling: ErrorMsg ErrorNo
@@ -93,7 +100,8 @@
ServerInfo
Statistics and Query-Rewriting: LogSQL fnExecute
and fnCacheExecute
- Deprecated: Bind BlankRecordSet
+
Deprecated: Bind BlankRecordSet
+ Parameter
ADORecordSet
@@ -176,7 +184,7 @@ visit http://php.weblog
Make sure you are running PHP 4.0.4 or later.
Unpack all the files into a directory accessible by your webserver.
To test, try modifying some of the tutorial examples. Make sure you customize
- the connection settings correctly. You can debug using:
+ the connection settings correctly. You can debug using $db->debug = true as shown below:
<?php
include('adodb/adodb.inc.php');
$db = ADONewConnection($dbdriver); # eg 'mysql' or 'postgres'
@@ -187,18 +195,32 @@ visit http://php.weblog
print_r($rs->GetRows());
print "</pre>";
?>
-Code Initialization
+
+ Minimum Install
+For developers who want to release a minimal install of ADOdb, you will need:
+
+- adodb.inc.php
+
- adodb-lib.inc.php
+
- adodb-time.inc.php
+
- adodb-csvlib.inc.php (if you use cached recordsets - CacheExecute(), etc)
+
- adodb-error.inc.php and lang/adodb-$lang.inc.php (if you use MetaError())
+
- drivers/adodb-$database.inc.php
+
- license.txt (for legal reasons)
+
+
+Code Initialization Examples
When running ADOdb, at least two files are loaded. First is adodb/adodb.inc.php,
which contains all functions used by all database classes. The code specific
to a particular database is in the adodb/driver/adodb-????.inc.php file.
+
For example, to connect to a mysql database:
include('/path/to/set/here/adodb.inc.php');
$conn = &ADONewConnection('mysql');
Whenever you need to connect to a database, you create a Connection object
- using the ADONewConnection($driver) function.
- NewADOConnection($driver) is an alternative name for the same function.
+ using the ADONewConnection($driver) function.
+ NewADOConnection($driver) is an alternative name for the same function.
At this point, you are not connected to the database. You will first need to decide
whether to use persistent or non-persistent connections. The advantage of persistent
@@ -215,6 +237,7 @@ the creation of a new connection.
PHP will share the same connection. This can cause problems if the connections are meant to
different databases. The solution is to always use different userid's for different databases,
or use NConnect().
+
Examples of Connecting to Databases
MySQL and Most Other Database Drivers
MySQL connections are very straightforward, and the parameters are identical
@@ -240,19 +263,24 @@ You define the database in the $host parameter:
$conn = &ADONewConnection('ibase');
$conn->PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey');
-
+
SQLite
+Sqlite will create database if it does not exist.
+
+ $conn = &ADONewConnection('sqlite');
+ $conn->PConnect('c:\path\to\sqlite.db'); # sqlite will create if does not exist
+
Oracle
With Oracle, you can connect in multiple ways.
a. PHP and Oracle reside on the same machine, use default SID.
$conn->Connect(false, 'scott', 'tiger');
-b. TNS Name defined, eg. 'TNSDB'
- $conn->PConnect(false, 'scott', 'tiger', TNSDB');
+b. TNS Name defined, eg. 'myTNS'
+ $conn->PConnect(false, 'scott', 'tiger', 'myTNS');
or
- $conn->PConnect('TNSDB', 'scott', 'tiger');
-c. Host address and SID
+ $conn->PConnect('myTNS', 'scott', 'tiger');
+c. Host Address and SID
$conn->Connect('192.168.0.1', 'scott', 'tiger', 'SID');
-d. Host address and Service Name
+d. Host Address and Service Name
$conn->Connect('192.168.0.1', 'scott', 'tiger', 'servicename');
DSN-less ODBC (access and mssql examples)
@@ -262,7 +290,7 @@ You define the database in the $host parameter:
For Microsoft Access:
$db =& ADONewConnection('access');
- $dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\northwind.mdb;Uid=Admin;Pwd=;";
+ $dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;";
$db->Connect($dsn);
For Microsoft SQL Server:
@@ -278,7 +306,6 @@ using the ADOdb library and Microsoft's ADO:
<?php
include('adodb.inc.php');
- ADOLoadCode("ado_mssql");
$db = &ADONewConnection("ado_mssql");
print "<h1>Connecting DSN-less $db->databaseType...</h1>";
@@ -290,10 +317,36 @@ using the ADOdb library and Microsoft's ADO:
$arr = $rs->GetArray();
print_r($arr);
?>
-
-
-
-Hacking ADOdb Safely
+
+High Speed ADOdb - tuning tips
+ADOdb is a big class library, yet it consistently beats all other PHP class
+ libraries in performance. This is because it is designed in a layered fashion,
+ like an onion, with the fastest functions in the innermost layer. Stick to the
+ following functions for best performance:
+
+
+ Innermost Layer |
+
+
+ Connect, PConnect, NConnect
+ Execute, CacheExecute
+ SelectLimit, SelectLimit
+ MoveNext, Close
+ qstr, Affected_Rows, Insert_ID |
+
+
+The fastest way to access the fields is by accessing the array $recordset->fields
+ directly. Also set the global variables $ADODB_FETCH_MODE
+ = ADODB_FETCH_NUM, and (for oci8, ibase/firebird and odbc) $ADODB_COUNTRECS = false
+ before you connect to your database. At the time of writing (Dec 2003).
+Consider using bind parameters if your database supports it, as it improves
+ query plan reuse. Use ADOdb's performance tuning system to identify bottlenecks
+ quickly. At the time of writing (Dec 2003), this means oci8 and odbc drivers.
+Lastly make sure you have a PHP accelerator cache installed such as APC, Turck
+ MMCache, Zend Accelerator or ionCube.
+ Informix tips: Disable scrollable cursors with $db->cursorType = 0.
+
+Hacking ADOdb Safely
You might want to modify ADOdb for your own purposes. Luckily you can
still maintain backward compatibility by sub-classing ADOdb and using the $ADODB_NEWCONNECTION
variable. $ADODB_NEWCONNECTION allows you to override the behaviour of ADONewConnection().
@@ -339,6 +392,35 @@ include_once('adodb.inc.php');
Don't forget to call the constructor of the parent class.
+
+PHP5 Features
+ ADOdb 4.02 or later will transparently determine which version of PHP you are using.
+If PHP5 is detected, the following features become available:
+
Databases Supported
@@ -641,7 +723,7 @@ include_once('adodb.inc.php');
-
+
The "Tested" column indicates how extensively the code has been tested
and used.
A = well tested and used by many people
@@ -659,7 +741,7 @@ include_once('adodb.inc.php');
is executed, so you can selectively choose which recordsets to count.
-Tutorial
+Tutorials
Example 1: Select Statement
Task: Connect to the Access Northwind DSN, display the first 2 columns of each
row.
@@ -1124,7 +1206,7 @@ include('tohtml.inc.php');
$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); #invalid table productsz');
-if ($rs) $rs2html($rs);
+if ($rs) rs2html($rs);
?>
If you want to log the error message, you can do so by defining the following
@@ -1145,7 +1227,7 @@ include('tohtml.inc.php');
$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); ## invalid table productsz
-if ($rs) $rs2html($rs);
+if ($rs) rs2html($rs);
?>
The following message will be logged in the error.log file:
@@ -1164,7 +1246,7 @@ include('tohtml.inc.php');
$c = NewADOConnection('mysql');
$c->PConnect('localhost','root','','northwind');
$rs=$c->Execute('select * from productsz'); #invalid table productsz');
-if ($rs) $rs2html($rs);
+if ($rs) rs2html($rs);
else {
$e = ADODB_Pear_Error();
echo '<p>',$e->message,'</p>';
@@ -1237,7 +1319,7 @@ $rs = $conn->CacheExec
Since ADOdb 2.30, we support the generation of
SQL to create pivot tables, also known as cross-tabulations. For further explanation
read this DevShed Cross-Tabulation
-tutorial. We assume that your database supports the SQL case-when expression.
+tutorial. We assume that your database supports the SQL case-when expression.
In this example, we will use the Northwind database from Microsoft. In the
database, we have a products table, and we want to analyze this table by suppliers
@@ -1396,6 +1478,10 @@ tutorial. We assume that your database supports the SQL case-when expression
chown -R apache /path/to/adodb/cache
chgrp -R apache /path/to/adodb/cache
+$ADODB_ANSI_PADDING_OFF
+Determines whether to right trim CHAR fields (and also VARCHAR for ibase/firebird).
+Set to true to trim. Default is false. Currently works for oci8po, ibase and firebird
+drivers. Added in ADOdb 4.01.
$ADODB_LANG
Determines the language used in MetaErrorMsg(). The default is 'en', for English.
To find out what languages are supported, see the files
@@ -1562,7 +1648,7 @@ ADODB_NEVER_PERSIST before you call PConnect.
NConnect($host,[$user],[$password],[$database])
Always force a new connection. In contrast, PHP sometimes reuses connections
when you use Connect() or PConnect(). Currently works only on mysql (PHP 4.3.0
- or later) and oci8-derived drivers. For other drivers, NConnect() works like
+ or later), postgresql and oci8-derived drivers. For other drivers, NConnect() works like
Connect().
Execute($sql,$inputarr=false)
@@ -1587,6 +1673,7 @@ ADODB_NEVER_PERSIST before you call PConnect.
Variable binding speeds the compilation and caching of SQL statements, leading
to higher performance. Currently Oracle, Interbase and ODBC supports variable binding.
Interbase/ODBC style ? binding is emulated in databases that do not support binding.
+Note that you do not have to quote strings if you use binding.
Variable binding in the odbc, interbase and oci8po drivers.
$rs = $db->Execute('select * from table where val=?', array('10'));
@@ -1654,7 +1741,7 @@ only with SELECT statements.
# $rs is now just like any other ADOdb recordset object
rs2html($rs);
ExecuteCursor() is a helper function that does the following internally:
- $stmt = $db->Prepare("BEGIN :RS := SP_FOO(); END;");
+ $stmt = $db->Prepare("BEGIN :RS := SP_FOO(); END;", true);
$db->Parameter($stmt, $cur, 'RS', false, -1, OCI_B_CURSOR);
$rs = $db->Execute($stmt);
SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false)
@@ -2048,7 +2135,7 @@ convention.
for ($i=0; $i < $max; $i++)
$DB->Execute($stmt,array((string) rand(), $i));
-Also see PrepareSP() and Parameter() below. Only supported internally by interbase,
+
Also see InParameter(), OutParameter() and PrepareSP() below. Only supported internally by interbase,
oci8 and selected ODBC-based drivers, otherwise it is emulated. There is no
performance advantage to using Prepare() with emulation.
Important: Due to limitations or bugs in PHP, if you are getting errors when
@@ -2059,6 +2146,19 @@ for ($i=0; $i < $max; $i++)
$DB->Execute(
the function that checks whether a $field is null for the given database, and
if null, change the value returned to $nullReplacementValue. Eg.
$sql = 'SELECT '.$db->IfNull('name', "'- unknown -'"). ' FROM table';
+
+length
+This is not a function, but a property. Some databases have "length" and others "len"
+as the function to measure the length of a string. To use this property:
+
+ $sql = "SELECT ".$db->length."(field) from table";
+ $rs = $db->Execute($sql);
+
+
+random
+This is not a function, but a property. This is a string that holds the sql to
+generate a random number between 0.0 and 1.0 inclusive.
+
substr
This is not a function, but a property. Some databases have "substr" and others "substring"
as the function to retrieve a sub-string. To use this property:
@@ -2068,6 +2168,8 @@ as the function to retrieve a sub-string. To use this property:
For all databases, the 1st parameter of substr is the field, the 2nd is the
offset (1-based) to the beginning of the sub-string, and the 3rd is the length of the sub-string.
+
+
Param($name )
Generates a bind placeholder portably. For most databases, the bind placeholder
is "?". However some databases use named bind parameters such as Oracle, eg
@@ -2086,12 +2188,72 @@ $stmt = $DB->Execute($stmt,array('one','two'));
PrepareSP() allows you to do so.
Returns the same array or $sql string as Prepare( ) above. If you do not need
to bind to return values, you should use Prepare( ) instead.
-For examples of usage of PrepareSP( ), see Parameter( ) below.
+
For examples of usage of PrepareSP( ), see InParameter( ) below.
Note: in the mssql driver, preparing stored procedures requires a special function
call, mssql_init( ), which is called by this function. PrepareSP( ) is available
in all other drivers, and is emulated by calling Prepare( ).
+ InParameter($stmt, $var, $name,
+ $maxLen = 4000, $type = false )
+Binds a PHP variable as input to a stored procedure variable. The parameter $stmt
+ is the value returned by PrepareSP(), $var is the PHP variable you want to bind, $name
+ is the name of the stored procedure variable. Optional is $maxLen, the maximum length of the
+ data to bind, and $type which is database dependant.
+ Consult mssql_bind and ocibindbyname docs
+ at php.net for more info on legal values for $type.
+
+InParameter() is a wrapper function that calls Parameter() with $isOutput=false.
+The advantage of this function is that it is self-documenting, because
+the $isOutput parameter is no longer needed. Only for mssql
+ and oci8 currently.
+
Here is an example using oci8:
+
# For oracle, Prepare and PrepareSP are identical
+$stmt = $db->PrepareSP(
+ "declare RETVAL integer;
+ begin
+ :RETVAL := SP_RUNSOMETHING(:myid,:group);
+ end;");
+$db->InParameter($stmt,$id,'myid');
+$db->InParameter($stmt,$group,'group',64);
+$db->OutParameter($stmt,$ret,'RETVAL');
$db->Execute($stmt);
+
+ The same example using mssql:
+
+# @RETVAL = SP_RUNSOMETHING @myid,@group
+$stmt = $db->PrepareSP('SP_RUNSOMETHING');
# note that the parameter name does not have @ in front!
+$db->InParameter($stmt,$id,'myid');
+$db->InParameter($stmt,$group,'group',64);
+# return value in mssql - RETVAL is hard-coded name
+$db->OutParameter($stmt,$ret,'RETVAL');
+$db->Execute($stmt);
+
+Note that the only difference between the oci8 and mssql implementations is $sql.
+
+ If $type parameter is set to false, in mssql, $type will be dynamicly determined
+based on the type of the PHP variable passed (string
+=> SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 or float/double=>SQLFLT8).
+
+In oci8, $type can be set to OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File),
+OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) and OCI_B_ROWID (ROWID). To
+pass in a null, use $db->Parameter($stmt,
+$null=null, 'param').
+
OutParameter($stmt, $var, $name,
+ $maxLen = 4000, $type = false )
+ Binds a PHP variable as output from a stored procedure variable. The parameter $stmt
+ is the value returned by PrepareSP(), $var is the PHP variable you want to bind, $name
+ is the name of the stored procedure variable. Optional is $maxLen, the maximum length of the
+ data to bind, and $type which is database dependant.
+
+ OutParameter() is a wrapper function that calls Parameter() with $isOutput=true.
+ The advantage of this function is that it is self-documenting, because
+the $isOutput parameter is no longer needed. Only for mssql
+ and oci8 currently.
+
+For an example, see InParameter.
+
Parameter($stmt, $var, $name, $isOutput=false,
$maxLen = 4000, $type = false )
+Note: This function is deprecated, because of the new InParameter() and OutParameter() functions.
+These are superior because they are self-documenting, unlike Parameter().
Adds a bind parameter suitable for return values or special data handling (eg.
LOBs) after a statement has been prepared using PrepareSP(). Only for mssql
and oci8 currently. The parameters are:
@@ -2105,25 +2267,6 @@ $stmt = $DB->Execute($stmt,array('one','two'));
[$type] Consult mssql_bind and
ocibindbyname docs at php.net for
more info on legal values for type.
- Example:
-
-# @RETVAL = SP_RUNSOMETHING @myid,@group
$stmt = $db->PrepareSP('SP_RUNSOMETHING');
# note that the parameter name does not have @ in front!
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group',false,64);
# return value in mssql - RETVAL is hard-coded name
$db->Parameter($stmt,$ret,'RETVAL',true);
$db->Execute($stmt);
-An oci8 example:
-
-# For oracle, Prepare and PrepareSP are identical
-$stmt = $db->PrepareSP(
- "declare RETVAL integer;
begin
:RETVAL := SP_RUNSOMETHING(:myid,:group);
end;");
$db->Parameter($stmt,$id,'myid');
$db->Parameter($stmt,$group,'group',false,64);
-$db->Parameter($stmt,$ret,'RETVAL',true);
$db->Execute($stmt);
-
-Note that the only difference between the oci8 and mssql implementations is
- the syntax of $sql.
-If $type parameter is set to false, in mssql, $type will be dynamicly determined
-based on the type of the PHP variable passed (string
-=> SQLCHAR, boolean =>SQLINT1, integer =>SQLINT4 or float/double=>SQLFLT8).
-In oci8, $type can be set to OCI_B_FILE (Binary-File), OCI_B_CFILE (Character-File),
-OCI_B_CLOB (Character-LOB), OCI_B_BLOB (Binary-LOB) and OCI_B_ROWID (ROWID). To
-pass in a null, use $db->Parameter($stmt,
-$null=null, 'param').
Lastly, in oci8, bind parameters can be reused without calling PrepareSP( )
or Parameters again. This is not possible with mssql. An oci8 example:
$id = 0; $i = 0;
@@ -2231,7 +2374,17 @@ Usage:
echo $perf->SuspiciousSQL();
echo $perf->ExpensiveSQL();
-Also see Performance Monitor.
+
One limitation of logging is that rollback also prevents SQL from being logged.
+
+If you prefer to use another name for the table used to store the SQL, you can override it by calling
+adodb_perf::table($tablename), where $tablename is the new table name (you will still need to manually
+create the table yourself). An example:
+
+ include('adodb.inc.php');
+ include('adodb-perf.inc.php');
+ adodb_perf::table('my_logsql_table');
+
+Also see Performance Monitor.
fnExecute and fnCacheExecute properties
These two properties allow you to define bottleneck functions for all sql statements
processed by ADOdb. This allows you to perform statistical analysis and query-rewriting
@@ -2318,8 +2471,18 @@ printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$
Returns the last autonumbering ID inserted. Returns false if function not supported.
Only supported by databases that support auto-increment or object id's, such
- as PostgreSQL, MySQL and MSSQL currently. PostgreSQL returns the OID, which
+ as PostgreSQL, MySQL and MS SQL Server currently. PostgreSQL returns the OID, which
can change on a database reload.
+RowLock($table,$where)
+Lock a table row for the duration of a transaction. For example to lock record $id in table1:
+
+ $DB->StartTrans();
+ $DB->RowLock("table1","rowid=$id");
+ $DB->Execute($sql1);
+ $DB->Execute($sql2);
+ $DB->CompleteTrans();
+
+Supported in db2, interbase, informix, mssql, oci8, postgres, sybase.
MetaDatabases()
Returns a list of databases available on the server as an array. You have to
connect to the server first. Only available for ODBC, MySQL and ADO.
@@ -2333,10 +2496,15 @@ printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$
You can define a mask for matching. For example, setting $mask = 'TMP%' will
match all tables that begin with 'TMP'. Currently only mssql, oci8, odbc_mssql
and postgres* support $mask.
-
MetaColumns($table)
+MetaColumns($table,$toupper=true)
Returns an array of ADOFieldObject's, one field object for every column of
- $table. Currently Sybase does not recognise date types, and ADO cannot identify
- the correct data type (so we default to varchar)..
+ $table. A field object is a class instance with (name, type, max_length) defined.
+ Currently Sybase does not recognise date types, and ADO cannot identify
+ the correct data type (so we default to varchar).
+ The $toupper parameter determines whether we uppercase the table name
+ (required for some databases).
+
For schema support, pass in the $table parameter, "$schema.$tablename". This is only
+ supported for selected databases.
MetaColumnNames($table)
Returns an array of column names for $table.
MetaPrimaryKeys($table,
@@ -2344,6 +2512,24 @@ printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$
Returns an array containing column names that are the
primary keys of $table. Supported by mysql, odbc (including db2, odbc_mssql,
etc), mssql, postgres, interbase/firebird, oci8 currently.
+Views (and some tables) have primary keys, but sometimes this information is not available from the
+database. You can define a function ADODB_View_PrimaryKeys($databaseType, $database, $view, $owner) that
+should return an array containing the fields that make up the primary key. If that function exists,
+it will be called when MetaPrimaryKeys() cannot find a primary key for a table or view.
+
+// In this example: dbtype = 'oci8', $db = 'mydb', $view = 'dataView', $owner = false
+function ADODB_View_PrimaryKeys($dbtype,$db,$view,$owner)
+{
+ switch(strtoupper($view)) {
+ case 'DATAVIEW': return array('DATAID');
+ default: return false;
+ }
+}
+
+$db = NewADOConnection('oci8');
+$db->Connect('localhost','root','','mydb');
+$db->MetaPrimaryKeys('dataView');
+
ServerInfo($table)
Returns an array of containing two elements 'description'
and 'version'. The 'description' element contains the string description of
@@ -2437,12 +2623,12 @@ for GetArray() for compatibility with Microsoft ADO.
time the selection is based on the 2nd column, which holds the values to return
to the Web server.
UserDate($str, [$fmt])
-Converts the date string $str to another format.UserDate calls UnixDate
- to parse $str, and $fmt defaults to Y-m-d if not defined.
+Converts the date string $str to another format. The date format is Y-m-d,
+or Unix timestamp format. The default $fmt is Y-m-d.
UserTimeStamp($str, [$fmt])
Converts the timestamp string $str to another format. The timestamp
- format is Y-m-d H:i:s, as in '2002-02-28 23:00:12'. UserTimeStamp calls UnixTimeStamp
- to parse $str, and $fmt defaults to Y-m-d H:i:s if not defined.
+ format is Y-m-d H:i:s, as in '2002-02-28 23:00:12', or Unix timestamp format.
+ UserTimeStamp calls UnixTimeStamp to parse $str, and $fmt defaults to Y-m-d H:i:s if not defined.
UnixDate($str)
Parses the date string $str and returns it in unix mktime format (eg.
@@ -2454,8 +2640,8 @@ for GetArray() for compatibility with Microsoft ADO.
UnixTimeStamp($str)
Parses the timestamp string $str and returns it in unix mktime format
(eg. a number indicating the seconds after January 1st, 1970). Expects the date
- to be in Y-m-d H:i:s format, except for Sybase and Microsoft SQL Server, where
- M d Y h:i:sA is also accepted (the 3 letter month strings are controlled by
+ to be in "Y-m-d, H:i:s" (1970-12-24, 00:00:00) or "Y-m-d H:i:s" (1970-12-24 00:00:00) or "YmdHis" (19701225000000) format, except for Sybase and Microsoft SQL Server, where
+ "M d Y h:i:sA" (Dec 25 1970 00:00:00AM) is also accepted (the 3 letter month strings are controlled by
a global array, which might need localisation).
This function is available in both ADORecordSet and ADOConnection
@@ -2669,7 +2855,12 @@ For example, $db->MetaType('char') will return 'C'.
parameter, instead of $nativeDBType.
Close( )
-Close the recordset.
+Closes the recordset, cleaning all memory and resources associated with the recordset.
+
+If memory management is not an issue, you do not need to call this function as recordsets
+are closed for you by PHP at the end of the script.
+SQL statements such as INSERT/UPDATE/DELETE do not really return a recordset, so you do not have to call Close()
+for such SQL statements.
function rs2html($adorecordset,[$tableheader_attributes],
[$col_titles])
@@ -2778,17 +2969,93 @@ $rs = $conn->Execute
See the RoadMap article.
Also see the ADOdb proxy article
for bridging Windows and Unix databases using http remote procedure calls. For
- your education, visit palslib.com for database info,
+ your education, visit palslib.com for database info,
and read this article on Optimizing
PHP.
-
-Change Log
+
+
Change Log
+4.11 27 Jan 2004
+
Table misspelt in perf-oci8.inc.php. Changed v$conn_cache_advice to v$db_cache_advice. Reported by Steve W.
+
UserTimeStamp and DBTimeStamp did not handle YYYYMMDDHHMMSS format properly. Reported by Mike Muir. Fixed.
+
Changed oci8 Prepare(). Does not auto-allocate OCINewCursor automatically, unless 2nd param is set to true.
+This will break backward compat, if Prepare/Execute is used instead of ExecuteCursor. Reported by Chris Jones.
+
Added InParameter() and OutParameter(). Wrapper functions to Parameter(), but nicer because they
+are self-documenting.
+
Added 'R' handling in ActualType() to datadict-mysql.inc.php
+
Added ADOConnection::SerializableRS($rs). Returns a recordset that can be serialized in a session.
+
Added "Run SQL" to performance UI().
+
Misc spelling corrections in adodb-mysqli.inc.php, adodb-oci8.inc.php and datadict-oci8.inc.php, from Heinz Hombergs.
+
MetaIndexes() for ibase contributed by Heinz Hombergs.
+
4.10 12 Jan 2004
+
Dan Cech contributed extensive changes to data dictionary to support name quoting (with `), and drop table/index.
+
Informix added cursorType property. Default remains IFX_SCROLL, but you can change to 0 (non-scrollable cursor) for performance.
+
Added ADODB_View_PrimaryKeys() for returning view primary keys to MetaPrimaryKeys().
+
Simplified chinese file, adodb-cn.inc.php from cysoft.
+
Added check for ctype_alnum in adodb-datadict.inc.php. Thx to Jason Judge.
+
Added connection parameter to ibase Prepare(). Fix by Daniel Hassan.
+
Added nameQuote for quoting identifiers and names to connection obj. Requested by Jason Judge. Also the
+data dictionary parser now detects `field name` and generates column names with spaces correctly.
+
BOOL type not recognised correctly as L. Fixed.
+
Fixed paths in ADODB_DIR for session files, and back-ported it to 4.05 (15 Dec 2003)
+
Added Schema to postgresql MetaTables. Thx to col#gear.hu
+
Empty postgresql recordsets that had blob fields did not set EOF properly. Fixed.
+
CacheSelectLimit internal parameters to SelectLimit were wrong. Thx to Nio.
+
Modified adodb_pr() and adodb_backtrace() to support command-line usage (eg. no html).
+
Fixed some fr and it lang errors. Thx to Gaetano G.
+
Added contrib directory, with adodb rs to xmlrpc convertor by Gaetano G.
+
Fixed array recordset bugs when _skiprow1 is true. Thx to Gaetano G.
+
Fixed pivot table code when count is false.
+
+
+
4.05 13 Dec 2003
+
Added MetaIndexes - thx to Dan Cech.
+
Rewritten session code by Ross Smith. Moved code to adodb/session directory.
+
Added function exists check on connecting to most drivers, so we don't crash with the unknown function error.
+
Smart Transactions failed with GenID() when it no seq table has been created because the sql
+ statement fails. Fix by Mark Newnham.
+
Added $db->length, which holds name of function that returns strlen.
+
Fixed error handling for bad driver in ADONewConnection - passed too few params to error-handler.
+
Datadict did not handle types like 16.0 properly in _GetSize. Fixed.
+
Oci8 driver SelectLimit() bug &= instead of =& used. Thx to Swen Thümmler.
+
Jesse Mullan suggested not flushing outp when output buffering enabled. Due to Apache 2.0 bug. Added.
+
MetaTables/MetaColumns return ref bug with PHP5 fixed in adodb-datadict.inc.php.
+
New mysqli driver contributed by Arjen de Rijke. Based on adodb 3.40 driver.
+Then jlim added BeginTrans, CommitTrans, RollbackTrans, IfNull, SQLDate. Also fixed return ref bug.
+
$ADODB_FLUSH added, if true then force flush in debugging outp. Default is false. In earlier
+versions, outp defaulted to flush, which is not compat with apache 2.0.
+
Mysql driver's GenID() function did not work when when sql logging is on. Fixed.
+
$ADODB_SESSION_TBL not declared as global var. Not available if adodb-session.inc.php included in function. Fixed.
+
The input array not passed to Execute() in _adodb_getcount(). Fixed.
+
4.04 13 Nov 2003
+
Switched back to foreach - faster than list-each.
+
Fixed bug in ado driver - wiping out $this->fields with date fields.
+
Performance Monitor, View SQL, Explain Plan did not work if strlen($SQL)>max($_GET length). Fixed.
+
Performance monitor, oci8 driver added memory sort ratio.
+
Added random property, returns SQL to generate a floating point number between 0 and 1;
+
4.03 6 Nov 2003
+
The path to adodb-php4.inc.php and adodb-iterators.inc.php was not setup properly.
+
Patched SQLDate in interbase to support hours/mins/secs. Thx to ari kuorikoski.
+
Force autorollback for pgsql persistent connections -
+apparently pgsql did not autorollback properly before 4.3.4. See http://bugs.php.net/bug.php?id=25404
+
4.02 5 Nov 2003
+
Some errors in adodb_error_pg() fixed. Thx to Styve.
+
Spurious Insert_ID() error was generated by LogSQL(). Fixed.
+
Insert_ID was interfering with Affected_Rows() and Replace() when LogSQL() enabled. Fixed.
+
More foreach loops optimized with list/each.
+
Null dates not handled properly in ADO driver (it becomes 31 Dec 1969!).
+
Heinz Hombergs contributed patches for mysql MetaColumns - adding scale, made
+interbase MetaColumns work with firebird/interbase, and added lang/adodb-de.inc.php.
+
Added INFORMIXSERVER environment variable.
+
Added $ADODB_ANSI_PADDING_OFF for interbase/firebird.
+
PHP 5 beta 2 compat check. Foreach (Iterator) support. Exceptions support.
4.01 23 Oct 2003
-
Informix ErrorNo() fixed.
-
Modified PostgreSQL _fixblobs to use list/each instead of foreach.
-
Modified several places to use list/each, including GetRowAssoc().
+
Fixed bug in rs2html(), tohtml.inc.php, that generated blank table cells.
Fixed insert_id() incorrectly generated when logsql() enabled.
+
Modified PostgreSQL _fixblobs to use list/each instead of foreach.
+
Informix ErrorNo() implemented correctly.
+
Modified several places to use list/each, including GetRowAssoc().
Added UserTimeStamp() to connection class.
+
Added $ADODB_ANSI_PADDING_OFF for oci8po.
4.00 20 Oct 2003
Upgraded adodb-xmlschema to 1 Oct 2003 snapshot.
Fix to rs2html warning message. Thx to Filo.
diff --git a/lib/adodb/docs-datadict.htm b/lib/adodb/docs-datadict.htm
index 6840245a363..a5192d48ab2 100644
--- a/lib/adodb/docs-datadict.htm
+++ b/lib/adodb/docs-datadict.htm
@@ -11,7 +11,7 @@
ADOdb Data Dictionary Library for PHP
- V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my)
+ V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)
This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products.
Useful ADOdb links: Download Other Docs
@@ -65,9 +65,10 @@ $dict->ExecuteSQLArray($sqlarray);
The older (and still supported) format of $fldarray is a 2-dimensional array, where each row in the
1st dimension represents one field. Each row has this format:
array($fieldname, $type, [,$colsize] [,$otheroptions]*)
- The first 2 fields must be the field name and the field type. The field type
- can be a portable type codes or the actual type for that database.
-
+
+
The first 2 fields must be the field name and the field type. The field type
+ can be a portable type codes or the actual type for that database.
+
Legal portable type codes include:
C: varchar
@@ -97,40 +98,41 @@ N: Numeric or decimal number
The $otheroptions include the following keywords (case-insensitive):
-AUTO For autoincrement number. Emulated with triggers if not available.
+AUTO For autoincrement number. Emulated with triggers if not available.
Sets NOTNULL also.
-AUTOINCREMENT Same as auto.
-KEY Primary key field. Sets NOTNULL also. Compound keys are supported.
+AUTOINCREMENT Same as auto.
+KEY Primary key field. Sets NOTNULL also. Compound keys are supported.
PRIMARY Same as KEY.
-DEF Synonym for DEFAULT for lazy typists.
-DEFAULT The default value. Character strings are auto-quoted unless
- the string begins and ends with spaces, eg ' SYSDATE '.
-NOTNULL If field is not null.
-DEFDATE Set default value to call function to get today's date.
-DEFTIMESTAMP Set default to call function to get today's datetime.
-NOQUOTE Prevents autoquoting of default string values.
-CONSTRAINTS Additional constraints defined at the end of the field
- definition.
+DEF Synonym for DEFAULT for lazy typists.
+DEFAULT The default value. Character strings are auto-quoted unless
+ the string begins and ends with spaces, eg ' SYSDATE '.
+NOTNULL If field is not null.
+DEFDATE Set default value to call function to get today's date.
+DEFTIMESTAMP Set default to call function to get today's datetime.
+NOQUOTE Prevents autoquoting of default string values.
+CONSTRAINTS Additional constraints defined at the end of the field
+ definition.
The Data Dictonary accepts two formats, the older array specification:
$flds = array(
- array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NotNull'),
- array('ID', 'I' , 'AUTO'),
- array('MYDATE', 'D' , 'DEFDATE'),
- array('NAME', 'C' ,'32',
+ array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NotNull'),
+ array('id', 'I' , 'AUTO'),
+ array('`MY DATE`', 'D' , 'DEFDATE'),
+ array('NAME', 'C' , '32',
'CONSTRAINTS' => 'FOREIGN KEY REFERENCES reftable')
);
Or the simpler declarative format:
$flds = "
COLNAME DECIMAL(8.4) DEFAULT 0 NotNull,
- ID I AUTO,
- MYDATE D DEFDATE,
+ id I AUTO,
+ `MY DATE` D DEFDATE,
NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable'
";
- The $taboptarray is the 3rd parameter of the CreateTableSQL function.
+ Note that if you have special characters in the field name (e.g. My Date), you should enclose it in back-quotes. Normally field names are not case-sensitive, but if you enclose it in back-quotes, some databases treat the names as case-sensitive, and some don't. So be careful.
+
The $taboptarray is the 3rd parameter of the CreateTableSQL function.
This contains table specific settings. Legal keywords include:
@@ -138,6 +140,9 @@ Or the simpler declarative format:
Indicates that the previous table definition should be removed (dropped)together
with ALL data. See first example below.
+ - DROP
+ Drop table. Useful for removing unused tables.
+
- CONSTRAINTS
Define this as the key, with the constraint as the value. See the postgresql
example below. Additional constraints defined for the whole table. You
@@ -177,6 +182,7 @@ Or the simpler declarative format:
UNIQUE Make unique index
FULLTEXT Make fulltext index (only mysql)
HASH Create hash index (only postgres)
+ DROP Drop legacy index
function AddColumnSQL($tabname, $flds)
Add one or more columns. Not guaranteed to work under all situations.
diff --git a/lib/adodb/docs-perf.htm b/lib/adodb/docs-perf.htm
index 05c909cf9a1..bfcaa774338 100644
--- a/lib/adodb/docs-perf.htm
+++ b/lib/adodb/docs-perf.htm
@@ -7,7 +7,7 @@
The ADOdb Performance Monitoring Library
-V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my)
+V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)
This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products.
Useful ADOdb links: Download Other Docs
diff --git a/lib/adodb/docs-session.htm b/lib/adodb/docs-session.htm
index 16ca8cdc5fe..04204789a62 100644
--- a/lib/adodb/docs-session.htm
+++ b/lib/adodb/docs-session.htm
@@ -3,22 +3,23 @@
ADODB Session Management Manual
-
+ body,td {font-family:Arial,Helvetica,sans-serif;font-size:11pt}
+ pre {font-size:9pt}
+ .toplink {font-size:8pt}
+ />
+
ADODB Session Management Manual
-V4.01 23 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my)
+V4.11 27 Jan 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)
This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products.
Useful ADOdb links: Download Other Docs
Introduction
-PHP is packed with good features. One of the most popular is session variables.
-These are variables that persist throughout a session, as the user moves from page to page. Session variables are great holders of state information and other useful stuff.
+
+We store state information specific to a user or web client in session variables. These session variables
+ persist throughout a session, as the user moves from page to page.
To use session variables, call session_start() at the beginning of your web page,
before your HTTP headers are sent. Then for every variable you want to keep alive
@@ -35,13 +36,15 @@ the session handler will keep track of the session by using a cookie. You can sa
Then the ADOdb session handler provides you with the above additional capabilities
by storing the session information as records in a database table that can be
shared across multiple servers.
+
Important Upgrade Notice: Since ADOdb 4.05, the session files have been moved to its own folder, adodb/session. This is a rewrite
+of the session code by Ross Smith. The old session code is in adodb/session/old.
ADOdb Session Handler Features
- Ability to define a notification function that is called when a session expires. Typically
used to detect session logout and release global resources.
- Optimization of database writes. We crc32 the session data and only perform an update
to the session data if there is a data change.
-
- Support for large amounts of session data with CLOBs (see adodb-session-clob.inc.php). Useful
+
- Support for large amounts of session data with CLOBs (see adodb-session-clob.php). Useful
for Oracle.
- Support for encrypted session data, see adodb-cryptsession.inc.php. Enabling encryption
is simply a matter of including adodb-cryptsession.inc.php instead of adodb-session.inc.php.
@@ -49,110 +52,161 @@ is simply a matter of including adodb-cryptsession.inc.php instead of adodb-sess
Setup
There are 3 session management files that you can use:
-adodb-session.inc.php : The default
-adodb-session-clob.inc.php : Use this if you are storing DATA in clobs
-adodb-cryptsession.inc.php : Use this if you want to store encrypted session data in the database
+adodb-session.php : The default
+adodb-session-clob.php : Use this if you are storing DATA in clobs
+adodb-cryptsession.php : Use this if you want to store encrypted session data in the database
Examples
-
- GLOBAL $HTTP_SESSION_VARS;
- include('adodb.inc.php');
- include('adodb-session.php');
- session_start();
- session_register('AVAR');
- $HTTP_SESSION_VARS['AVAR'] += 1;
- print "\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}
";
-
+
+ include('adodb/adodb.inc.php');
+
+ $ADODB_SESSION_DRIVER='mysql';
+ $ADODB_SESSION_CONNECT='localhost';
+ $ADODB_SESSION_USER ='scott';
+ $ADODB_SESSION_PWD ='tiger';
+ $ADODB_SESSION_DB ='sessiondb';
+
+ include('adodb/session/adodb-session.php');
+ session_start();
+
+ #
+ # Test session vars, the following should increment on refresh
+ #
+ $_SESSION['AVAR'] += 1;
+ print "<p>\$_SESSION['AVAR']={$_SESSION['AVAR']}</p>";
+
To force non-persistent connections, call adodb_session_open first before session_start():
-
- GLOBAL $HTTP_SESSION_VARS;
- include('adodb.inc.php');
- include('adodb-session.php');
- adodb_sess_open(false,false,false);
- session_start();
- session_register('AVAR');
- $HTTP_SESSION_VARS['AVAR'] += 1;
- print "\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}
";
-
+
+ include('adodb/adodb.inc.php');
+
+ $ADODB_SESSION_DRIVER='mysql';
+ $ADODB_SESSION_CONNECT='localhost';
+ $ADODB_SESSION_USER ='scott';
+ $ADODB_SESSION_PWD ='tiger';
+ $ADODB_SESSION_DB ='sessiondb';
+
+ include('adodb/session/adodb-session.php');
+ adodb_sess_open(false,false,false);
+ session_start();
+
To use a encrypted sessions, simply replace the file:
-
- GLOBAL $HTTP_SESSION_VARS;
- include('adodb.inc.php');
- include('adodb-cryptsession.php');
- session_start();
-
-And the same technique for adodb-session-clob.inc.php:
-
- GLOBAL $HTTP_SESSION_VARS;
- include('adodb.inc.php');
- include('adodb-session-clob.php');
- session_start();
-
+
+ include('adodb/adodb.inc.php');
+
+ $ADODB_SESSION_DRIVER='mysql';
+ $ADODB_SESSION_CONNECT='localhost';
+ $ADODB_SESSION_USER ='scott';
+ $ADODB_SESSION_PWD ='tiger';
+ $ADODB_SESSION_DB ='sessiondb';
+
+ include('adodb/session/adodb-cryptsession.php');
+ session_start();
+
+And the same technique for adodb-session-clob.php:
+
+ include('adodb/adodb.inc.php');
+
+ $ADODB_SESSION_DRIVER='mysql';
+ $ADODB_SESSION_CONNECT='localhost';
+ $ADODB_SESSION_USER ='scott';
+ $ADODB_SESSION_PWD ='tiger';
+ $ADODB_SESSION_DB ='sessiondb';
+
+ include('adodb/session/adodb-session-clob.php');
+ session_start();
+
Installation
1. Create this table in your database (syntax might vary depending on your db):
-
+
create table sessions (
- SESSKEY char(32) not null,
- EXPIRY int(11) unsigned not null,
- EXPIREREF varchar(64),
- DATA text not null,
- primary key (sesskey)
- );
+ SESSKEY char(32) not null,
+ EXPIRY int(11) unsigned not null,
+ EXPIREREF varchar(64),
+ DATA text not null,
+ primary key (sesskey)
+ );
- For the adodb-session-clob.inc.php version, create this:
-
- create table sessions (
- SESSKEY char(32) not null,
- EXPIRY int(11) unsigned not null,
- EXPIREREF varchar(64),
- DATA CLOB,
- primary key (sesskey)
- );
+ For the adodb-session-clob.php version, create this:
+
+ create table sessions (
+ SESSKEY char(32) not null,
+ EXPIRY int(11) unsigned not null,
+ EXPIREREF varchar(64),
+ DATA CLOB,
+ primary key (sesskey)
+ );
2. Then define the following parameters. You can either modify
this file, or define them before this file is included:
-
- $ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
- $ADODB_SESSION_CONNECT='server to connect to';
- $ADODB_SESSION_USER ='user';
- $ADODB_SESSION_PWD ='password';
- $ADODB_SESSION_DB ='database';
- $ADODB_SESSION_TBL = 'sessions'
-
- 3. Recommended is PHP 4.0.6 or later. There are documented
- session bugs in earlier versions of PHP.
+
+ $ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
+ $ADODB_SESSION_CONNECT='server to connect to';
+ $ADODB_SESSION_USER ='user';
+ $ADODB_SESSION_PWD ='password';
+ $ADODB_SESSION_DB ='database';
+ $ADODB_SESSION_TBL = 'sessions'; # setting this is optional
+
+ When the session is created, $ADODB_SESS_CONN holds the connection object.
+
+ 3. Recommended is PHP 4.0.6 or later. There are documented session bugs
+ in earlier versions of PHP.
+
- Notifications
- If you want to receive notifications when a session expires, then
- you can tag a session with an EXPIREREF tag (see the definition of
- the sessions table above), and before the session record is deleted,
- we can call a function that will pass the contents of the EXPIREREF
- field as the first parameter, and the session key as the 2nd parameter.
-
- To do this, define a notification function, say NotifyFn:
-
- function NotifyFn($expireref, $sesskey)
- {
- }
-
- Then you need to define a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
- This is an array with 2 elements, the first being the name of the variable
+ Notifications
+If you want to receive notification when a session expires, then
+ tag the session record with a EXPIREREF tag (see the
+ definition of the sessions table above). Before any session record is deleted,
+ ADOdb will call a notification function, passing in the EXPIREREF.
+
+When a session is first created, we check a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
+ This is an array with 2 elements, the first being the name of the session variable
you would like to store in the EXPIREREF field, and the 2nd is the
notification function's name.
-
- In this example, we want to be notified when a user's session
- has expired, so we store the user id in the global variable $USERID,
- store this value in the EXPIREREF field:
-
- $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
-
- Then when the NotifyFn is called, we are passed the $USERID as the first
- parameter, eg. NotifyFn($userid, $sesskey).
-
- NOTE: When you want to change the EXPIREREF, you will need to modify a session
- variable to force a database record update because we checksum the session
- variables, and only perform the update when the checksum changes.
+
+ Suppose we want to be notified when a user's session
+ has expired, based on the userid. The user id in the global session variable $USERID.
+ The function name is 'NotifyFn'. So we define:
+
+ $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
+
+ And when the NotifyFn is called (when the session expires), we pass the $USERID
+ as the first parameter, eg. NotifyFn($userid, $sesskey). The session key (which is
+ the primary key of the record in the sessions table) is the 2nd parameter.
+
+ Here is an example of a Notification function that deletes some records in the database
+ and temporary files:
+
+ function NotifyFn($expireref, $sesskey)
+ {
+ global $ADODB_SESS_CONN; # the session connection object
+
+ $user = $ADODB_SESS_CONN->qstr($expireref);
+ $ADODB_SESS_CONN->Execute("delete from shopping_cart where user=$user");
+ system("rm /work/tmpfiles/$expireref/*");
+ }
+
+
+
+
+ NOTE: If you want to change the EXPIREREF after the session record has been
+ created, you will need to modify any session variable to force a database
+ record update.
+
Compression/Encryption Schemes
+Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and compression schemes are supported.
+ Currently, supported:
+
+ MD5Crypt (crypt.inc.php)
+ MCrypt
+ Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)
+ GZip
+ BZip2
+These are stackable. E.g.
+
+ADODB_Session::filter(new ADODB_Compress_Bzip2());
+ADODB_Session::filter(new ADODB_Encrypt_MD5());
+
+will compress and then encrypt the record in the database.
Also see the core ADOdb documentation.
diff --git a/lib/adodb/drivers/adodb-access.inc.php b/lib/adodb/drivers/adodb-access.inc.php
index e1078ee5d95..fca5a832857 100644
--- a/lib/adodb/drivers/adodb-access.inc.php
+++ b/lib/adodb/drivers/adodb-access.inc.php
@@ -1,6 +1,6 @@
fields[] = date('Y-m-d H:i:s',(integer)$f->value);
- break;
-
+ if (!strlen((string)$f->value)) $this->fields[] = false;
+ else $this->fields[] = adodb_date('Y-m-d H:i:s',(float)$f->value);
+ break;
case 133:// A date value (yyyymmdd)
- $val = $f->value;
- $this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
+ if ($val = $f->value) {
+ $this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
+ } else
+ $this->fields[] = false;
break;
case 7: // adDate
- $this->fields[] = date('Y-m-d',(integer)$f->value);
+ if (!strlen((string)$f->value)) $this->fields[] = false;
+ else $this->fields[] = adodb_date('Y-m-d',(float)$f->value);
break;
case 1: // null
$this->fields[] = false;
@@ -577,7 +583,25 @@ class ADORecordSet_ado extends ADORecordSet {
return true;
}
-
+ function NextRecordSet()
+ {
+ $rs = $this->_queryID;
+ $this->_queryID = $rs->NextRecordSet();
+ //$this->_queryID = $this->_QueryId->NextRecordSet();
+ if ($this->_queryID == null) return false;
+
+ $this->_currentRow = -1;
+ $this->_currentPage = -1;
+ $this->bind = false;
+ $this->fields = false;
+ $this->_flds = false;
+ $this->_tarr = false;
+
+ $this->_inited = false;
+ $this->Init();
+ return true;
+ }
+
function _close() {
$this->_flds = false;
@$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
diff --git a/lib/adodb/drivers/adodb-ado_access.inc.php b/lib/adodb/drivers/adodb-ado_access.inc.php
index 4cb590e79f7..946714defab 100644
--- a/lib/adodb/drivers/adodb-ado_access.inc.php
+++ b/lib/adodb/drivers/adodb-ado_access.inc.php
@@ -1,6 +1,6 @@
- // Only quote string types
if (gettype($v) == 'string')
$sql .= $this->qstr($v);
else if ($v === null)
diff --git a/lib/adodb/drivers/adodb-db2.inc.php b/lib/adodb/drivers/adodb-db2.inc.php
index be68a98f750..24f67020339 100644
--- a/lib/adodb/drivers/adodb-db2.inc.php
+++ b/lib/adodb/drivers/adodb-db2.inc.php
@@ -1,6 +1,6 @@
= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY ";
- return $this->Execute($sql,false);
+ $rs =& $this->Execute($sql,false);
} else {
if ($offset > 0 && $nrows < 0);
else {
$nrows += $offset;
$sql .= " FETCH FIRST $nrows ROWS ONLY ";
}
- return ADOConnection::SelectLimit($sql,-1,$offset);
+ $rs =& ADOConnection::SelectLimit($sql,-1,$offset);
}
+
+ return $rs;
}
};
diff --git a/lib/adodb/drivers/adodb-fbsql.inc.php b/lib/adodb/drivers/adodb-fbsql.inc.php
index 459a8533a73..46a4460db87 100644
--- a/lib/adodb/drivers/adodb-fbsql.inc.php
+++ b/lib/adodb/drivers/adodb-fbsql.inc.php
@@ -1,6 +1,6 @@
=0) ? "SKIP $offset " : '';
$sql = preg_replace('/^[ \t]*select/i',$str,$sql);
- return ($secs) ?
- $this->CacheExecute($secs,$sql,$inputarr)
- :
- $this->Execute($sql,$inputarr);
+ if ($secs)
+ $rs =& $this->CacheExecute($secs,$sql,$inputarr);
+ else
+ $rs =& $this->Execute($sql,$inputarr);
+
+ return $rs;
}
diff --git a/lib/adodb/drivers/adodb-ibase.inc.php b/lib/adodb/drivers/adodb-ibase.inc.php
index 6a44559fe64..d42b1d70892 100644
--- a/lib/adodb/drivers/adodb-ibase.inc.php
+++ b/lib/adodb/drivers/adodb-ibase.inc.php
@@ -1,6 +1,6 @@
fetchMode !== FALSE) {
+ $savem = $this->SetFetchMode(FALSE);
+ }
+ $table = strtoupper($table);
+ $sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
+ if (!$primary) {
+ $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
+ } else {
+ $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
+ }
+ // get index details
+ $rs = $this->Execute($sql);
+ if (!is_object($rs)) {
+ // restore fetchmode
+ if (isset($savem)) {
+ $this->SetFetchMode($savem);
+ }
+ $ADODB_FETCH_MODE = $save;
+ return FALSE;
+ }
+
+ $indexes = array ();
+ while ($row = $rs->FetchRow()) {
+ $index = $row[0];
+ if (!isset($indexes[$index])) {
+ if (is_null($row[3])) {$row[3] = 0;}
+ $indexes[$index] = array(
+ 'unique' => ($row[3] == 1),
+ 'columns' => array()
+ );
+ }
+ $sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$name."' ORDER BY RDB\$FIELD_POSITION ASC";
+ $rs1 = $this->Execute($sql);
+ while ($row1 = $rs1->FetchRow()) {
+ $indexes[$index]['columns'][$row1[2]] = $row1[1];
+ }
+ }
+ // restore fetchmode
+ if (isset($savem)) {
+ $this->SetFetchMode($savem);
+ }
+ $ADODB_FETCH_MODE = $save;
+
+ return $indexes;
+ }
+
+
// See http://community.borland.com/article/0,1410,25844,00.html
function RowLock($tables,$where,$col)
{
@@ -128,52 +184,7 @@ class ADODB_ibase extends ADOConnection {
return 1;
}
- /*// use delete and insert instead
- function Replace($table, $fieldArray, $keyCol,$autoQuote=false)
- {
- if (count($fieldArray) == 0) return 0;
-
- if (!is_array($keyCol)) {
- $keyCol = array($keyCol);
- }
-
- if ($autoQuote)
- foreach($fieldArray as $k => $v) {
- if (!is_numeric($v) and $v[0] != "'" and strcasecmp($v,'null')!=0) {
- $v = $this->qstr($v);
- $fieldArray[$k] = $v;
- }
- }
-
- $first = true;
- foreach ($keyCol as $v) {
- if ($first) {
- $first = false;
- $where = "$v=$fieldArray[$v]";
- } else {
- $where .= " and $v=$fieldArray[$v]";
- }
- }
-
- $first = true;
- foreach($fieldArray as $k => $v) {
- if ($first) {
- $first = false;
- $iCols = "$k";
- $iVals = "$v";
- } else {
- $iCols .= ",$k";
- $iVals .= ",$v";
- }
- }
- $this->BeginTrans();
- $this->Execute("DELETE FROM $table WHERE $where");
- $ok = $this->Execute("INSERT INTO $table ($iCols) VALUES ($iVals)");
- $this->CommitTrans();
-
- return ($ok) ? 2 : 0;
- }
- */
+
function CreateSequence($seqname,$startID=1)
{
$ok = $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
@@ -228,6 +239,7 @@ class ADODB_ibase extends ADOConnection {
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
+ if (!function_exists('ibase_pconnect')) return false;
if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
$this->_connectionID = ibase_connect($argHostname,$argUsername,$argPassword,$this->charSet,$this->buffers,$this->dialect);
if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
@@ -244,6 +256,7 @@ class ADODB_ibase extends ADOConnection {
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
+ if (!function_exists('ibase_pconnect')) return false;
if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
$this->_connectionID = ibase_pconnect($argHostname,$argUsername,$argPassword,$this->charSet,$this->buffers,$this->dialect);
if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
@@ -261,7 +274,7 @@ class ADODB_ibase extends ADOConnection {
function Prepare($sql)
{
// return $sql;
- $stmt = ibase_prepare($sql);
+ $stmt = ibase_prepare($this->_connectionID,$sql);
if (!$stmt) return false;
return array($sql,$stmt);
}
@@ -335,6 +348,101 @@ class ADODB_ibase extends ADOConnection {
return @ibase_close($this->_connectionID);
}
+ //OPN STUFF start
+ function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $isInterbase6)
+ {
+ $fscale = abs($fscale);
+ $fld->max_length = $flen;
+ $fld->scale = null;
+ switch($ftype){
+ case 7:
+ case 8:
+ if ($isInterbase6) {
+ switch($fsubtype){
+ case 0:
+ $fld->type = ($ftype == 7 ? 'smallint' : 'integer');
+ break;
+ case 1:
+ $fld->type = 'numeric';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ case 2:
+ $fld->type = 'decimal';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ } // switch
+ } else {
+ if ($fscale !=0) {
+ $fld->type = 'decimal';
+ $fld->scale = $fscale;
+ $fld->max_length = ($ftype == 7 ? 4 : 9);
+ } else {
+ $fld->type = ($ftype == 7 ? 'smallint' : 'integer');
+ }
+ }
+ break;
+ case 16:
+ if ($isInterbase6) {
+ switch($fsubtype){
+ case 0:
+ $fld->type = 'decimal';
+ $fld->max_length = 18;
+ $fld->scale = 0;
+ break;
+ case 1:
+ $fld->type = 'numeric';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ case 2:
+ $fld->type = 'decimal';
+ $fld->max_length = $fprecision;
+ $fld->scale = $fscale;
+ break;
+ } // switch
+ }
+ break;
+ case 10:
+ $fld->type = 'float';
+ break;
+ case 14:
+ $fld->type = 'char';
+ break;
+ case 27:
+ if ($fscale !=0) {
+ $fld->type = 'decimal';
+ $fld->max_length = 15;
+ $fld->scale = 5;
+ } else {
+ $fld->type = 'double';
+ }
+ break;
+ case 35:
+ if ($isInterbase6) {
+ $fld->type = 'timestamp';
+ } else {
+ $fld->type = 'date';
+ }
+ break;
+ case 12:
+ case 13:
+ $fld->type = 'date';
+ break;
+ case 37:
+ $fld->type = 'varchar';
+ break;
+ case 40:
+ $fld->type = 'cstring';
+ break;
+ case 261:
+ $fld->type = 'blob';
+ $fld->max_length = -1;
+ break;
+ } // switch
+ }
+ //OPN STUFF end
// returns array of ADOFieldObjects for current table
function &MetaColumns($table)
{
@@ -351,31 +459,41 @@ class ADODB_ibase extends ADOConnection {
if ($rs === false) return false;
$retarr = array();
+ //OPN STUFF start
+ $isInterbase6 = ($this->dialect==3 ? true : false);
+ //OPN STUFF end
while (!$rs->EOF) { //print_r($rs->fields);
$fld = new ADOFieldObject();
$fld->name = trim($rs->fields[0]);
- $tt = $rs->fields[1];
- switch($tt)
- {
- case 7:
- case 8:
- case 9:$tt = 'INTEGER'; break;
- case 10:
- case 27:
- case 11:$tt = 'FLOAT'; break;
- default:
- case 40:
- case 14:$tt = 'CHAR'; break;
- case 35:$tt = 'DATE'; break;
- case 37:$tt = 'VARCHAR'; break;
- case 261:$tt = 'BLOB'; break;
- case 14: $tt = 'TEXT'; break;
- case 13:
- case 35:$tt = 'TIMESTAMP'; break;
+ //OPN STUFF start
+ $this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $isInterbase6);
+ if (isset($rs->fields[1]) && $rs->fields[1]) {
+ $fld->not_null = true;
+ }
+ if (isset($rs->fields[2])) {
+
+ $fld->has_default = true;
+ $d = substr($rs->fields[2],strlen('default '));
+ switch ($fld->type)
+ {
+ case 'smallint':
+ case 'integer': $fld->default_value = (int) $d; break;
+ case 'char':
+ case 'blob':
+ case 'text':
+ case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
+ case 'double':
+ case 'float': $fld->default_value = (float) $d; break;
+ default: $fld->default_value = $d; break;
+ }
+ // case 35:$tt = 'TIMESTAMP'; break;
}
- $fld->type = $tt;
- $fld->max_length = $rs->fields[2];
-
+ if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
+ $fld->sub_type = $rs->fields[5];
+ } else {
+ $fld->sub_type = null;
+ }
+ //OPN STUFF end
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
@@ -517,6 +635,19 @@ class ADODB_ibase extends ADOConnection {
case 'd':
$s .= "(extract(day from $col))";
break;
+ case 'H':
+ case 'h':
+ $s .= "(extract(hour from $col))";
+ break;
+ case 'I':
+ case 'i':
+ $s .= "(extract(minute from $col))";
+ break;
+ case 'S':
+ case 's':
+ $s .= "CAST((extract(second from $col)) AS INTEGER)";
+ break;
+
default:
if ($ch == '\\') {
$i++;
@@ -593,7 +724,11 @@ class ADORecordset_ibase extends ADORecordSet
}
// OPN stuff start - optimized
// fix missing nulls and decode blobs automatically
-
+
+ global $ADODB_ANSI_PADDING_OFF;
+ //$ADODB_ANSI_PADDING_OFF=1;
+ $rtrim = !empty($ADODB_ANSI_PADDING_OFF);
+
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
if ($this->_cacheType[$i]=="BLOB") {
if (isset($f[$i])) {
@@ -604,7 +739,9 @@ class ADORecordset_ibase extends ADORecordSet
} else {
if (!isset($f[$i])) {
$f[$i] = null;
- }
+ } else if ($rtrim && is_string($f[$i])) {
+ $f[$i] = rtrim($f[$i]);
+ }
}
}
// OPN stuff end
diff --git a/lib/adodb/drivers/adodb-informix.inc.php b/lib/adodb/drivers/adodb-informix.inc.php
index 7f3ed4ac041..0473f950028 100644
--- a/lib/adodb/drivers/adodb-informix.inc.php
+++ b/lib/adodb/drivers/adodb-informix.inc.php
@@ -1,6 +1,6 @@
_connectionID = ifx_connect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -189,7 +196,10 @@ class ADODB_informix72 extends ADOConnection {
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
+ if (!function_exists('ifx_connect')) return false;
+
$dbs = $argDatabasename . "@" . $argHostname;
+ if ($argHostname) putenv("INFORMIXSERVER=$argHostname");
$this->_connectionID = ifx_pconnect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -225,10 +235,10 @@ class ADODB_informix72 extends ADOConnection {
// to be able to call "move", or "movefirst" statements
if (!$ADODB_COUNTRECS && preg_match("/^\s*select/is", $sql)) {
if ($inputarr) {
- $this->lastQuery = ifx_query($sql,$this->_connectionID, IFX_SCROLL, $tab);
+ $this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType, $tab);
}
else {
- $this->lastQuery = ifx_query($sql,$this->_connectionID, IFX_SCROLL);
+ $this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType);
}
}
else {
diff --git a/lib/adodb/drivers/adodb-mssql.inc.php b/lib/adodb/drivers/adodb-mssql.inc.php
index 69fa7d4fb8f..7a0247b6499 100644
--- a/lib/adodb/drivers/adodb-mssql.inc.php
+++ b/lib/adodb/drivers/adodb-mssql.inc.php
@@ -1,6 +1,6 @@
'master'";
@@ -100,6 +101,7 @@ class ADODB_mssql extends ADOConnection {
var $uniqueOrderBy = true;
var $_bindInputArray = true;
+
function ADODB_mssql()
{
$this->_has_mssql_init = (strnatcmp(PHP_VERSION,'4.1.0')>=0);
@@ -197,11 +199,14 @@ class ADODB_mssql extends ADOConnection {
if ($nrows > 0 && $offset <= 0) {
$sql = preg_replace(
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
- return $this->Execute($sql,$inputarr);
+ $rs =& $this->Execute($sql,$inputarr);
} else
- return ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+
+ return $rs;
}
+
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
@@ -430,6 +435,7 @@ order by constraint_name, referenced_table_name, keyno";
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
+ if (!function_exists('mssql_pconnect')) return false;
$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -440,6 +446,7 @@ order by constraint_name, referenced_table_name, keyno";
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
+ if (!function_exists('mssql_pconnect')) return false;
$this->_connectionID = mssql_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
@@ -511,7 +518,9 @@ order by constraint_name, referenced_table_name, keyno";
}
if ($this->debug) {
- ADOConnection::outp( "Parameter(\$stmt, \$php_var='$var', \$name='$name'); (type=$type)");
+ $prefix = ($isOutput) ? 'Out' : 'In';
+ $ztype = (empty($type)) ? 'false' : $type;
+ ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
}
/*
See http://phplens.com/lens/lensforum/msgs.php?id=7231
diff --git a/lib/adodb/drivers/adodb-mssqlpo.inc.php b/lib/adodb/drivers/adodb-mssqlpo.inc.php
index 747abdd95c8..d727def5fe0 100644
--- a/lib/adodb/drivers/adodb-mssqlpo.inc.php
+++ b/lib/adodb/drivers/adodb-mssqlpo.inc.php
@@ -1,6 +1,6 @@
GetOne("select version()");
+ $arr['description'] = ADOConnection::GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
@@ -69,6 +68,59 @@ class ADODB_mysql extends ADOConnection {
return $ret;
}
+
+ function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+ {
+ // save old fetch mode
+ global $ADODB_FETCH_MODE;
+
+ $save = $ADODB_FETCH_MODE;
+ $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+ if ($this->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;
+ }
+
+
// if magic quotes disabled, use mysql_real_escape_string()
function qstr($s,$magic_quotes=false)
{
@@ -128,14 +180,19 @@ class ADODB_mysql extends ADOConnection {
return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
}
+
function GenID($seqname='adodbseq',$startID=1)
{
// post-nuke sets hasGenID to false
if (!$this->hasGenID) return false;
+ $savelog = $this->_logsql;
+ $this->_logsql = false;
$getnext = sprintf($this->_genIDSQL,$seqname);
+ $holdtransOK = $this->_transOK; // save the current status
$rs = @$this->Execute($getnext);
if (!$rs) {
+ if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
$u = strtoupper($seqname);
$this->Execute(sprintf($this->_genSeqSQL,$seqname));
$this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
@@ -145,6 +202,7 @@ class ADODB_mysql extends ADOConnection {
if ($rs) $rs->Close();
+ $this->_logsql = $savelog;
return $this->genID;
}
@@ -240,14 +298,6 @@ class ADODB_mysql extends ADOConnection {
{
$s = "";
$arr = func_get_args();
- $first = true;
- /*
- foreach($arr as $a) {
- if ($first) {
- $s = $a;
- $first = false;
- } else $s .= ','.$a;
- }*/
// suggestion by andrew005@mnogo.ru
$s = implode(',',$arr);
@@ -320,6 +370,21 @@ class ADODB_mysql extends ADOConnection {
$fld->name = $rs->fields[0];
$type = $rs->fields[1];
+
+ // split type into type(length):
+ $fld->scale = null;
+ if (strpos($type,',') && preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
+ $fld->type = $query_array[1];
+ $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
+ $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
+ } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
+ $fld->type = $query_array[1];
+ $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
+ } else {
+ $fld->max_length = -1;
+ $fld->type = $type;
+ }
+ /*
// split type into type(length):
if (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
$fld->type = $query_array[1];
@@ -327,11 +392,12 @@ class ADODB_mysql extends ADOConnection {
} else {
$fld->max_length = -1;
$fld->type = $type;
- }
+ }*/
$fld->not_null = ($rs->fields[2] != 'YES');
$fld->primary_key = ($rs->fields[3] == 'PRI');
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
$fld->binary = (strpos($fld->type,'blob') !== false);
+
if (!$fld->binary) {
$d = $rs->fields[4];
if ($d != "" && $d != "NULL") {
@@ -366,9 +432,11 @@ class ADODB_mysql extends ADOConnection {
{
$offsetStr =($offset>=0) ? "$offset," : '';
- return ($secs) ? $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr)
- : $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
-
+ if ($secs)
+ $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
+ else
+ $rs =& $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
+ return $rs;
}
@@ -484,7 +552,8 @@ class ADORecordSet_mysql extends ADORecordSet{
function &GetRowAssoc($upper=true)
{
if ($this->fetchMode == MYSQL_ASSOC && !$upper) return $this->fields;
- return ADORecordSet::GetRowAssoc($upper);
+ $row =& ADORecordSet::GetRowAssoc($upper);
+ return $row;
}
/* Use associative array to get fields array */
@@ -575,6 +644,7 @@ class ADORecordSet_mysql extends ADORecordSet{
case 'BLOB':
case 'MEDIUMBLOB':
return !empty($fieldobj->binary) ? 'B' : 'X';
+
case 'YEAR':
case 'DATE': return 'D';
diff --git a/lib/adodb/drivers/adodb-mysqli.inc.php b/lib/adodb/drivers/adodb-mysqli.inc.php
new file mode 100644
index 00000000000..a9daa02e482
--- /dev/null
+++ b/lib/adodb/drivers/adodb-mysqli.inc.php
@@ -0,0 +1,828 @@
+GetOne("select version()");
+ $arr['version'] = ADOConnection::_findvers($arr['description']);
+ return $arr;
+ }
+
+
+ function BeginTrans()
+ {
+ if ($this->transOff) return true;
+ $this->transCnt += 1;
+ $this->Execute('SET AUTOCOMMIT=0');
+ $this->Execute('BEGIN');
+ return true;
+ }
+
+ function CommitTrans($ok=true)
+ {
+ if ($this->transOff) return true;
+ if (!$ok) return $this->RollbackTrans();
+
+ if ($this->transCnt) $this->transCnt -= 1;
+ $this->Execute('COMMIT');
+ $this->Execute('SET AUTOCOMMIT=1');
+ return true;
+ }
+
+ function RollbackTrans()
+ {
+ if ($this->transOff) return true;
+ if ($this->transCnt) $this->transCnt -= 1;
+ $this->Execute('ROLLBACK');
+ $this->Execute('SET AUTOCOMMIT=1');
+ return true;
+ }
+
+ // if magic quotes disabled, use mysql_real_escape_string()
+ // From readme.htm:
+ // Quotes a string to be sent to the database. The $magic_quotes_enabled
+ // parameter may look funny, but the idea is if you are quoting a
+ // string extracted from a POST/GET variable, then
+ // pass get_magic_quotes_gpc() as the second parameter. This will
+ // ensure that the variable is not quoted twice, once by qstr and once
+ // by the magic_quotes_gpc.
+ //
+ //Eg. $s = $db->qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());
+ function qstr($s, $magic_quotes = false)
+ {
+ if (!$magic_quotes) {
+ if (ADODB_PHPVER >= 0x5000) {
+ // $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
+ return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";
+ }
+ else
+ {
+ trigger_error("phpver < 5 not implemented", E_USER_ERROR);
+ }
+
+ if ($this->replaceQuote[0] == '\\')
+ {
+ $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
+ }
+ return "'".str_replace("'",$this->replaceQuote,$s)."'";
+ }
+ // undo magic quotes for "
+ $s = str_replace('\\"','"',$s);
+ return "'$s'";
+ }
+
+ function _insertid()
+ {
+// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
+ $result = @mysqli_insert_id($this->_connectionID);
+ if ($result == -1){
+ if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg());
+ }
+ return $result;
+ }
+
+ // Only works for INSERT, UPDATE and DELETE query's
+ function _affectedrows()
+ {
+ // $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
+ $result = @mysqli_affected_rows($this->_connectionID);
+ if ($result == -1) {
+ if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg());
+ }
+ return $result;
+ }
+
+ // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
+ // Reference on Last_Insert_ID on the recommended way to simulate sequences
+ var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
+ var $_genSeqSQL = "create table %s (id int not null)";
+ var $_genSeq2SQL = "insert into %s values (%s)";
+ var $_dropSeqSQL = "drop table %s";
+
+ function CreateSequence($seqname='adodbseq',$startID=1)
+ {
+ if (empty($this->_genSeqSQL)) return false;
+ $u = strtoupper($seqname);
+
+ $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
+ if (!$ok) return false;
+ return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
+ }
+
+ function GenID($seqname='adodbseq',$startID=1)
+ {
+ // post-nuke sets hasGenID to false
+ if (!$this->hasGenID) return false;
+
+ $getnext = sprintf($this->_genIDSQL,$seqname);
+ $holdtransOK = $this->_transOK; // save the current status
+ $rs = @$this->Execute($getnext);
+ if (!$rs) {
+ if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
+ $u = strtoupper($seqname);
+ $this->Execute(sprintf($this->_genSeqSQL,$seqname));
+ $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
+ $rs = $this->Execute($getnext);
+ }
+ $this->genID = mysqli_insert_id($this->_connectionID);
+
+ if ($rs) $rs->Close();
+
+ return $this->genID;
+ }
+
+ function &MetaDatabases()
+ {
+ $query = "SHOW DATABASES";
+ $ret =& $this->Execute($query);
+ return $ret;
+ }
+
+
+ function &MetaIndexes ($table, $primary = FALSE)
+ {
+ // save old fetch mode
+ global $ADODB_FETCH_MODE;
+
+ $save = $ADODB_FETCH_MODE;
+ $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+ if ($this->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;
+ }
+
+
+ // 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;
+ $s = 'DATE_FORMAT('.$col.",'";
+ $concat = false;
+ $len = strlen($fmt);
+ for ($i=0; $i < $len; $i++) {
+ $ch = $fmt[$i];
+ switch($ch) {
+ case 'Y':
+ case 'y':
+ $s .= '%Y';
+ break;
+ case 'Q':
+ case 'q':
+ $s .= "'),Quarter($col)";
+
+ if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
+ else $s .= ",('";
+ $concat = true;
+ break;
+ case 'M':
+ $s .= '%b';
+ break;
+
+ case 'm':
+ $s .= '%m';
+ break;
+ case 'D':
+ case 'd':
+ $s .= '%d';
+ break;
+
+ case 'H':
+ $s .= '%H';
+ break;
+
+ case 'h':
+ $s .= '%I';
+ break;
+
+ case 'i':
+ $s .= '%i';
+ break;
+
+ case 's':
+ $s .= '%s';
+ break;
+
+ case 'a':
+ case 'A':
+ $s .= '%p';
+ break;
+
+ default:
+
+ if ($ch == '\\') {
+ $i++;
+ $ch = substr($fmt,$i,1);
+ }
+ $s .= $ch;
+ break;
+ }
+ }
+ $s.="')";
+ if ($concat) $s = "CONCAT($s)";
+ return $s;
+ }
+
+ // returns concatenated string
+ // much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
+ function Concat()
+ {
+ $s = "";
+ $arr = func_get_args();
+
+ // suggestion by andrew005@mnogo.ru
+ $s = implode(',',$arr);
+ if (strlen($s) > 0) return "CONCAT($s)";
+ else return '';
+ }
+
+ // dayFraction is a day in floating point
+ function OffsetDate($dayFraction,$date=false)
+ {
+ if (!$date)
+ $date = $this->sysDate;
+ return "from_unixtime(unix_timestamp($date)+($dayFraction)*24*3600)";
+ }
+
+ // returns true or false
+ // To add: parameter int $port,
+ // parameter string $socket
+ function _connect($argHostname = NULL,
+ $argUsername = NULL,
+ $argPassword = NULL,
+ $argDatabasename = NULL)
+ {
+ // @ means: error surpression on
+ $this->_connectionID = @mysqli_init();
+
+ if (is_null($this->_connectionID))
+ {
+ // mysqli_init only fails if insufficient memory
+ if ($this->debug)
+ ADOConnection::outp("mysqli_init() failed : " . $this->ErrorMsg());
+ return false;
+ }
+ // Set connection options
+ // Not implemented now
+ // mysqli_options($this->_connection,,);
+ if (mysqli_real_connect($this->_connectionID,
+ $argHostname,
+ $argUsername,
+ $argPassword,
+ $argDatabasename))
+ {
+ if ($argDatabasename)
+ {
+ return $this->SelectDB($argDatabasename);
+ }
+
+ return true;
+ }
+ else
+ {
+ if ($this->debug)
+ ADOConnection::outp("Could't connect : " . $this->ErrorMsg());
+ return false;
+ }
+ }
+
+ // returns true or false
+ // How to force a persistent connection
+ function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
+ {
+ // not implemented in mysqli (yet)?
+ $this->_connectionID = mysqli_connect($argHostname,
+ $argUsername,
+ $argPassword,
+ $argDatabasename);
+ if ($this->_connectionID === false) return false;
+ // if ($this->autoRollback) $this->RollbackTrans();
+ if ($argDatabasename) return $this->SelectDB($argDatabasename);
+ return true;
+ }
+
+ // When is this used? Close old connection first?
+ // In _connect(), check $this->forceNewConnect?
+ function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
+ {
+ $this->forceNewConnect = true;
+ $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
+ }
+
+ function &MetaColumns($table)
+ {
+ if ($this->metaColumnsSQL) {
+ global $ADODB_FETCH_MODE;
+ $save = $ADODB_FETCH_MODE;
+ $rs = false;
+ switch($ADODB_FETCH_MODE)
+ {
+ case ADODB_FETCH_NUM:
+ $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+ $rs = $this->Execute(sprintf($this->metaColumnsSQL,
+ $table));
+
+ $ADODB_FETCH_MODE = $save;
+ if ($rs === false) break;
+ $retarr = array();
+ while (!$rs->EOF){
+ $fld = new ADOFieldObject();
+ $fld->name = $rs->fields[0];
+ $fld->type = $rs->fields[1];
+ // split type into type(length):
+ if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array))
+ {
+ $fld->type = $query_array[1];
+ $fld->max_length = $query_array[2];
+ }
+ else
+ {
+ $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);
+ $fld->binary = (strpos($fld->type,'blob') !== false);
+ if (!$fld->binary)
+ {
+ $d = $rs->fields[4];
+ $d = $rs->fields['Default'];
+ if ($d != "" && $d != "NULL")
+ {
+ $fld->has_default = true;
+ $fld->default_value = $d;
+ }
+ else
+ {
+ $fld->has_default = false;
+ }
+ }
+ $retarr[strtoupper($fld->name)] = $fld;
+ $rs->MoveNext();
+ }
+ break;
+ case ADODB_FETCH_ASSOC:
+ case ADODB_FETCH_DEFAULT:
+ case ADODB_FETCH_BOTH:
+ $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
+ $rs = $this->Execute(sprintf($this->metaColumnsSQL,
+ $table));
+ $ADODB_FETCH_MODE = $save;
+ if ($rs === false) break;
+ $retarr = array();
+ while (!$rs->EOF){
+ $fld = new ADOFieldObject();
+ $fld->name = $rs->fields['Field'];
+ $fld->type = $rs->fields['Type'];
+
+ // split type into type(length):
+ if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array))
+ {
+ $fld->type = $query_array[1];
+ $fld->max_length = $query_array[2];
+ }
+ else
+ {
+ $fld->max_length = -1;
+ }
+ $fld->not_null = ($rs->fields['Null'] != 'YES');
+ $fld->primary_key = ($rs->fields['Key'] == 'PRI');
+ $fld->auto_increment = (strpos($rs->fields['Extra'], 'auto_increment') !== false);
+ $fld->binary = (strpos($fld->type,'blob') !== false);
+ if (!$fld->binary)
+ {
+ $d = $rs->fields['Default'];
+ if ($d != "" && $d != "NULL")
+ {
+ $fld->has_default = true;
+ $fld->default_value = $d;
+ }
+ else
+ {
+ $fld->has_default = false;
+ }
+ }
+ $retarr[strtoupper($fld->name)] = $fld;
+ $rs->MoveNext();
+ }
+ break;
+ default:
+ }
+
+ if ($rs === false) return false;
+ $rs->Close();
+ return $retarr;
+ }
+ return false;
+ }
+
+ // returns true or false
+ function SelectDB($dbName)
+ {
+// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
+ $this->databaseName = $dbName;
+ if ($this->_connectionID) {
+ $result = @mysqli_select_db($this->_connectionID, $dbName);
+ if (!$result) {
+ ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
+ }
+ return $result;
+ }
+ return false;
+ }
+
+ // parameters use PostgreSQL convention, not MySQL
+ function &SelectLimit($sql,
+ $nrows = -1,
+ $offset = -1,
+ $inputarr = false,
+ $arg3 = false,
+ $secs = 0)
+ {
+ $offsetStr = ($offset >= 0) ? "$offset," : '';
+
+ if ($secs)
+ $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
+ else
+ $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
+
+ return $rs;
+ }
+
+
+ function Prepare($sql)
+ {
+ return $sql;
+
+ $stmt = mysqli_prepare($this->_connectionID,$sql);
+ if (!$stmt) return false;
+ return array($sql,$stmt);
+ }
+
+
+ // returns queryID or false
+ function _query($sql, $inputarr)
+ {
+ global $ADODB_COUNTRECS;
+
+ if (is_array($sql)) {
+ $stmt = $sql[1];
+ foreach($inputarr as $k => $v) {
+ if (is_string($v)) $a[] = MYSQLI_BIND_STRING;
+ else if (is_integer($v)) $a[] = MYSQLI_BIND_INT;
+ else $a[] = MYSQLI_BIND_DOUBLE;
+
+ $fnarr =& array_merge( array($stmt,$a) , $inputarr);
+ $ret = call_user_func_array('mysqli_bind_param',$fnarr);
+ }
+ $ret = mysqli_execute($stmt);
+ return $ret;
+ }
+ if (!$mysql_res = mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
+ if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
+ return false;
+ }
+
+ return $mysql_res;
+ }
+
+ /* Returns: the last error message from previous database operation */
+ function ErrorMsg()
+ {
+ if (empty($this->_connectionID))
+ $this->_errorMsg = @mysqli_error();
+ else
+ $this->_errorMsg = @mysqli_error($this->_connectionID);
+ return $this->_errorMsg;
+ }
+
+ /* Returns: the last error number from previous database operation */
+ function ErrorNo()
+ {
+ if (empty($this->_connectionID))
+ return @mysqli_errno();
+ else
+ return @mysqli_errno($this->_connectionID);
+ }
+
+ // returns true or false
+ function _close()
+ {
+ @mysqli_close($this->_connectionID);
+ $this->_connectionID = false;
+ }
+
+ /*
+ * Maximum size of C field
+ */
+ function CharMax()
+ {
+ return 255;
+ }
+
+ /*
+ * Maximum size of X field
+ */
+ function TextMax()
+ {
+ return 4294967295;
+ }
+
+
+}
+
+/*--------------------------------------------------------------------------------------
+ Class Name: Recordset
+--------------------------------------------------------------------------------------*/
+
+class ADORecordSet_mysqli extends ADORecordSet{
+
+ var $databaseType = "mysqli";
+ var $canSeek = true;
+
+ function ADORecordSet_mysqli($queryID, $mode = false)
+ {
+ if ($mode === false)
+ {
+ global $ADODB_FETCH_MODE;
+ $mode = $ADODB_FETCH_MODE;
+ }
+ switch ($mode)
+ {
+ case ADODB_FETCH_NUM:
+ $this->fetchMode = MYSQLI_NUM;
+ break;
+ case ADODB_FETCH_ASSOC:
+ $this->fetchMode = MYSQLI_ASSOC;
+ break;
+ case ADODB_FETCH_DEFAULT:
+ case ADODB_FETCH_BOTH:
+ default:
+ $this->fetchMode = MYSQLI_ASSOC;
+ break;
+ }
+ $this->ADORecordSet($queryID);
+ }
+
+ function _initrs()
+ {
+ // mysqli_num_rows only return correct number, depens
+ // on the use of mysql_store_result and mysql_use_result
+ if (!$this->Connection->executeOnly) {
+ $this->_numOfRows = @mysqli_num_rows($this->_queryID);
+ $this->_numOfFields = @mysqli_num_fields($this->_queryID);
+ }
+ else {
+ $this->_numOfRows = 0;
+ $this->_numOfFields = 0;
+ }
+ }
+
+ function &FetchField($fieldOffset = -1)
+ {
+ $fieldnr = $fieldOffset;
+ if ($fieldOffset != -1) {
+ $fieldOffset = mysqi_field_seek($this->_queryID, $fieldnr);
+ }
+ $o = mysqli_fetch_field($this->_queryID);
+ return $o;
+ }
+
+ function &GetRowAssoc($upper = true)
+ {
+ if ($this->fetchMode == MYSQLI_ASSOC && !$upper)
+ return $this->fields;
+ $row =& ADORecordSet::GetRowAssoc($upper);
+ return $row;
+ }
+
+ /* Use associative array to get fields array */
+ function Fields($colname)
+ {
+ if ($this->fetchMode != MYSQLI_NUM)
+ return @$this->fields[$colname];
+
+ if (!$this->bind) {
+ $this->bind = array();
+ for ($i = 0; $i < $this->_numOfFields; $i++) {
+ $o = $this->FetchField($i);
+ $this->bind[strtoupper($o->name)] = $i;
+ }
+ }
+ return $this->fields[$this->bind[strtoupper($colname)]];
+ }
+
+ function _seek($row)
+ {
+ if ($this->_numOfRows == 0)
+ return false;
+
+ if ($row < 0)
+ return false;
+
+ mysqli_data_seek($this->_queryID, $row);
+ $this->EOF = false;
+ return true;
+ }
+
+ // 10% speedup to move MoveNext to child class
+ // This is the only implementation that works now (23-10-2003).
+ // Other functions return no or the wrong results.
+ function MoveNext()
+ {
+ if ($this->EOF)
+ return false;
+ $this->_currentRow++;
+ switch($this->fetchMode)
+ {
+ case MYSQLI_NUM:
+ $this->fields = mysqli_fetch_array($this->_queryID);
+ break;
+ case MYSQLI_ASSOC:
+ case MYSQLI_BOTH:
+ $this->fields = mysqli_fetch_assoc($this->_queryID);
+ break;
+ default:
+ }
+ if (is_array($this->fields))
+ return true;
+ $this->EOF = true;
+ return false;
+ }
+
+ function _fetch()
+ {
+ // mysqli_fetch_array($this->_queryID, MYSQLI_NUM) does not
+ // work (22-10-2003). But mysqli_fetch_array($this->_queryID) gives
+ // int resulttype should default to MYSQLI_BOTH,but give MYSQLI_NUM.
+
+ // $this->fields = mysqli_fetch_fields($this->_queryID);
+ // $this->fields = mysqli_fetch_array($this->_queryID); //, $this->fetchMode);
+
+ $this->fields = mysqli_fetch_assoc($this->_queryID); // $this->fetchMode);
+ return is_array($this->fields);
+ }
+
+ function _close()
+ {
+ mysqli_free_result($this->_queryID);
+ $this->_queryID = false;
+ }
+
+ function MetaType($t, $len = -1, $fieldobj = false)
+ {
+ if (is_object($t))
+ {
+ $fieldobj = $t;
+ $t = $fieldobj->type;
+ $len = $fieldobj->max_length;
+ }
+
+ $len = -1; // mysql max_length is not accurate
+ switch (strtoupper($t)) {
+ case 'STRING':
+ case 'CHAR':
+ case 'VARCHAR':
+ case 'TINYBLOB':
+ case 'TINYTEXT':
+ case 'ENUM':
+ case 'SET':
+ if ($len <= $this->blobSize) return 'C';
+
+ case 'TEXT':
+ case 'LONGTEXT':
+ case 'MEDIUMTEXT':
+ return 'X';
+
+ // php_mysql extension always returns 'blob' even if 'text'
+ // so we have to check whether binary...
+ case 'IMAGE':
+ case 'LONGBLOB':
+ case 'BLOB':
+ case 'MEDIUMBLOB':
+ return !empty($fieldobj->binary) ? 'B' : 'X';
+ case 'YEAR':
+ case 'DATE':
+ return 'D';
+
+ case 'TIME':
+ case 'DATETIME':
+ case 'TIMESTAMP': return 'T';
+
+ case 'INT':
+ case 'INTEGER':
+ case 'BIGINT':
+ case 'TINYINT':
+ case 'MEDIUMINT':
+ case 'SMALLINT':
+
+ if (!empty($fieldobj->primary_key)) return 'R';
+ else return 'I';
+ // Added floating-point types
+ // Maybe not necessery.
+ case 'FLOAT':
+ case 'DOUBLE':
+ // case 'DOUBLE PRECISION':
+ case 'DECIMAL':
+ case 'DEC':
+ case 'FIXED':
+ default:
+ return 'N';
+ }
+ }
+
+
+}
+
+}
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/drivers/adodb-mysqlt.inc.php b/lib/adodb/drivers/adodb-mysqlt.inc.php
index 2c3dc95b5e3..8b82ea50ba7 100644
--- a/lib/adodb/drivers/adodb-mysqlt.inc.php
+++ b/lib/adodb/drivers/adodb-mysqlt.inc.php
@@ -1,7 +1,7 @@
_errorMsg = false;
$this->_errorCode = false;
@@ -207,6 +208,8 @@ NATSOFT.DOMAIN =
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,1);
}
+
+
// returns true or false
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
@@ -438,7 +441,9 @@ NATSOFT.DOMAIN =
}
// note that $nrows = 0 still has to work ==> no rows returned
- return ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ return $rs;
+
} else {
// Algorithm by Tomas V V Cox, from PEAR DB oci8.php
@@ -449,8 +454,7 @@ NATSOFT.DOMAIN =
}
if (is_array($inputarr)) {
- reset($inputarr);
- while (list($k,$v) = each($inputarr)) {
+ foreach($inputarr as $k => $v) {
if (is_array($v)) {
if (sizeof($v) == 2) // suggested by g.giunta@libero.
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
@@ -498,8 +502,9 @@ NATSOFT.DOMAIN =
$inputarr['adodb_nrows'] = $nrows;
$inputarr['adodb_offset'] = $offset;
- if ($secs2cache>0) return $this->CacheExecute($secs2cache, $sql,$inputarr);
- else return $this->Execute($sql,$inputarr);
+ if ($secs2cache>0) $rs =& $this->CacheExecute($secs2cache, $sql,$inputarr);
+ else $rs =& $this->Execute($sql,$inputarr);
+ return $rs;
}
}
@@ -589,7 +594,7 @@ NATSOFT.DOMAIN =
$stmt = $this->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
*/
- function Prepare($sql)
+ function Prepare($sql,$cursor=false)
{
static $BINDNUM = 0;
@@ -600,7 +605,7 @@ NATSOFT.DOMAIN =
$BINDNUM += 1;
if (@OCIStatementType($stmt) == 'BEGIN') {
- return array($sql,$stmt,0,$BINDNUM,OCINewCursor($this->_connectionID));
+ return array($sql,$stmt,0,$BINDNUM, ($cursor) ? false : OCINewCursor($this->_connectionID));
}
return array($sql,$stmt,0,$BINDNUM);
@@ -623,13 +628,12 @@ NATSOFT.DOMAIN =
*/
function &ExecuteCursor($sql,$cursorName='rs',$params=false)
{
- $stmt = ADODB_oci8::Prepare($sql);
+ $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate OCINewCursor
if (is_array($stmt) && sizeof($stmt) >= 5) {
$this->Parameter($stmt, $ignoreCur, $cursorName, false, -1, OCI_B_CURSOR);
if ($params) {
- reset($params);
- while (list($k,$v) = each($params)) {
+ foreach($params as $k => $v) {
$this->Parameter($stmt,$params[$k], $k);
}
}
@@ -711,7 +715,9 @@ NATSOFT.DOMAIN =
function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false)
{
if ($this->debug) {
- ADOConnection::outp( "Parameter(\$stmt, \$php_var='$var', \$name='$name');");
+ $prefix = ($isOutput) ? 'Out' : 'In';
+ $ztype = (empty($type)) ? 'false' : $type;
+ ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
}
return $this->Bind($stmt,$var,$maxLen,$type,$name);
}
@@ -747,8 +753,7 @@ NATSOFT.DOMAIN =
} else {
// one statement to bind them all
$bindarr = array();
- reset($inputarr);
- while(list($k,$v) = each($inputarr)) {
+ foreach($inputarr as $k => $v) {
$bindarr[$k] = $v;
OCIBindByName($stmt,":$k",$bindarr[$k],4000);
}
@@ -765,8 +770,7 @@ NATSOFT.DOMAIN =
if (defined('ADODB_PREFETCH_ROWS')) @OCISetPrefetch($stmt,ADODB_PREFETCH_ROWS);
if (is_array($inputarr)) {
- reset($inputarr);
- while(list($k,$v) = each($inputarr)) {
+ foreach($inputarr as $k => $v) {
if (is_array($v)) {
if (sizeof($v) == 2) // suggested by g.giunta@libero.
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1]);
@@ -795,17 +799,17 @@ NATSOFT.DOMAIN =
return $stmt;
case "BEGIN":
- if (is_array($sql) && isset($sql[4])) {
+ if (is_array($sql) && !empty($sql[4])) {
$cursor = $sql[4];
if (is_resource($cursor)) {
- OCIExecute($cursor);
+ $ok = OCIExecute($cursor);
return $cursor;
}
return $stmt;
} else {
if (is_resource($stmt)) {
- OCIFreeStatement($stmt);
- return true;
+ OCIFreeStatement($stmt);
+ return true;
}
return $stmt;
}
@@ -984,10 +988,10 @@ class ADORecordset_oci8 extends ADORecordSet {
$this->_inited = true;
if ($this->_queryID) {
-
+
$this->_currentRow = 0;
@$this->_initrs();
- $this->EOF = !$this->_fetch();
+ $this->EOF = !$this->_fetch();
/*
// based on idea by Gaetano Giunta to detect unusual oracle errors
@@ -1065,7 +1069,10 @@ class ADORecordset_oci8 extends ADORecordSet {
/* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
function &GetArrayLimit($nrows,$offset=-1)
{
- if ($offset <= 0) return $this->GetArray($nrows);
+ if ($offset <= 0) {
+ $arr =& $this->GetArray($nrows);
+ return $arr;
+ }
for ($i=1; $i < $offset; $i++)
if (!@OCIFetch($this->_queryID)) return array();
@@ -1139,7 +1146,7 @@ class ADORecordset_oci8 extends ADORecordSet {
case 'NCLOB':
case 'LONG':
case 'LONG VARCHAR':
- case 'CLOB';
+ case 'CLOB':
return 'X';
case 'LONG RAW':
diff --git a/lib/adodb/drivers/adodb-oci805.inc.php b/lib/adodb/drivers/adodb-oci805.inc.php
index 704de4175ce..4dde2b363b8 100644
--- a/lib/adodb/drivers/adodb-oci805.inc.php
+++ b/lib/adodb/drivers/adodb-oci805.inc.php
@@ -1,6 +1,6 @@
EOF) {
$this->_currentRow++;
if(@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
+ global $ADODB_ANSI_PADDING_OFF;
+
if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
+ if (!empty($ADODB_ANSI_PADDING_OFF)) {
+ foreach($this->fields as $k => $v) {
+ if (is_string($v)) $this->fields[$k] = rtrim($v);
+ }
+ }
return true;
}
$this->EOF = true;
@@ -150,7 +158,7 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
$arr = array();
$lowercase = (ADODB_ASSOC_CASE == 0);
- foreach ($this->fields as $k => $v) {
+ foreach($this->fields as $k => $v) {
if (is_integer($k)) $arr[$k] = $v;
else {
if ($lowercase)
@@ -166,7 +174,14 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
{
$ret = @OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
if ($ret) {
- if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
+ global $ADODB_ANSI_PADDING_OFF;
+
+ if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
+ if (!empty($ADODB_ANSI_PADDING_OFF)) {
+ foreach($this->fields as $k => $v) {
+ if (is_string($v)) $this->fields[$k] = rtrim($v);
+ }
+ }
}
return $ret;
}
diff --git a/lib/adodb/drivers/adodb-odbc.inc.php b/lib/adodb/drivers/adodb-odbc.inc.php
index b9b8ac01f53..aff3efa390f 100644
--- a/lib/adodb/drivers/adodb-odbc.inc.php
+++ b/lib/adodb/drivers/adodb-odbc.inc.php
@@ -1,6 +1,6 @@
debug && $argDatabasename) {
ADOConnection::outp("For odbc Connect(), $argDatabasename is not used. Place dsn in 1st parameter.");
}
@@ -173,6 +176,9 @@ class ADODB_odbc extends ADOConnection {
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
+
+ if (!function_exists('odbc_connect')) return false;
+
$php_errormsg = '';
if ($this->debug && $argDatabasename) {
ADOConnection::outp("For odbc PConnect(), $argDatabasename is not used. Place dsn in 1st parameter.");
@@ -352,7 +358,9 @@ class ADODB_odbc extends ADOConnection {
global $ADODB_FETCH_MODE;
$table = strtoupper($table);
-
+ $schema = false;
+ $this->_findschema($table,$schema);
+
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
@@ -394,7 +402,6 @@ class ADODB_odbc extends ADOConnection {
if (!$rs) return false;
- //print_r($rs);
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
$rs->_fetch();
$retarr = array();
@@ -415,8 +422,8 @@ class ADODB_odbc extends ADOConnection {
11 REMARKS
*/
while (!$rs->EOF) {
- //print_r($rs->fields);
- if (strtoupper($rs->fields[2]) == $table) {
+ //adodb_pr($rs->fields);
+ if (strtoupper($rs->fields[2]) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
$fld = new ADOFieldObject();
$fld->name = $rs->fields[3];
$fld->type = $this->ODBCTypes($rs->fields[4]);
@@ -632,7 +639,10 @@ class ADORecordSet_odbc extends ADORecordSet {
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
function &GetArrayLimit($nrows,$offset=-1)
{
- if ($offset <= 0) return $this->GetArray($nrows);
+ if ($offset <= 0) {
+ $rs =& $this->GetArray($nrows);
+ return $rs;
+ }
$savem = $this->fetchMode;
$this->fetchMode = ADODB_FETCH_NUM;
$this->Move($offset);
diff --git a/lib/adodb/drivers/adodb-odbc_mssql.inc.php b/lib/adodb/drivers/adodb-odbc_mssql.inc.php
index 19a0b2cfef1..435bd73465f 100644
--- a/lib/adodb/drivers/adodb-odbc_mssql.inc.php
+++ b/lib/adodb/drivers/adodb-odbc_mssql.inc.php
@@ -1,6 +1,6 @@
0 && $offset <= 0) {
$sql = preg_replace(
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
- return $this->Execute($sql,$inputarr);
+ $rs =& $this->Execute($sql,$inputarr);
} else
- return ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+
+ return $rs;
}
// Format date column in sql string given an input format that understands Y M D
diff --git a/lib/adodb/drivers/adodb-odbc_oracle.inc.php b/lib/adodb/drivers/adodb-odbc_oracle.inc.php
index 8647b1baea7..293af7653f0 100644
--- a/lib/adodb/drivers/adodb-odbc_oracle.inc.php
+++ b/lib/adodb/drivers/adodb-odbc_oracle.inc.php
@@ -1,6 +1,6 @@
0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
+
+ var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
+FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
+WHERE relkind = 'r' AND (c.relname='%s' or c.relname = lower('%s'))
+ and c.relnamespace=n.oid and n.nspname='%s'
+ and a.attname not like '....%%' AND a.attnum > 0
+ AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
+
// get primary key etc -- from Freek Dijkstra
- var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
+ var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
+ FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
var $hasAffectedRows = true;
var $hasLimit = false; // set to true for pgsql 7 only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
@@ -85,8 +94,9 @@ AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum
var $_genSeqSQL = "CREATE SEQUENCE %s START %s";
var $_dropSeqSQL = "DROP SEQUENCE %s";
var $metaDefaultsSQL = "SELECT d.adnum as num, d.adsrc as def from pg_attrdef d, pg_class c where d.adrelid=c.oid and c.relname='%s' order by d.adnum";
- var $upperCase = 'upper';
- var $substr = "substr";
+ var $random = 'random()'; /// random function
+ var $autoRollback = true; // apparently pgsql does not autorollback properly before 4.3.4
+ // http://bugs.php.net/bug.php?id=25404
// The last (fmtTimeStamp is not entirely correct:
// PostgreSQL also has support for time zones,
@@ -145,7 +155,7 @@ a different OID if a database must be reloaded. */
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
return pg_cmdtuples($this->_resultid);
}
-
+
// returns true/false
function BeginTrans()
@@ -348,6 +358,8 @@ select viewname,'V' from pg_views where viewname like $mask";
function BlobEncode($blob)
{
if (ADODB_PHPVER >= 0x4200) return pg_escape_bytea($blob);
+
+ /*92=backslash, 0=null, 39=single-quote*/
$badch = array(chr(92),chr(0),chr(39)); # \ null '
$fixch = array('\\\\134','\\\\000','\\\\047');
return adodb_str_replace($badch,$fixch,$blob);
@@ -357,8 +369,8 @@ select viewname,'V' from pg_views where viewname like $mask";
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
{
- return $this->Execute("UPDATE $table SET $column=? WHERE $where",
- array($this->BlobEncode($val))) != false;
+ // do not use bind params which uses qstr(), as blobencode() already quotes data
+ return $this->Execute("UPDATE $table SET $column='".$this->BlobEncode($val)."'::bytea WHERE $where");
}
function OffsetDate($dayFraction,$date=false)
@@ -368,111 +380,177 @@ select viewname,'V' from pg_views where viewname like $mask";
}
- // converts field names to lowercase
- function &MetaColumns($table)
+ // for schema support, pass in the $table param "$schema.$tabname".
+ // converts field names to lowercase, $upper is ignored
+ function &MetaColumns($table,$upper=true)
{
global $ADODB_FETCH_MODE;
- //if (strncmp(PHP_OS,'WIN',3) === 0);
+ $schema = false;
+ $this->_findschema($table,$schema);
+
$table = strtolower($table);
-
- if (!empty($this->metaColumnsSQL)) {
- $save = $ADODB_FETCH_MODE;
- $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
- $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+
+ $save = $ADODB_FETCH_MODE;
+ $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+ if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
+
+ if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
+ else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+ if (isset($savem)) $this->SetFetchMode($savem);
+ $ADODB_FETCH_MODE = $save;
+
+ if ($rs === false) return false;
+
+ if (!empty($this->metaKeySQL)) {
+ // If we want the primary keys, we have to issue a separate query
+ // Of course, a modified version of the metaColumnsSQL query using a
+ // LEFT JOIN would have been much more elegant, but postgres does
+ // not support OUTER JOINS. So here is the clumsy way.
+
+ $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
+
+ $rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
+ // fetch all result in once for performance.
+ $keys =& $rskey->GetArray();
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
- if ($rs === false) return false;
-
- if (!empty($this->metaKeySQL)) {
- // If we want the primary keys, we have to issue a separate query
- // Of course, a modified version of the metaColumnsSQL query using a
- // LEFT JOIN would have been much more elegant, but postgres does
- // not support OUTER JOINS. So here is the clumsy way.
-
- $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
-
- $rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
- // fetch all result in once for performance.
- $keys =& $rskey->GetArray();
- if (isset($savem)) $this->SetFetchMode($savem);
- $ADODB_FETCH_MODE = $save;
-
- $rskey->Close();
- unset($rskey);
- }
-
- $rsdefa = array();
- if (!empty($this->metaDefaultsSQL)) {
- $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
- $sql = sprintf($this->metaDefaultsSQL, ($table));
- $rsdef = $this->Execute($sql);
- if (isset($savem)) $this->SetFetchMode($savem);
- $ADODB_FETCH_MODE = $save;
-
- if ($rsdef) {
- while (!$rsdef->EOF) {
- $num = $rsdef->fields['num'];
- $s = $rsdef->fields['def'];
- if (substr($s, 0, 1) == "'") { /* quoted strings hack... for now... fixme */
- $s = substr($s, 1);
- $s = substr($s, 0, strlen($s) - 1);
- }
-
- $rsdefa[$num] = $s;
- $rsdef->MoveNext();
- }
- } else {
- ADOConnection::outp( "==> SQL => " . $sql);
- }
- unset($rsdef);
- }
-
- $retarr = array();
- while (!$rs->EOF) {
- $fld = new ADOFieldObject();
- $fld->name = $rs->fields[0];
- $fld->type = $rs->fields[1];
- $fld->max_length = $rs->fields[2];
- if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
- if ($fld->max_length <= 0) $fld->max_length = -1;
-
- // dannym
- // 5 hasdefault; 6 num-of-column
- $fld->has_default = ($rs->fields[5] == 't');
- if ($fld->has_default) {
- $fld->default_value = $rsdefa[$rs->fields[6]];
- }
-
- //Freek
- if ($rs->fields[4] == $this->true) {
- $fld->not_null = true;
- }
-
- // Freek
- if (is_array($keys)) {
- reset ($keys);
- while (list($x,$key) = each($keys)) {
- if ($fld->name == $key['column_name'] AND $key['primary_key'] == $this->true)
- $fld->primary_key = true;
- if ($fld->name == $key['column_name'] AND $key['unique_key'] == $this->true)
- $fld->unique = true; // What name is more compatible?
- }
- }
-
- if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
- else $retarr[strtoupper($fld->name)] = $fld;
-
- $rs->MoveNext();
- }
- $rs->Close();
- return $retarr;
+ $rskey->Close();
+ unset($rskey);
}
- return false;
+
+ $rsdefa = array();
+ if (!empty($this->metaDefaultsSQL)) {
+ $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
+ $sql = sprintf($this->metaDefaultsSQL, ($table));
+ $rsdef = $this->Execute($sql);
+ if (isset($savem)) $this->SetFetchMode($savem);
+ $ADODB_FETCH_MODE = $save;
+
+ if ($rsdef) {
+ while (!$rsdef->EOF) {
+ $num = $rsdef->fields['num'];
+ $s = $rsdef->fields['def'];
+ if (substr($s, 0, 1) == "'") { /* quoted strings hack... for now... fixme */
+ $s = substr($s, 1);
+ $s = substr($s, 0, strlen($s) - 1);
+ }
+
+ $rsdefa[$num] = $s;
+ $rsdef->MoveNext();
+ }
+ } else {
+ ADOConnection::outp( "==> SQL => " . $sql);
+ }
+ unset($rsdef);
+ }
+
+ $retarr = array();
+ while (!$rs->EOF) {
+ $fld = new ADOFieldObject();
+ $fld->name = $rs->fields[0];
+ $fld->type = $rs->fields[1];
+ $fld->max_length = $rs->fields[2];
+ if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
+ if ($fld->max_length <= 0) $fld->max_length = -1;
+
+ // dannym
+ // 5 hasdefault; 6 num-of-column
+ $fld->has_default = ($rs->fields[5] == 't');
+ if ($fld->has_default) {
+ $fld->default_value = $rsdefa[$rs->fields[6]];
+ }
+
+ //Freek
+ if ($rs->fields[4] == $this->true) {
+ $fld->not_null = true;
+ }
+
+ // Freek
+ if (is_array($keys)) {
+ foreach($keys as $key) {
+ if ($fld->name == $key['column_name'] AND $key['primary_key'] == $this->true)
+ $fld->primary_key = true;
+ if ($fld->name == $key['column_name'] AND $key['unique_key'] == $this->true)
+ $fld->unique = true; // What name is more compatible?
+ }
+ }
+
+ if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
+ else $retarr[($upper) ? strtoupper($fld->name) : $fld->name] = $fld;
+
+ $rs->MoveNext();
+ }
+ $rs->Close();
+ return $retarr;
+
}
+ function &MetaIndexes ($table, $primary = FALSE)
+ {
+ global $ADODB_FETCH_MODE;
+
+ $schema = false;
+ $this->_findschema($table,$schema);
+
+ if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
+ $sql = '
+SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
+FROM pg_catalog.pg_class c
+JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
+JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
+ ,pg_namespace n
+WHERE c2.relname=\'%s\' and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\' AND i.indisprimary=false';
+ } else {
+ $sql = '
+SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
+FROM pg_catalog.pg_class c
+JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
+JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
+WHERE c2.relname=\'%s\'';
+ }
+
+ if ($primary == FALSE) {
+ $sql .= ' AND i.indisprimary=false;';
+ }
+
+ $save = $ADODB_FETCH_MODE;
+ $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+ if ($this->fetchMode !== FALSE) {
+ $savem = $this->SetFetchMode(FALSE);
+ }
+
+ $rs = $this->Execute(sprintf($sql,$table,$schema));
+
+ if (isset($savem)) {
+ $this->SetFetchMode($savem);
+ }
+ $ADODB_FETCH_MODE = $save;
+
+ if (!is_object($rs)) {
+ return FALSE;
+ }
+
+ $col_names = $this->MetaColumnNames($table);
+ $indexes = array();
+
+ while ($row = $rs->FetchRow()) {
+ $columns = array();
+
+ foreach (explode(' ', $row[2]) as $col) {
+ $columns[] = $col_names[$col - 1];
+ }
+
+ $indexes[$row[0]] = array(
+ 'unique' => ($row[1] == 't'),
+ 'columns' => $columns
+ );
+ }
+
+ return $indexes;
+ }
+
// returns true or false
//
// examples:
@@ -480,6 +558,9 @@ select viewname,'V' from pg_views where viewname like $mask";
// $db->Connect('host1','user1','secret');
function _connect($str,$user='',$pwd='',$db='',$ctype=0)
{
+
+ if (!function_exists('pg_pconnect')) return false;
+
$this->_errorMsg = false;
if ($user || $pwd || $db) {
@@ -687,7 +768,8 @@ class ADORecordSet_postgres64 extends ADORecordSet{
function &GetRowAssoc($upper=true)
{
if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
- return ADORecordSet::GetRowAssoc($upper);
+ $row =& ADORecordSet::GetRowAssoc($upper);
+ return $row;
}
function _initrs()
@@ -746,14 +828,12 @@ class ADORecordSet_postgres64 extends ADORecordSet{
function _fixblobs()
{
if ($this->fetchMode == PGSQL_NUM || $this->fetchMode == PGSQL_BOTH) {
- reset($this->_blobArr);
- while(list($k,$v) = each($this->_blobArr)) {
+ foreach($this->_blobArr as $k => $v) {
$this->fields[$k] = ADORecordSet_postgres64::_decode($this->fields[$k]);
}
}
if ($this->fetchMode == PGSQL_ASSOC || $this->fetchMode == PGSQL_BOTH) {
- reset($this->_blobArr);
- while(list($k,$v) = each($this->_blobArr)) {
+ foreach($this->_blobArr as $k => $v) {
$this->fields[$v] = ADORecordSet_postgres64::_decode($this->fields[$v]);
}
}
@@ -766,9 +846,8 @@ class ADORecordSet_postgres64 extends ADORecordSet{
$this->_currentRow++;
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
-
- if (is_array($this->fields)) {
- if (isset($this->_blobArr)) $this->_fixblobs();
+ if (is_array($this->fields) && $this->fields) {
+ if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
return true;
}
}
@@ -780,11 +859,13 @@ class ADORecordSet_postgres64 extends ADORecordSet{
function _fetch()
{
+
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
return false;
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
- if (isset($this->_blobArr)) $this->_fixblobs();
+
+ if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
return (is_array($this->fields));
}
diff --git a/lib/adodb/drivers/adodb-postgres7.inc.php b/lib/adodb/drivers/adodb-postgres7.inc.php
index 8e923eefd30..2b9eb235f03 100644
--- a/lib/adodb/drivers/adodb-postgres7.inc.php
+++ b/lib/adodb/drivers/adodb-postgres7.inc.php
@@ -1,6 +1,6 @@
= 0) ? " OFFSET $offset" : '';
- $limitStr = ($nrows >= 0) ? " LIMIT $nrows" : '';
- return $secs2cache ?
- $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr)
- :
- $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+ $offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
+ $limitStr = ($nrows >= 0) ? " LIMIT $nrows" : '';
+ if ($secs2cache)
+ $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+ else
+ $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+
+ return $rs;
}
/*
function Prepare($sql)
@@ -135,7 +137,7 @@ class ADORecordSet_postgres7 extends ADORecordSet_postgres64{
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
if (is_array($this->fields)) {
- if (isset($this->_blobArr)) $this->_fixblobs();
+ if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
return true;
}
}
diff --git a/lib/adodb/drivers/adodb-proxy.inc.php b/lib/adodb/drivers/adodb-proxy.inc.php
index c53e057d657..c589ce96ada 100644
--- a/lib/adodb/drivers/adodb-proxy.inc.php
+++ b/lib/adodb/drivers/adodb-proxy.inc.php
@@ -1,6 +1,6 @@
_connectionID = sqlite_open($argHostname);
if ($this->_connectionID === false) return false;
$this->_createFunctions();
@@ -135,6 +137,8 @@ class ADODB_sqlite extends ADOConnection {
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
+ if (!function_exists('sqlite_open')) return false;
+
$this->_connectionID = sqlite_popen($argHostname);
if ($this->_connectionID === false) return false;
$this->_createFunctions();
@@ -156,10 +160,12 @@ class ADODB_sqlite extends ADOConnection {
{
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : '');
- return $secs2cache ?
- $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr)
- :
- $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+ if ($secs2cache)
+ $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+ else
+ $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+
+ return $rs;
}
/*
diff --git a/lib/adodb/drivers/adodb-sybase.inc.php b/lib/adodb/drivers/adodb-sybase.inc.php
index 1291162ad1c..b1626674978 100644
--- a/lib/adodb/drivers/adodb-sybase.inc.php
+++ b/lib/adodb/drivers/adodb-sybase.inc.php
@@ -1,6 +1,6 @@
_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -123,6 +125,8 @@ class ADODB_sybase extends ADOConnection {
// returns true or false
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
+ if (!function_exists('sybase_connect')) return false;
+
$this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -143,14 +147,15 @@ class ADODB_sybase extends ADOConnection {
// See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
- if ($secs2cache > 0) // we do not cache rowcount, so we have to load entire recordset
- return ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
-
+ if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
+ $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ return $rs;
+ }
$cnt = ($nrows > 0) ? $nrows : 0;
if ($offset > 0 && $cnt) $cnt += $offset;
$this->Execute("set rowcount $cnt");
- $rs = &ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
$this->Execute("set rowcount 0");
return $rs;
diff --git a/lib/adodb/drivers/adodb-vfp.inc.php b/lib/adodb/drivers/adodb-vfp.inc.php
index 42dddf9d162..86e1e752abb 100644
--- a/lib/adodb/drivers/adodb-vfp.inc.php
+++ b/lib/adodb/drivers/adodb-vfp.inc.php
@@ -1,6 +1,6 @@
'ca',
+ DB_ERROR => 'error desconegut',
+ DB_ERROR_ALREADY_EXISTS => 'ja existeix',
+ DB_ERROR_CANNOT_CREATE => 'no es pot crear',
+ DB_ERROR_CANNOT_DELETE => 'no es pot esborrar',
+ DB_ERROR_CANNOT_DROP => 'no es pot eliminar',
+ DB_ERROR_CONSTRAINT => 'violació de constraint',
+ DB_ERROR_DIVZERO => 'divisió per zero',
+ DB_ERROR_INVALID => 'no és vàlid',
+ DB_ERROR_INVALID_DATE => 'la data o l\'hora no són vàlides',
+ DB_ERROR_INVALID_NUMBER => 'el nombre no és vàlid',
+ DB_ERROR_MISMATCH => 'no hi ha coincidència',
+ DB_ERROR_NODBSELECTED => 'cap base de dades seleccionada',
+ DB_ERROR_NOSUCHFIELD => 'camp inexistent',
+ DB_ERROR_NOSUCHTABLE => 'taula inexistent',
+ DB_ERROR_NOT_CAPABLE => 'l\'execució secundària de DB no pot',
+ DB_ERROR_NOT_FOUND => 'no trobat',
+ DB_ERROR_NOT_LOCKED => 'no blocat',
+ DB_ERROR_SYNTAX => 'error de sintaxi',
+ DB_ERROR_UNSUPPORTED => 'no suportat',
+ DB_ERROR_VALUE_COUNT_ON_ROW => 'el nombre de columnes no coincideix amb el nombre de valors en la fila',
+ DB_ERROR_INVALID_DSN => 'el DSN no és vàlid',
+ DB_ERROR_CONNECT_FAILED => 'connexió fallida',
+ 0 => 'cap error', // DB_OK
+ DB_ERROR_NEED_MORE_DATA => 'les dades subministrades són insuficients',
+ DB_ERROR_EXTENSION_NOT_FOUND=> 'extensió no trobada',
+ DB_ERROR_NOSUCHDB => 'base de dades inexistent',
+ DB_ERROR_ACCESS_VIOLATION => 'permisos insuficients'
+);
+?>
+
\ No newline at end of file
diff --git a/lib/adodb/lang/adodb-cn.inc.php b/lib/adodb/lang/adodb-cn.inc.php
new file mode 100644
index 00000000000..eb8c7de55c2
--- /dev/null
+++ b/lib/adodb/lang/adodb-cn.inc.php
@@ -0,0 +1,35 @@
+ 'cn',
+ DB_ERROR => 'δ֪´íÎó',
+ DB_ERROR_ALREADY_EXISTS => 'ÒѾ´æÔÚ',
+ DB_ERROR_CANNOT_CREATE => '²»ÄÜ´´½¨',
+ DB_ERROR_CANNOT_DELETE => '²»ÄÜɾ³ý',
+ DB_ERROR_CANNOT_DROP => '²»ÄܶªÆú',
+ DB_ERROR_CONSTRAINT => 'Ô¼ÊøÏÞÖÆ',
+ DB_ERROR_DIVZERO => '±»0³ý',
+ DB_ERROR_INVALID => 'ÎÞЧ',
+ DB_ERROR_INVALID_DATE => 'ÎÞЧµÄÈÕÆÚ»òÕßʱ¼ä',
+ DB_ERROR_INVALID_NUMBER => 'ÎÞЧµÄÊý×Ö',
+ DB_ERROR_MISMATCH => '²»Æ¥Åä',
+ DB_ERROR_NODBSELECTED => 'ûÓÐÊý¾Ý¿â±»Ñ¡Ôñ',
+ DB_ERROR_NOSUCHFIELD => 'ûÓÐÏàÓ¦µÄ×Ö¶Î',
+ DB_ERROR_NOSUCHTABLE => 'ûÓÐÏàÓ¦µÄ±í',
+ DB_ERROR_NOT_CAPABLE => 'Êý¾Ý¿âºǫ́²»¼æÈÝ',
+ DB_ERROR_NOT_FOUND => 'ûÓз¢ÏÖ',
+ DB_ERROR_NOT_LOCKED => 'ûÓб»Ëø¶¨',
+ DB_ERROR_SYNTAX => 'Óï·¨´íÎó',
+ DB_ERROR_UNSUPPORTED => '²»Ö§³Ö',
+ DB_ERROR_VALUE_COUNT_ON_ROW => 'ÔÚÐÐÉÏÀÛ¼ÆÖµ',
+ DB_ERROR_INVALID_DSN => 'ÎÞЧµÄÊý¾ÝÔ´ (DSN)',
+ DB_ERROR_CONNECT_FAILED => 'Á¬½Óʧ°Ü',
+ 0 => 'ûÓдíÎó', // DB_OK
+ DB_ERROR_NEED_MORE_DATA => 'ÌṩµÄÊý¾Ý²»ÄÜ·ûºÏÒªÇó',
+ DB_ERROR_EXTENSION_NOT_FOUND=> 'À©Õ¹Ã»Óб»·¢ÏÖ',
+ DB_ERROR_NOSUCHDB => 'ûÓÐÏàÓ¦µÄÊý¾Ý¿â',
+ DB_ERROR_ACCESS_VIOLATION => 'ûÓкÏÊʵÄȨÏÞ'
+);
+?>
\ No newline at end of file
diff --git a/lib/adodb/lang/adodb-de.inc.php b/lib/adodb/lang/adodb-de.inc.php
new file mode 100644
index 00000000000..244cb2f66ae
--- /dev/null
+++ b/lib/adodb/lang/adodb-de.inc.php
@@ -0,0 +1,33 @@
+
+$ADODB_LANG_ARRAY = array (
+ 'LANG' => 'de',
+ DB_ERROR => 'Unbekannter Fehler',
+ DB_ERROR_ALREADY_EXISTS => 'existiert bereits',
+ DB_ERROR_CANNOT_CREATE => 'kann nicht erstellen',
+ DB_ERROR_CANNOT_DELETE => 'kann nicht löschen',
+ DB_ERROR_CANNOT_DROP => 'Tabelle oder Index konnte nicht gelöscht werden',
+ DB_ERROR_CONSTRAINT => 'Constraint Verletzung',
+ DB_ERROR_DIVZERO => 'Division durch Null',
+ DB_ERROR_INVALID => 'ung¨ltig',
+ DB_ERROR_INVALID_DATE => 'ung¨ltiges Datum oder Zeit',
+ DB_ERROR_INVALID_NUMBER => 'ung¨ltige Zahl',
+ DB_ERROR_MISMATCH => 'Unverträglichkeit',
+ DB_ERROR_NODBSELECTED => 'keine Dantebank ausgewählt',
+ DB_ERROR_NOSUCHFIELD => 'Feld nicht vorhanden',
+ DB_ERROR_NOSUCHTABLE => 'Tabelle nicht vorhanden',
+ DB_ERROR_NOT_CAPABLE => 'Funktion nicht installiert',
+ DB_ERROR_NOT_FOUND => 'nicht gefunden',
+ DB_ERROR_NOT_LOCKED => 'nicht gesperrt',
+ DB_ERROR_SYNTAX => 'Syntaxfehler',
+ DB_ERROR_UNSUPPORTED => 'nicht Unterst¨tzt',
+ DB_ERROR_VALUE_COUNT_ON_ROW => 'Anzahl der zur¨ckgelieferten Felder entspricht nicht der Anzahl der Felder in der Abfrage',
+ DB_ERROR_INVALID_DSN => 'ung¨ltiger DSN',
+ DB_ERROR_CONNECT_FAILED => 'Verbindung konnte nicht hergestellt werden',
+ 0 => 'kein Fehler', // DB_OK
+ DB_ERROR_NEED_MORE_DATA => 'Nicht gen¨gend Daten geliefert',
+ DB_ERROR_EXTENSION_NOT_FOUND=> 'erweiterung nicht gefunden',
+ DB_ERROR_NOSUCHDB => 'keine Datenbank',
+ DB_ERROR_ACCESS_VIOLATION => 'ungen¨gende Rechte'
+);
+?>
\ No newline at end of file
diff --git a/lib/adodb/lang/adodb-fr.inc.php b/lib/adodb/lang/adodb-fr.inc.php
index 9d7e98f20b4..066a2a5e5b7 100644
--- a/lib/adodb/lang/adodb-fr.inc.php
+++ b/lib/adodb/lang/adodb-fr.inc.php
@@ -28,6 +28,6 @@ $ADODB_LANG_ARRAY = array (
DB_ERROR_NEED_MORE_DATA => 'données fournies insuffisantes',
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension non trouvée',
DB_ERROR_NOSUCHDB => 'base de données inconnue',
- DB_ERROR_ACCESS_VIOLATION => 'droits ynsuffisants'
+ DB_ERROR_ACCESS_VIOLATION => 'droits insuffisants'
);
?>
\ No newline at end of file
diff --git a/lib/adodb/lang/adodb-it.inc.php b/lib/adodb/lang/adodb-it.inc.php
index 71dcb88599b..20c5b93b630 100644
--- a/lib/adodb/lang/adodb-it.inc.php
+++ b/lib/adodb/lang/adodb-it.inc.php
@@ -8,10 +8,10 @@ $ADODB_LANG_ARRAY = array (
DB_ERROR_CANNOT_CREATE => 'non posso creare',
DB_ERROR_CANNOT_DELETE => 'non posso cancellare',
DB_ERROR_CANNOT_DROP => 'non posso eliminare',
- DB_ERROR_CONSTRAINT => 'viiolazione constraint',
+ DB_ERROR_CONSTRAINT => 'violazione constraint',
DB_ERROR_DIVZERO => 'divisione per zero',
DB_ERROR_INVALID => 'non valido',
- DB_ERROR_INVALID_DATE => 'date od ora non valido',
+ DB_ERROR_INVALID_DATE => 'data od ora non valida',
DB_ERROR_INVALID_NUMBER => 'numero non valido',
DB_ERROR_MISMATCH => 'diversi',
DB_ERROR_NODBSELECTED => 'nessun database selezionato',
@@ -26,9 +26,9 @@ $ADODB_LANG_ARRAY = array (
DB_ERROR_INVALID_DSN => 'DSN non valido',
DB_ERROR_CONNECT_FAILED => 'connessione fallita',
0 => 'nessun errore', // DB_OK
- DB_ERROR_NEED_MORE_DATA => 'dati inseriti insufficenti',
+ DB_ERROR_NEED_MORE_DATA => 'dati inseriti insufficienti',
DB_ERROR_EXTENSION_NOT_FOUND=> 'estensione non trovata',
DB_ERROR_NOSUCHDB => 'database non trovato',
- DB_ERROR_ACCESS_VIOLATION => 'permessi insufficenti'
+ DB_ERROR_ACCESS_VIOLATION => 'permessi insufficienti'
);
?>
\ No newline at end of file
diff --git a/lib/adodb/license.txt b/lib/adodb/license.txt
index b05750301be..65831629fa7 100644
--- a/lib/adodb/license.txt
+++ b/lib/adodb/license.txt
@@ -13,12 +13,27 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
-Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-Neither the name of the John Lim nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+Redistributions of source code must retain the above copyright notice, this list
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this list
+of conditions and the following disclaimer in the documentation and/or other materials
+provided with the distribution.
+
+Neither the name of the John Lim nor the names of its contributors may be used to
+endorse or promote products derived from this software without specific prior written
+permission.
DISCLAIMER:
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+JOHN LIM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
==========================================================
GNU LESSER GENERAL PUBLIC LICENSE
diff --git a/lib/adodb/perf/perf-db2.inc.php b/lib/adodb/perf/perf-db2.inc.php
index bc73ab3a6f8..64e26222d07 100644
--- a/lib/adodb/perf/perf-db2.inc.php
+++ b/lib/adodb/perf/perf-db2.inc.php
@@ -1,6 +1,6 @@
conn =& $conn;
}
- function Explain($sql)
+ function Explain($sql,$partial=false)
{
$save = $this->conn->LogSQL(false);
+ if ($partial) {
+ $sqlq = $this->conn->qstr($sql.'%');
+ $arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
+ if ($arr) {
+ foreach($arr as $row) {
+ $sql = reset($row);
+ if (crc32($sql) == $partial) break;
+ }
+ }
+ }
$qno = rand();
$ok = $this->conn->Execute("EXPLAIN PLAN SET QUERYNO=$qno FOR $sql");
ob_start();
diff --git a/lib/adodb/perf/perf-informix.inc.php b/lib/adodb/perf/perf-informix.inc.php
index 3ee4b923dc9..2b2923b8687 100644
--- a/lib/adodb/perf/perf-informix.inc.php
+++ b/lib/adodb/perf/perf-informix.inc.php
@@ -1,6 +1,6 @@
conn =& $conn;
}
- function Explain($sql)
+ function Explain($sql,$partial=false)
{
+
+ $save = $this->conn->LogSQL(false);
+ if ($partial) {
+ $sqlq = $this->conn->qstr($sql.'%');
+ $arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
+ if ($arr) {
+ foreach($arr as $row) {
+ $sql = reset($row);
+ if (crc32($sql) == $partial) break;
+ }
+ }
+ }
+
$s = '
Explain: '.htmlspecialchars($sql).'
';
$this->conn->Execute("SET SHOWPLAN_ALL ON;");
$sql = str_replace('?',"''",$sql);
@@ -96,7 +109,7 @@ class perf_mssql extends adodb_perf{
}
$this->conn->Execute("SET SHOWPLAN_ALL OFF;");
-
+ $this->conn->LogSQL($save);
$s .= $this->Tracer($sql);
return $s;
}
diff --git a/lib/adodb/perf/perf-mysql.inc.php b/lib/adodb/perf/perf-mysql.inc.php
index 9e038c6dd4c..bfa1883d4f1 100644
--- a/lib/adodb/perf/perf-mysql.inc.php
+++ b/lib/adodb/perf/perf-mysql.inc.php
@@ -1,6 +1,6 @@
conn =& $conn;
}
- function Explain($sql)
+ function Explain($sql,$partial=false)
{
+
if (strtoupper(substr(trim($sql),0,6)) !== 'SELECT') return 'Unable to EXPLAIN non-select statement
';
+ $save = $this->conn->LogSQL(false);
+ if ($partial) {
+ $sqlq = $this->conn->qstr($sql.'%');
+ $arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
+ if ($arr) {
+ foreach($arr as $row) {
+ $sql = reset($row);
+ if (crc32($sql) == $partial) break;
+ }
+ }
+ }
$sql = str_replace('?',"''",$sql);
+
+ if ($partial) {
+ $sqlq = $this->conn->qstr($sql.'%');
+ $sql = $this->conn->GetOne("select sql1 from adodb_logsql where sql1 like $sqlq");
+ }
+
$s = 'Explain: '.htmlspecialchars($sql).'
';
$rs = $this->conn->Execute('EXPLAIN '.$sql);
$s .= rs2html($rs,false,false,false,false);
+ $this->conn->LogSQL($save);
$s .= $this->Tracer($sql);
return $s;
}
@@ -207,7 +226,9 @@ class perf_mysql extends adodb_perf{
{
global $HTTP_SESSION_VARS;
- $stat = $this->conn->GetOne('show innodb status');
+ $rs = $this->conn->Execute('show innodb status');
+ if (!$rs || $rs->EOF) return 0;
+ $stat = $rs->fields[0];
$at = strpos($stat,'Buffer pool hit rate');
$stat = substr($stat,$at,200);
if (preg_match('!Buffer pool hit rate\s*([0-9]*) / ([0-9]*)!',$stat,$arr)) {
diff --git a/lib/adodb/perf/perf-oci8.inc.php b/lib/adodb/perf/perf-oci8.inc.php
index e301a225c2b..cc1151ea575 100644
--- a/lib/adodb/perf/perf-oci8.inc.php
+++ b/lib/adodb/perf/perf-oci8.inc.php
@@ -1,6 +1,6 @@
shared_pool_size if too ratio low'),
+
+ 'memory sort ratio' => array('RATIOH',
+ "SELECT ROUND((100 * b.VALUE) /DECODE ((a.VALUE + b.VALUE),
+ 0,1,(a.VALUE + b.VALUE)),2)
+FROM v\$sysstat a,
+ v\$sysstat b
+WHERE a.name = 'sorts (disk)'
+AND b.name = 'sorts (memory)'",
+ "% of memory sorts compared to disk sorts - should be over 95%"),
'IO',
'data reads' => array('IO',
@@ -176,7 +185,7 @@ class perf_oci8 extends ADODB_perf{
return reset($rs->fields);
}
- function Explain($sql)
+ function Explain($sql,$partial=false)
{
$savelog = $this->conn->LogSQL(false);
$rs =& $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
@@ -216,6 +225,17 @@ CREATE TABLE PLAN_TABLE (
$rs->Close();
// $this->conn->debug=1;
+ if ($partial) {
+ $sqlq = $this->conn->qstr($sql.'%');
+ $arr = $this->conn->GetArray("select distinct distinct sql1 from adodb_logsql where sql1 like $sqlq");
+ if ($arr) {
+ foreach($arr as $row) {
+ $sql = reset($row);
+ if (crc32($sql) == $partial) break;
+ }
+ }
+ }
+
$s = "Explain: ".htmlspecialchars($sql)."
";
$this->conn->BeginTrans();
@@ -239,7 +259,7 @@ CONNECT BY prior id=parent_id and statement_id='$id'");
$s .= rs2html($rs,false,false,false,false);
$this->conn->RollbackTrans();
$this->conn->LogSQL($savelog);
- $s .= $this->Tracer($sql);
+ $s .= $this->Tracer($sql,$partial);
return $s;
}
@@ -256,17 +276,18 @@ select a.size_for_estimate as cache_mb_estimate,
'- BETTER - '
else ' ' end as currsize,
a.estd_physical_read_factor-b.estd_physical_read_factor as best_when_0
- from (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$conn_cache_advice) a ,
- (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$conn_cache_advice) b where a.r = b.r-1");
+ from (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$db_cache_advice) a ,
+ (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$db_cache_advice) b where a.r = b.r-1");
if (!$rs) return false;
/*
- The v$conn_cache_advice utility show the marginal changes in physical data block reads for different sizes of db_cache_size
+ The v$db_cache_advice utility show the marginal changes in physical data block reads for different sizes of db_cache_size
*/
$s = "Data Cache Estimate
";
if ($rs->EOF) {
$s .= "Cache that is 50% of current size is still too big
";
} else {
+ $s .= "Ideal size of Data Cache is when \"best_when_0\" changes from a positive number and becomes zero.";
$s .= rs2html($rs,false,false,false,false);
}
return $s;
@@ -360,7 +381,8 @@ order by
global $ADODB_CACHE_MODE,$HTTP_GET_VARS;
if (isset($HTTP_GET_VARS['expsixora']) && isset($HTTP_GET_VARS['sql'])) {
- echo "".$this->Explain($HTTP_GET_VARS['sql'])."\n";
+ $partial = empty($HTTP_GET_VARS['part']);
+ echo "".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
}
if (isset($HTTP_GET_VARS['sql'])) return $this->_SuspiciousSQL();
@@ -385,7 +407,7 @@ order by
// code thanks to Ixora.
// http://www.ixora.com.au/scripts/query_opt.htm
// requires oracle 8.1.7 or later
- function& ExpensiveSQL($numsql = 10)
+ function ExpensiveSQL($numsql = 10)
{
$sql = "
select
@@ -424,11 +446,14 @@ order by
";
global $ADODB_CACHE_MODE,$HTTP_GET_VARS;
if (isset($HTTP_GET_VARS['expeixora']) && isset($HTTP_GET_VARS['sql'])) {
- echo "".$this->Explain($HTTP_GET_VARS['sql'])."\n";
+ $partial = empty($HTTP_GET_VARS['part']);
+ echo "".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
}
- if (isset($HTTP_GET_VARS['sql'])) return $this->_ExpensiveSQL();
-
+ if (isset($HTTP_GET_VARS['sql'])) {
+ $var =& $this->_ExpensiveSQL();
+ return $var;
+ }
$save = $ADODB_CACHE_MODE;
$ADODB_CACHE_MODE = ADODB_FETCH_NUM;
$savelog = $this->conn->LogSQL(false);
diff --git a/lib/adodb/perf/perf-postgres.inc.php b/lib/adodb/perf/perf-postgres.inc.php
index f0d97b1a5a7..5ae20e4d2a7 100644
--- a/lib/adodb/perf/perf-postgres.inc.php
+++ b/lib/adodb/perf/perf-postgres.inc.php
@@ -1,7 +1,7 @@
conn =& $conn;
}
- function Explain($sql)
+ function Explain($sql,$partial=false)
{
- $sql = str_replace('?',"''",$sql);
$save = $this->conn->LogSQL(false);
+
+ if ($partial) {
+ $sqlq = $this->conn->qstr($sql.'%');
+ $arr = $this->conn->GetArray("select distinct distinct sql1 from adodb_logsql where sql1 like $sqlq");
+ if ($arr) {
+ foreach($arr as $row) {
+ $sql = reset($row);
+ if (crc32($sql) == $partial) break;
+ }
+ }
+ }
+ $sql = str_replace('?',"''",$sql);
$s = 'Explain: '.htmlspecialchars($sql).'
';
$rs = $this->conn->Execute('EXPLAIN '.$sql);
$this->conn->LogSQL($save);
@@ -102,7 +113,7 @@ class perf_postgres extends adodb_perf{
$rs->MoveNext();
}
$s .= '';
- $s .= $this->Tracer($sql);
+ $s .= $this->Tracer($sql,$partial);
return $s;
}
}
diff --git a/lib/adodb/pivottable.inc.php b/lib/adodb/pivottable.inc.php
index 96834f37232..f9c547f11b7 100644
--- a/lib/adodb/pivottable.inc.php
+++ b/lib/adodb/pivottable.inc.php
@@ -1,6 +1,6 @@
_block_size;
+ }
+
+ /**
+ */
+ function setBlockSize($block_size) {
+ assert('$block_size >= 1');
+ assert('$block_size <= 9');
+ $this->_block_size = (int) $block_size;
+ }
+
+ /**
+ */
+ function getWorkLevel() {
+ return $this->_work_level;
+ }
+
+ /**
+ */
+ function setWorkLevel($work_level) {
+ assert('$work_level >= 0');
+ assert('$work_level <= 250');
+ $this->_work_level = (int) $work_level;
+ }
+
+ /**
+ */
+ function getMinLength() {
+ return $this->_min_length;
+ }
+
+ /**
+ */
+ function setMinLength($min_length) {
+ assert('$min_length >= 0');
+ $this->_min_length = (int) $min_length;
+ }
+
+ /**
+ */
+ function ADODB_Compress_Bzip2($block_size = null, $work_level = null, $min_length = null) {
+ if (!is_null($block_size)) {
+ $this->setBlockSize($block_size);
+ }
+
+ if (!is_null($work_level)) {
+ $this->setWorkLevel($work_level);
+ }
+
+ if (!is_null($min_length)) {
+ $this->setMinLength($min_length);
+ }
+ }
+
+ /**
+ */
+ function write($data, $key) {
+ if (strlen($data) < $this->_min_length) {
+ return $data;
+ }
+
+ if (!is_null($this->_block_size)) {
+ if (!is_null($this->_work_level)) {
+ return bzcompress($data, $this->_block_size, $this->_work_level);
+ } else {
+ return bzcompress($data, $this->_block_size);
+ }
+ }
+
+ return bzcompress($data);
+ }
+
+ /**
+ */
+ function read($data, $key) {
+ return $data ? bzdecompress($data) : $data;
+ }
+
+}
+
+return 1;
+
+?>
diff --git a/lib/adodb/session/adodb-compress-gzip.php b/lib/adodb/session/adodb-compress-gzip.php
new file mode 100644
index 00000000000..c5e568e7e9c
--- /dev/null
+++ b/lib/adodb/session/adodb-compress-gzip.php
@@ -0,0 +1,94 @@
+_level;
+ }
+
+ /**
+ */
+ function setLevel($level) {
+ assert('$level >= 0');
+ assert('$level <= 9');
+ $this->_level = (int) $level;
+ }
+
+ /**
+ */
+ function getMinLength() {
+ return $this->_min_length;
+ }
+
+ /**
+ */
+ function setMinLength($min_length) {
+ assert('$min_length >= 0');
+ $this->_min_length = (int) $min_length;
+ }
+
+ /**
+ */
+ function ADODB_Compress_Gzip($level = null, $min_length = null) {
+ if (!is_null($level)) {
+ $this->setLevel($level);
+ }
+
+ if (!is_null($min_length)) {
+ $this->setMinLength($min_length);
+ }
+ }
+
+ /**
+ */
+ function write($data, $key) {
+ if (strlen($data) < $this->_min_length) {
+ return $data;
+ }
+
+ if (!is_null($this->_level)) {
+ return gzcompress($data, $this->_level);
+ } else {
+ return gzcompress($data);
+ }
+ }
+
+ /**
+ */
+ function read($data, $key) {
+ return $data ? gzuncompress($data) : $data;
+ }
+
+}
+
+return 1;
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/session/adodb-cryptsession.php b/lib/adodb/session/adodb-cryptsession.php
new file mode 100644
index 00000000000..c0ffc3c1875
--- /dev/null
+++ b/lib/adodb/session/adodb-cryptsession.php
@@ -0,0 +1,25 @@
+
\ No newline at end of file
diff --git a/lib/adodb/session/adodb-encrypt-mcrypt.php b/lib/adodb/session/adodb-encrypt-mcrypt.php
new file mode 100644
index 00000000000..2083436392e
--- /dev/null
+++ b/lib/adodb/session/adodb-encrypt-mcrypt.php
@@ -0,0 +1,110 @@
+_cipher;
+ }
+
+ /**
+ */
+ function setCipher($cipher) {
+ $this->_cipher = $cipher;
+ }
+
+ /**
+ */
+ function getMode() {
+ return $this->_mode;
+ }
+
+ /**
+ */
+ function setMode($mode) {
+ $this->_mode = $mode;
+ }
+
+ /**
+ */
+ function getSource() {
+ return $this->_source;
+ }
+
+ /**
+ */
+ function setSource($source) {
+ $this->_source = $source;
+ }
+
+ /**
+ */
+ function ADODB_Encrypt_MCrypt($cipher = null, $mode = null, $source = null) {
+ if (!$cipher) {
+ $cipher = MCRYPT_RIJNDAEL_256;
+ }
+ if (!$mode) {
+ $mode = MCRYPT_MODE_ECB;
+ }
+ if (!$source) {
+ $source = MCRYPT_RAND;
+ }
+
+ $this->_cipher = $cipher;
+ $this->_mode = $mode;
+ $this->_source = $source;
+ }
+
+ /**
+ */
+ function write($data, $key) {
+ $iv_size = mcrypt_get_iv_size($this->_cipher, $this->_mode);
+ $iv = mcrypt_create_iv($iv_size, $this->_source);
+ return mcrypt_encrypt($this->_cipher, $key, $data, $this->_mode, $iv);
+ }
+
+ /**
+ */
+ function read($data, $key) {
+ $iv_size = mcrypt_get_iv_size($this->_cipher, $this->_mode);
+ $iv = mcrypt_create_iv($iv_size, $this->_source);
+ $rv = mcrypt_decrypt($this->_cipher, $key, $data, $this->_mode, $iv);
+ return rtrim($rv, "\0");
+ }
+
+}
+
+return 1;
+
+?>
diff --git a/lib/adodb/session/adodb-encrypt-md5.php b/lib/adodb/session/adodb-encrypt-md5.php
new file mode 100644
index 00000000000..8a7e9395391
--- /dev/null
+++ b/lib/adodb/session/adodb-encrypt-md5.php
@@ -0,0 +1,38 @@
+encrypt($data, $key);
+ }
+
+ /**
+ */
+ function read($data, $key) {
+ $md5crypt =& new MD5Crypt();
+ return $md5crypt->decrypt($data, $key);
+ }
+
+}
+
+return 1;
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/session/adodb-encrypt-secret.php b/lib/adodb/session/adodb-encrypt-secret.php
new file mode 100644
index 00000000000..f979c7a0d02
--- /dev/null
+++ b/lib/adodb/session/adodb-encrypt-secret.php
@@ -0,0 +1,50 @@
+
diff --git a/lib/adodb/session/adodb-sess.txt b/lib/adodb/session/adodb-sess.txt
new file mode 100644
index 00000000000..d23dac42dfe
--- /dev/null
+++ b/lib/adodb/session/adodb-sess.txt
@@ -0,0 +1,131 @@
+John,
+
+I have been an extremely satisfied ADODB user for several years now.
+
+To give you something back for all your hard work, I've spent the last 3
+days rewriting the adodb-session.php code.
+
+----------
+What's New
+----------
+
+Here's a list of the new code's benefits:
+
+* Combines the functionality of the three files:
+
+adodb-session.php
+adodb-session-clob.php
+adodb-cryptsession.php
+
+each with very similar functionality, into a single file adodb-session.php.
+This will ease maintenance and support issues.
+
+* Supports multiple encryption and compression schemes.
+ Currently, we support:
+
+ MD5Crypt (crypt.inc.php)
+ MCrypt
+ Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)
+ GZip
+ BZip2
+
+These can be stacked, so if you want to compress and then encrypt your
+session data, it's easy.
+Also, the built-in MCrypt functions will be *much* faster, and more secure,
+than the MD5Crypt code.
+
+* adodb-session.php contains a single class ADODB_Session that encapsulates
+all functionality.
+ This eliminates the use of global vars and defines (though they are
+supported for backwards compatibility).
+
+* All user defined parameters are now static functions in the ADODB_Session
+class.
+
+New parameters include:
+
+* encryptionKey(): Define the encryption key used to encrypt the session.
+Originally, it was a hard coded string.
+
+* persist(): Define if the database will be opened in persistent mode.
+Originally, the user had to call adodb_sess_open().
+
+* dataFieldName(): Define the field name used to store the session data, as
+'DATA' appears to be a reserved word in the following cases:
+ ANSI SQL
+ IBM DB2
+ MS SQL Server
+ Postgres
+ SAP
+
+* filter(): Used to support multiple, simulataneous encryption/compression
+schemes.
+
+* Debug support is improved thru _rsdump() function, which is called after
+every database call.
+
+------------
+What's Fixed
+------------
+
+The new code includes several bug fixes and enhancements:
+
+* sesskey is compared in BINARY mode for MySQL, to avoid problems with
+session keys that differ only by case.
+ Of course, the user should define the sesskey field as BINARY, to
+correctly fix this problem, otherwise performance will suffer.
+
+* In ADODB_Session::gc(), if $expire_notify is true, the multiple DELETES in
+the original code have been optimized to a single DELETE.
+
+* In ADODB_Session::destroy(), since "SELECT expireref, sesskey FROM $table
+WHERE sesskey = $qkey" will only return a single value, we don't loop on the
+result, we simply process the row, if any.
+
+* We close $rs after every use.
+
+---------------
+What's the Same
+---------------
+
+I know backwards compatibility is *very* important to you. Therefore, the
+new code is 100% backwards compatible.
+
+If you like my code, but don't "trust" it's backwards compatible, maybe we
+offer it as beta code, in a new directory for a release or two?
+
+------------
+What's To Do
+------------
+
+I've vascillated over whether to use a single function to get/set
+parameters:
+
+$user = ADODB_Session::user(); // get
+ADODB_Session::user($user); // set
+
+or to use separate functions (which is the PEAR/Java way):
+
+$user = ADODB_Session::getUser();
+ADODB_Session::setUser($user);
+
+I've chosen the former as it's makes for a simpler API, and reduces the
+amount of code, but I'd be happy to change it to the latter.
+
+Also, do you think the class should be a singleton class, versus a static
+class?
+
+Let me know if you find this code useful, and will be including it in the
+next release of ADODB.
+
+If so, I will modify the current documentation to detail the new
+functionality. To that end, what file(s) contain the documentation? Please
+send them to me if they are not publically available.
+
+Also, if there is *anything* in the code that you like to see changed, let
+me know.
+
+Thanks,
+
+Ross
+
diff --git a/lib/adodb/session/adodb-session-clob.php b/lib/adodb/session/adodb-session-clob.php
new file mode 100644
index 00000000000..425adfb8f6e
--- /dev/null
+++ b/lib/adodb/session/adodb-session-clob.php
@@ -0,0 +1,24 @@
+
\ No newline at end of file
diff --git a/lib/adodb/session/adodb-session.php b/lib/adodb/session/adodb-session.php
new file mode 100644
index 00000000000..7cba4f854e3
--- /dev/null
+++ b/lib/adodb/session/adodb-session.php
@@ -0,0 +1,817 @@
+Session Error: PHP.INI setting session.gc_maxlifetimenot set: $lifetime";
+ $_lifetime = 1440;
+ }
+ }
+
+ return $_lifetime;
+ }
+
+ /*!
+ */
+ function debug($debug = null) {
+ static $_debug = false;
+ static $set = false;
+
+ if (!is_null($debug)) {
+ $_debug = (bool) $debug;
+
+ $conn = ADODB_Session::_conn();
+ if ($conn) {
+ $conn->debug = $_debug;
+ }
+ $set = true;
+ } elseif (!$set) {
+ // backwards compatibility
+ if (isset($GLOBALS['ADODB_SESS_DEBUG'])) {
+ return $GLOBALS['ADODB_SESS_DEBUG'];
+ }
+ }
+
+ return $_debug;
+ }
+
+ /*!
+ */
+ function expireNotify($expire_notify = null) {
+ static $_expire_notify;
+ static $set = false;
+
+ if (!is_null($expire_notify)) {
+ $_expire_notify = $expire_notify;
+ $set = true;
+ } elseif (!$set) {
+ // backwards compatibility
+ if (isset($GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'])) {
+ return $GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'];
+ }
+ }
+
+ return $_expire_notify;
+ }
+
+ /*!
+ */
+ function table($table = null) {
+ static $_table = 'sessions';
+ static $set = false;
+
+ if (!is_null($table)) {
+ $_table = trim($table);
+ $set = true;
+ } elseif (!$set) {
+ // backwards compatibility
+ if (isset($GLOBALS['ADODB_SESSION_TBL'])) {
+ return $GLOBALS['ADODB_SESSION_TBL'];
+ }
+ }
+
+ return $_table;
+ }
+
+ /*!
+ */
+ function optimize($optimize = null) {
+ static $_optimize = false;
+ static $set = false;
+
+ if (!is_null($optimize)) {
+ $_optimize = (bool) $optimize;
+ $set = true;
+ } elseif (!$set) {
+ // backwards compatibility
+ if (defined('ADODB_SESSION_OPTIMIZE')) {
+ return true;
+ }
+ }
+
+ return $_optimize;
+ }
+
+ /*!
+ */
+ function syncSeconds($sync_seconds = null) {
+ static $_sync_seconds = 60;
+ static $set = false;
+
+ if (!is_null($sync_seconds)) {
+ $_sync_seconds = (int) $sync_seconds;
+ $set = true;
+ } elseif (!$set) {
+ // backwards compatibility
+ if (defined('ADODB_SESSION_SYNCH_SECS')) {
+ return ADODB_SESSION_SYNCH_SECS;
+ }
+ }
+
+ return $_sync_seconds;
+ }
+
+ /*!
+ */
+ function clob($clob = null) {
+ static $_clob = false;
+ static $set = false;
+
+ if (!is_null($clob)) {
+ $_clob = strtolower(trim($clob));
+ $set = true;
+ } elseif (!$set) {
+ // backwards compatibility
+ if (isset($GLOBALS['ADODB_SESSION_USE_LOBS'])) {
+ return $GLOBALS['ADODB_SESSION_USE_LOBS'];
+ }
+ }
+
+ return $_clob;
+ }
+
+ /*!
+ */
+ function dataFieldName($data_field_name = null) {
+ static $_data_field_name = 'data';
+
+ if (!is_null($data_field_name)) {
+ $_data_field_name = trim($data_field_name);
+ }
+
+ return $_data_field_name;
+ }
+
+ /*!
+ */
+ function filter($filter = null) {
+ static $_filter = array();
+
+ if (!is_null($filter)) {
+ if (!is_array($filter)) {
+ $filter = array($filter);
+ }
+ $_filter = $filter;
+ }
+
+ return $_filter;
+ }
+
+ /*!
+ */
+ function encryptionKey($encryption_key = null) {
+ static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
+
+ if (!is_null($encryption_key)) {
+ $_encryption_key = $encryption_key;
+ }
+
+ return $_encryption_key;
+ }
+
+ /////////////////////
+ // private methods
+ /////////////////////
+
+ /*!
+ */
+ function &_conn($conn=null) {
+ return $GLOBALS['ADODB_SESS_CONN'];
+ }
+
+ /*!
+ */
+ function _crc($crc = null) {
+ static $_crc = false;
+
+ if (!is_null($crc)) {
+ $_crc = $crc;
+ }
+
+ return $_crc;
+ }
+
+ /*!
+ */
+ function _init() {
+ session_module_name('user');
+ session_set_save_handler(
+ array('ADODB_Session', 'open'),
+ array('ADODB_Session', 'close'),
+ array('ADODB_Session', 'read'),
+ array('ADODB_Session', 'write'),
+ array('ADODB_Session', 'destroy'),
+ array('ADODB_Session', 'gc')
+ );
+ }
+
+
+ /*!
+ */
+ function _sessionKey() {
+ // use this function to create the encryption key for crypted sessions
+ // crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt
+ return crypt(ADODB_Session::encryptionKey(), session_id());
+ }
+
+ /*!
+ */
+ function _dumprs($rs) {
+ $conn =& ADODB_Session::_conn();
+ $debug = ADODB_Session::debug();
+
+ if (!$conn) {
+ return;
+ }
+
+ if (!$debug) {
+ return;
+ }
+
+ if (!$rs) {
+ echo "
\$rs is null or false
\n";
+ return;
+ }
+
+ //echo "
\nAffected_Rows=",$conn->Affected_Rows(),"
\n";
+
+ if (!is_object($rs)) {
+ return;
+ }
+
+ require_once ADODB_SESSION.'/../tohtml.inc.php';
+ rs2html($rs);
+ }
+
+ /////////////////////
+ // public methods
+ /////////////////////
+
+ /*!
+ Create the connection to the database.
+
+ If $conn already exists, reuse that connection
+ */
+ function open($save_path, $session_name, $persist = null) {
+ $conn =& ADODB_Session::_conn();
+
+ if ($conn) {
+ return true;
+ }
+
+ $database = ADODB_Session::database();
+ $debug = ADODB_Session::debug();
+ $driver = ADODB_Session::driver();
+ $host = ADODB_Session::host();
+ $password = ADODB_Session::password();
+ $user = ADODB_Session::user();
+
+ if (!is_null($persist)) {
+ $persist = (bool) $persist;
+ ADODB_Session::persist($persist);
+ } else {
+ $persist = ADODB_Session::persist();
+ }
+
+# these can all be defaulted to in php.ini
+# assert('$database');
+# assert('$driver');
+# assert('$host');
+
+ // cannot use =& below - do not know why...
+ $conn = ADONewConnection($driver);
+
+ if ($debug) {
+ $conn->debug = true;
+// ADOConnection::outp( " driver=$driver user=$user pwd=$password db=$database ");
+ }
+
+ if ($persist) {
+ $ok = $conn->PConnect($host, $user, $password, $database);
+ } else {
+ $ok = $conn->Connect($host, $user, $password, $database);
+ }
+
+ if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
+ else
+ ADOConnection::outp('Session: connection failed
', false);
+
+
+ return $ok;
+ }
+
+ /*!
+ Close the connection
+ */
+ function close() {
+ $conn =& ADODB_Session::_conn();
+
+ if ($conn) {
+ $conn->Close();
+ }
+
+ return true;
+ }
+
+ /*
+ Slurp in the session variables and return the serialized string
+ */
+ function read($key) {
+ $conn =& ADODB_Session::_conn();
+ $data = ADODB_Session::dataFieldName();
+ $filter = ADODB_Session::filter();
+ $table = ADODB_Session::table();
+
+ if (!$conn) {
+ return '';
+ }
+
+ assert('$table');
+
+ $qkey = $conn->quote($key);
+ $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
+
+ $sql = "SELECT $data FROM $table WHERE $binary sesskey = $qkey AND expiry >= " . time();
+ $rs =& $conn->Execute($sql);
+ //ADODB_Session::_dumprs($rs);
+ if ($rs) {
+ if ($rs->EOF) {
+ $v = '';
+ } else {
+ $v = reset($rs->fields);
+ $filter = array_reverse($filter);
+ foreach ($filter as $f) {
+ if (is_object($f)) {
+ $v = $f->read($v, ADODB_Session::_sessionKey());
+ }
+ }
+ $v = rawurldecode($v);
+ }
+
+ $rs->Close();
+
+ ADODB_Session::_crc(strlen($v) . crc32($v));
+ return $v;
+ }
+
+ return '';
+ }
+
+ /*!
+ Write the serialized data to a database.
+
+ If the data has not been modified since the last read(), we do not write.
+ */
+ function write($key, $val) {
+ $clob = ADODB_Session::clob();
+ $conn =& ADODB_Session::_conn();
+ $crc = ADODB_Session::_crc();
+ $data = ADODB_Session::dataFieldName();
+ $debug = ADODB_Session::debug();
+ $driver = ADODB_Session::driver();
+ $expire_notify = ADODB_Session::expireNotify();
+ $filter = ADODB_Session::filter();
+ $lifetime = ADODB_Session::lifetime();
+ $table = ADODB_Session::table();
+
+ if (!$conn) {
+ return false;
+ }
+
+ assert('$table');
+
+ $expiry = time() + $lifetime;
+
+ $qkey = $conn->quote($key);
+ $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
+
+ // crc32 optimization since adodb 2.1
+ // now we only update expiry date, thx to sebastian thom in adodb 2.32
+ if ($crc !== false && $crc == (strlen($val) . crc32($val))) {
+ if ($debug) {
+ echo 'Session: Only updating date - crc32 not changed
';
+ }
+ $sql = "UPDATE $table SET expiry = $expiry WHERE $binary sesskey = $qkey AND expiry >= " . time();
+ $rs =& $conn->Execute($sql);
+ ADODB_Session::_dumprs($rs);
+ if ($rs) {
+ $rs->Close();
+ }
+ return true;
+ }
+ $val = rawurlencode($val);
+ foreach ($filter as $f) {
+ if (is_object($f)) {
+ $val = $f->write($val, ADODB_Session::_sessionKey());
+ }
+ }
+
+ $arr = array('sesskey' => $key, 'expiry' => $expiry, $data => $val, 'expireref' => '');
+ if ($expire_notify) {
+ $var = reset($expire_notify);
+ global $$var;
+ if (isset($$var)) {
+ $arr['expireref'] = $$var;
+ }
+ }
+
+ if (!$clob) { // no lobs, simply use replace()
+ $rs = $conn->Replace($table, $arr, 'sesskey', $autoQuote = true);
+ ADODB_Session::_dumprs($rs);
+ } else {
+ // what value shall we insert/update for lob row?
+ switch ($driver) {
+ // empty_clob or empty_lob for oracle dbs
+ case 'oracle':
+ case 'oci8':
+ case 'oci8po':
+ case 'oci805':
+ $lob_value = sprintf('empty_%s()', strtolower($clob));
+ break;
+
+ // null for all other
+ default:
+ $lob_value = 'null';
+ break;
+ }
+
+ // do we insert or update? => as for sesskey
+ $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = $qkey");
+ ADODB_Session::_dumprs($rs);
+ if ($rs && reset($rs->fields) > 0) {
+ $sql = "UPDATE $table SET expiry = $expiry, $data = $lob_value WHERE sesskey = $qkey";
+ } else {
+ $sql = "INSERT INTO $table (expiry, $data, sesskey) VALUES ($expiry, $lob_value, $qkey)";
+ }
+ if ($rs) {
+ $rs->Close();
+ }
+
+ $err = '';
+ $rs1 =& $conn->Execute($sql);
+ ADODB_Session::_dumprs($rs1);
+ if (!$rs1) {
+ $err = $conn->ErrorMsg()."\n";
+ }
+ $rs2 =& $conn->UpdateBlob($table, $data, $val, " sesskey=$qkey", strtoupper($clob));
+ ADODB_Session::_dumprs($rs2);
+ if (!$rs2) {
+ $err .= $conn->ErrorMsg()."\n";
+ }
+ $rs = ($rs && $rs2) ? true : false;
+ if ($rs1) {
+ $rs1->Close();
+ }
+ if (is_object($rs2)) {
+ $rs2->Close();
+ }
+ }
+
+ if (!$rs) {
+ ADOConnection::outp('Session Replace: ' . $conn->ErrorMsg() . '
', false);
+ return false;
+ } else {
+ // bug in access driver (could be odbc?) means that info is not committed
+ // properly unless select statement executed in Win2000
+ if ($conn->databaseType == 'access') {
+ $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
+ $rs =& $conn->Execute($sql);
+ ADODB_Session::_dumprs($rs);
+ if ($rs) {
+ $rs->Close();
+ }
+ }
+ }
+ return $rs ? true : false;
+ }
+
+ /*!
+ */
+ function destroy($key) {
+ $conn =& ADODB_Session::_conn();
+ $table = ADODB_Session::table();
+ $expire_notify = ADODB_Session::expireNotify();
+
+ if (!$conn) {
+ return false;
+ }
+
+ assert('$table');
+
+ $qkey = $conn->quote($key);
+ $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
+
+ if ($expire_notify) {
+ reset($expire_notify);
+ $fn = next($expire_notify);
+ $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
+ $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
+ $rs =& $conn->Execute($sql);
+ ADODB_Session::_dumprs($rs);
+ $conn->SetFetchMode($savem);
+ if (!$rs) {
+ return false;
+ }
+ if (!$rs->EOF) {
+ $ref = $rs->fields[0];
+ $key = $rs->fields[1];
+ assert('$ref');
+ assert('$key');
+ $fn($ref, $key);
+ }
+ $rs->Close();
+ }
+
+ $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
+ $rs =& $conn->Execute($sql);
+ ADODB_Session::_dumprs($rs);
+ if ($rs) {
+ $rs->Close();
+ }
+
+ return $rs ? true : false;
+ }
+
+ /*!
+ */
+ function gc($maxlifetime) {
+ $conn =& ADODB_Session::_conn();
+ $debug = ADODB_Session::debug();
+ $expire_notify = ADODB_Session::expireNotify();
+ $optimize = ADODB_Session::optimize();
+ $sync_seconds = ADODB_Session::syncSeconds();
+ $table = ADODB_Session::table();
+
+ if (!$conn) {
+ return false;
+ }
+
+ assert('$table');
+
+ $time = time();
+
+ $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
+
+ if ($expire_notify) {
+ reset($expire_notify);
+ $fn = next($expire_notify);
+ $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
+ $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time";
+ $rs =& $conn->Execute($sql);
+ ADODB_Session::_dumprs($rs);
+ $conn->SetFetchMode($savem);
+ if ($rs) {
+ $conn->BeginTrans();
+ $keys = array();
+ while (!$rs->EOF) {
+ $ref = $rs->fields[0];
+ $key = $rs->fields[1];
+ $fn($ref, $key);
+ $del = $conn->Execute("DELETE FROM $table WHERE sesskey='$key'");
+ $rs->MoveNext();
+ }
+ $rs->Close();
+
+ $conn->CommitTrans();
+ }
+ } else {
+ $sql = "DELETE FROM $table WHERE expiry < $time";
+ $rs =& $conn->Execute($sql);
+ ADODB_Session::_dumprs($rs);
+ if ($rs) {
+ $rs->Close();
+ }
+ if ($debug) {
+ ADOConnection::outp("Garbage Collection: $sql
");
+ }
+ }
+
+ // suggested by Cameron, "GaM3R"
+ if ($optimize) {
+ $driver = ADODB_Session::driver();
+
+ if (preg_match('/mysql/i', $driver)) {
+ $sql = "OPTIMIZE TABLE $table";
+ }
+ if (preg_match('/postgres/i', $driver)) {
+ $sql = "VACUUM $table";
+ }
+ if (!empty($sql)) {
+ $conn->Execute($sql);
+ }
+ }
+
+ if ($sync_seconds) {
+ $sql = 'SELECT ';
+ if ($conn->dataProvider === 'oci8') {
+ $sql .= "TO_CHAR({$conn->sysTimeStamp}, 'RRRR-MM-DD HH24:MI:SS')";
+ } else {
+ $sql .= $conn->sysTimeStamp;
+ }
+ $sql .= " FROM $table";
+
+ $rs =& $conn->SelectLimit($sql, 1);
+ if ($rs && !$rs->EOF) {
+ $dbts = reset($rs->fields);
+ $rs->Close();
+ $dbt = $conn->UnixTimeStamp($dbts);
+ $t = time();
+
+ if (abs($dbt - $t) >= $sync_seconds) {
+ global $HTTP_SERVER_VARS;
+ $msg = __FILE__ .
+ ": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: " .
+ " database=$dbt ($dbts), webserver=$t (diff=". (abs($dbt - $t) / 3600) . ' hours)';
+ error_log($msg);
+ if ($debug) {
+ ADOConnection::outp("$msg
");
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+}
+
+ADODB_Session::_init();
+
+
+// for backwards compatability only
+function adodb_sess_open($save_path, $session_name, $persist = true) {
+ return ADODB_Session::open($save_path, $session_name, $persist);
+}
+
+// for backwards compatability only
+function adodb_sess_gc($t)
+{
+ return ADODB_Session::gc($t);
+}
+
+?>
diff --git a/lib/adodb/session/adodb-sessions.mysql.sql b/lib/adodb/session/adodb-sessions.mysql.sql
new file mode 100644
index 00000000000..f90de449313
--- /dev/null
+++ b/lib/adodb/session/adodb-sessions.mysql.sql
@@ -0,0 +1,16 @@
+-- $CVSHeader$
+
+CREATE DATABASE /*! IF NOT EXISTS */ adodb_sessions;
+
+USE adodb_sessions;
+
+DROP TABLE /*! IF EXISTS */ sessions;
+
+CREATE TABLE /*! IF NOT EXISTS */ sessions (
+ sesskey CHAR(32) /*! BINARY */ NOT NULL DEFAULT '',
+ expiry INT(11) /*! UNSIGNED */ NOT NULL DEFAULT 0,
+ expireref VARCHAR(64) DEFAULT '',
+ data LONGTEXT DEFAULT '',
+ PRIMARY KEY (sesskey),
+ INDEX expiry (expiry)
+);
diff --git a/lib/adodb/session/adodb-sessions.oracle.clob.sql b/lib/adodb/session/adodb-sessions.oracle.clob.sql
new file mode 100644
index 00000000000..c5c4f2d0700
--- /dev/null
+++ b/lib/adodb/session/adodb-sessions.oracle.clob.sql
@@ -0,0 +1,15 @@
+-- $CVSHeader$
+
+DROP TABLE adodb_sessions;
+
+CREATE TABLE sessions (
+ sesskey CHAR(32) DEFAULT '' NOT NULL,
+ expiry INT DEFAULT 0 NOT NULL,
+ expireref VARCHAR(64) DEFAULT '',
+ data CLOB DEFAULT '',
+ PRIMARY KEY (sesskey)
+);
+
+CREATE INDEX ix_expiry ON sessions (expiry);
+
+QUIT;
diff --git a/lib/adodb/session/adodb-sessions.oracle.sql b/lib/adodb/session/adodb-sessions.oracle.sql
new file mode 100644
index 00000000000..8fd5a342329
--- /dev/null
+++ b/lib/adodb/session/adodb-sessions.oracle.sql
@@ -0,0 +1,16 @@
+-- $CVSHeader$
+
+DROP TABLE adodb_sessions;
+
+CREATE TABLE sessions (
+ sesskey CHAR(32) DEFAULT '' NOT NULL,
+ expiry INT DEFAULT 0 NOT NULL,
+ expireref VARCHAR(64) DEFAULT '',
+ data VARCHAR(4000) DEFAULT '',
+ PRIMARY KEY (sesskey),
+ INDEX expiry (expiry)
+);
+
+CREATE INDEX ix_expiry ON sessions (expiry);
+
+QUIT;
diff --git a/lib/adodb/session/crypt.inc.php b/lib/adodb/session/crypt.inc.php
new file mode 100644
index 00000000000..7266ab619df
--- /dev/null
+++ b/lib/adodb/session/crypt.inc.php
@@ -0,0 +1,64 @@
+
+class MD5Crypt{
+ function keyED($txt,$encrypt_key)
+ {
+ $encrypt_key = md5($encrypt_key);
+ $ctr=0;
+ $tmp = "";
+ for ($i=0;$ikeyED($tmp,$key));
+ }
+
+ function Decrypt($txt,$key)
+ {
+ $txt = $this->keyED(base64_decode($txt),$key);
+ $tmp = "";
+ for ($i=0;$i= 58 && $randnumber <= 64) || ($randnumber >= 91 && $randnumber <= 96))
+ {
+ $randnumber = rand(48,120);
+ }
+
+ $randomPassword .= chr($randnumber);
+ }
+ return $randomPassword;
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/lib/adodb/tests/benchmark.php b/lib/adodb/tests/benchmark.php
index 76db3c12a0b..484b9cc78b9 100644
--- a/lib/adodb/tests/benchmark.php
+++ b/lib/adodb/tests/benchmark.php
@@ -8,7 +8,7 @@
Connect('localhost','tester','test','test') || die("failed connection");
+
+$enc = "GIF89a%01%00%01%00%80%FF%00%C0%C0%C0%00%00%00%21%F9%04%01%00%00%00%00%2C%00%00%00%00%01%00%01%00%00%01%012%00%3Bt_clear.gif%0D";
+$val = rawurldecode($enc);
+$db->debug=1;
+
+### TEST BEGINS
+
+$db->Execute("insert into photos (id,name) values(9999,'dot.gif')");
+$db->UpdateBlob('photos','photo',$val,'id=9999');
+$v = $db->GetOne('select photo from photos where id=9999');
+
+
+### CLEANUP
+
+$db->Execute("delete from photos where id=9999");
+
+### VALIDATION
+
+if ($v !== $val) echo "*** ERROR: Inserted value does not match downloaded val";
+else echo "*** OK: Passed";
+
+echo "";
+echo "INSERTED: ", $enc;
+echo "
";
+echo"RETURNED: ", rawurlencode($v);
+echo "
";
+echo "INSERTED: ", $val;
+echo "
";
+echo "RETURNED: ", $v;
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/tests/test-php5.php b/lib/adodb/tests/test-php5.php
new file mode 100644
index 00000000000..033f667a243
--- /dev/null
+++ b/lib/adodb/tests/test-php5.php
@@ -0,0 +1,56 @@
+Connect('','scott','natsoft');
+ break;
+default:
+case 'mysql':
+ $db = NewADOConnection("mysql");
+ $db->Connect('localhost','root','','test');
+ break;
+}
+
+$db->debug=1;
+
+$cnt = $db->GetOne("select count(*) from adoxyz");
+$rs = $db->Execute("select * from adoxyz order by id");
+
+$i = 0;
+foreach($rs as $v) {
+ $i += 1;
+ echo "$i: "; adodb_pr($v); adodb_pr($rs->fields);
+ flush();
+}
+
+if ($i != $cnt) die("actual cnt is $i, cnt should be $cnt\n");
+
+
+$rs = $db->Execute("select bad from badder");
+
+} catch (exception $e) {
+ adodb_pr($e);
+ $e = adodb_backtrace($e->trace);
+}
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/tests/test-xmlschema.php b/lib/adodb/tests/test-xmlschema.php
index 80058f71b6f..aa3b4e8be9b 100644
--- a/lib/adodb/tests/test-xmlschema.php
+++ b/lib/adodb/tests/test-xmlschema.php
@@ -1,6 +1,6 @@
date1 (1969-02-20) = ".$db->DBDate('1969-2-20');
print "
date1 (1999-02-20) = ".$db->DBDate('1999-2-20');
+ print "
date1.1 1999 = ".$db->DBDate("'1999'");
print "
date2 (1970-1-2) = ".$db->DBDate(24*3600)."";
print "ts1 (1999-02-20 13:40:50) = ".$db->DBTimeStamp('1999-2-20 1:40:50 pm');
print "
ts1.1 (1999-02-20 13:40:00) = ".$db->DBTimeStamp('1999-2-20 13:40');
@@ -126,6 +127,10 @@ FROM `nuke_stories` `t1`, `nuke_authors` `t2`, `nuke_stories_cat` `t3`, `nuke_to
print "
Fractional TS (1999-2-20 13:40:50.91): ".$db->DBTimeStamp($db->UnixTimeStamp('1999-2-20 13:40:50.91+1'));
$dd = $db->UnixDate('1999-02-20');
print "
unixdate 1999-02-20 = ".date('Y-m-d',$dd)."
";
+ print "
ts4 =".($db->UnixTimeStamp("19700101000101")+8*3600);
+ print "
ts5 =".$db->DBTimeStamp($db->UnixTimeStamp("20040110092123"));
+ print "
ts6 =".$db->UserTimeStamp("20040110092123");
+ print "
ts6 =".$db->DBTimeStamp("20040110092123");
flush();
// mssql too slow in failing bad connection
if (false && $db->databaseType != 'mssql') {
@@ -260,8 +265,18 @@ FROM `nuke_stories` `t1`, `nuke_authors` `t2`, `nuke_stories_cat` `t3`, `nuke_to
$a = $db->MetaColumns('ADOXYZ');
if ($a===false) print "MetaColumns not supported
";
else {
- print "Columns of ADOXYZ: ";
- foreach($a as $v) print " ($v->name $v->type $v->max_length) ";
+ print "
Columns of ADOXYZ:
";
+ foreach($a as $v) {print_r($v); echo "
";}
+ echo "";
+ }
+
+ print "
Testing MetaIndexes
";
+ $a = $db->MetaIndexes('ADOXYZ',true);
+ if ($a===false) print "MetaIndexes not supported";
+ else {
+ print "Indexes of ADOXYZ:
";
+ foreach($a as $v) {print_r($v); echo "
";}
+ echo "";
}
print "
Testing MetaPrimaryKeys
";
$a = $db->MetaPrimaryKeys('ADOXYZ');
@@ -329,8 +344,8 @@ GO
$yr = '1998';
$stmt = $db->PrepareSP('SalesByCategory');
- $db->Parameter($stmt,$cat,'CategoryName');
- $db->Parameter($stmt,$yr,'OrdYear');
+ $db->InParameter($stmt,$cat,'CategoryName');
+ $db->InParameter($stmt,$yr,'OrdYear');
$rs = $db->Execute($stmt);
rs2html($rs);
@@ -338,8 +353,8 @@ GO
$yr = 1998;
$stmt = $db->PrepareSP('SalesByCategory');
- $db->Parameter($stmt,$cat,'CategoryName');
- $db->Parameter($stmt,$yr,'OrdYear');
+ $db->InParameter($stmt,$cat,'CategoryName');
+ $db->InParameter($stmt,$yr,'OrdYear');
$rs = $db->Execute($stmt);
rs2html($rs);
@@ -362,9 +377,9 @@ GO
$days = 10;
$begin_date = '';
$end_date = '';
- $db->Parameter($stmt,$days,'days', false, 4, SQLINT4);
- $db->Parameter($stmt,$begin_date,'start', 1, 20, SQLVARCHAR );
- $db->Parameter($stmt,$end_date,'end', 1, 20, SQLVARCHAR );
+ $db->InParameter($stmt,$days,'days', 4, SQLINT4);
+ $db->OutParameter($stmt,$begin_date,'start', 20, SQLVARCHAR );
+ $db->OutParameter($stmt,$end_date,'end', 20, SQLVARCHAR );
$db->Execute($stmt);
if (empty($begin_date) or empty($end_date)) {
Err("MSSQL SP Test for OUT Failed");
@@ -388,6 +403,7 @@ GO
CREATE OR REPLACE PACKAGE adodb AS
TYPE TabType IS REF CURSOR RETURN tab%ROWTYPE;
PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar);
+PROCEDURE data_out(input IN varchar, output OUT varchar);
END adodb;
/
@@ -396,12 +412,16 @@ PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar) IS
BEGIN
OPEN tabcursor FOR SELECT * FROM tab where tname like tablenames;
END open_tab;
+
+PROCEDURE data_out(input IN varchar, output OUT varchar) IS
+ BEGIN
+ output := 'Cinta Hati '||input;
+ END;
END adodb;
-
/
-*/
+*/
$stmt = $db->Prepare("BEGIN adodb.open_tab(:RS,'A%'); END;");
- $db->Parameter($stmt, $cur, 'RS', false, -1, OCI_B_CURSOR);
+ $db->InParameter($stmt, $cur, 'RS', -1, OCI_B_CURSOR);
$rs = $db->Execute($stmt);
if ($rs && !$rs->EOF) {
@@ -410,15 +430,22 @@ END adodb;
print "Error in using Cursor Variables 1";
}
- $rs = $db->ExecuteCursor("BEGIN adodb.open_tab(:RS2,:TAB); END;",'RS2',array('TAB'=>'A%'));
- if ($rs && !$rs->EOF) {
- print "Test 2 RowCount: ".$rs->RecordCount()."
";
- } else {
- print "Error in using Cursor Variables 2
";
- }
print "
Testing Stored Procedures for oci8
";
-
+
+ $stmt = $db->PrepareSP("BEGIN adodb.data_out(:a1, :a2); END;");
+ $a1 = 'Malaysia';
+ //$a2 = ''; # a2 doesn't even need to be defined!
+ $db->InParameter($stmt,$a1,'a1');
+ $db->OutParameter($stmt,$a2,'a2');
+ $rs = $db->Execute($stmt);
+ if ($rs) {
+ if ($a2 !== 'Cinta Hati Malaysia') print "Stored Procedure Error: a2 = $a2";
+ else echo "OK: a2=$a2
";
+ } else {
+ print "Error in using Stored Procedure IN/Out Variables
";
+ }
+
$tname = 'A%';
@@ -530,6 +557,7 @@ END adodb;
$db->Execute("insert into ADOXYZ (id,firstname,lastname,created) values ($i*10+9,'Steven','Oey',$time )");
} // for
if (1) {
+ $db->debug=1;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$cnt = $db->GetOne("select count(*) from ADOXYZ");
$rs = $db->Execute('update ADOXYZ set id=id+1');
@@ -555,23 +583,24 @@ END adodb;
print "
Error on RecordCount. Should be 0. Was ".$rs->RecordCount()."
";
print_r($rs->fields);
}
- $rs = &$db->Execute("select id,firstname,lastname,created from ADOXYZ order by id");
- if ($rs) {
- if ($rs->RecordCount() != 50) {
- print "RecordCount returns ".$rs->RecordCount()."
";
- $poc = $rs->PO_RecordCount('ADOXYZ');
- if ($poc == 50) print " PO_RecordCount passed
";
- else print "PO_RecordCount returns wrong value: $poc
";
- } else print "RecordCount() passed
";
- if (isset($rs->fields['firstname'])) print 'The fields columns can be indexed by column name.
';
- else {
- Err( 'The fields columns cannot be indexed by column name.
');
- print_r($rs->fields);
+ if ($db->databaseType !== 'odbc') {
+ $rs = &$db->Execute("select id,firstname,lastname,created,".$db->random." from ADOXYZ order by id");
+ if ($rs) {
+ if ($rs->RecordCount() != 50) {
+ print "RecordCount returns ".$rs->RecordCount()."
";
+ $poc = $rs->PO_RecordCount('ADOXYZ');
+ if ($poc == 50) print " PO_RecordCount passed
";
+ else print "PO_RecordCount returns wrong value: $poc
";
+ } else print "RecordCount() passed
";
+ if (isset($rs->fields['firstname'])) print 'The fields columns can be indexed by column name.
';
+ else {
+ Err( 'The fields columns cannot be indexed by column name.
');
+ print_r($rs->fields);
+ }
+ if (empty($HTTP_GET_VARS['hide'])) rs2html($rs);
}
- if (empty($HTTP_GET_VARS['hide'])) rs2html($rs);
+ else print "Error in Execute of SELECT with random";
}
- else print "Error in Execute of SELECT";
-
$val = $db->GetOne("select count(*) from ADOXYZ");
if ($val == 50) print "GetOne returns ok
";
else print "Fail: GetOne returns $val
";
@@ -1076,6 +1105,7 @@ END adodb;
err('**** RSFilter failed');
print_r($rs->fields);
}
+
rs2html($rs);
$db->debug=1;
@@ -1138,7 +1168,10 @@ END adodb;
'firstname', # row fields
'lastname', # column fields
false, # join
- 'ID' # sum
+ 'ID', # sum
+ 'Sum ', # label for sum
+ 'sum', # aggregate function
+ true
);
$rs = $db->Execute($sql);
if ($rs) rs2html($rs);
@@ -1205,13 +1238,16 @@ END adodb;
if ($ds != date("d m Y")) Err("Bad UserDate: ".$ds);
else echo "Passed UserDate: $ds";
}
-
- $rs = $db->SelectLimit("select ".$db->sysTimeStamp." from adoxyz",1);
+ $db->debug=1;
+ if ($db->dataProvider == 'oci8')
+ $rs = $db->SelectLimit("select to_char(".$db->sysTimeStamp.",'YYYY-MM-DD HH24:MI:SS') from adoxyz",1);
+ else
+ $rs = $db->SelectLimit("select ".$db->sysTimeStamp." from adoxyz",1);
$date = $rs->fields[0];
if (!$date) Err("Bad sysTimeStamp");
else {
$ds = $db->UserTimeStamp($date,"H \\h\\r\\s-d m Y");
- if ($ds != date("H \\h\\r\\s-d m Y")) Err("Bad UserTimeStamp: ".$ds);
+ if ($ds != date("H \\h\\r\\s-d m Y")) Err("Bad UserTimeStamp: ".$ds.", correct is ".date("H \\h\\r\\s-d m Y"));
else echo "Passed UserTimeStamp: $ds
";
$date = 100;
@@ -1408,6 +1444,6 @@ include('./testdatabases.inc.php');
include_once('../adodb-time.inc.php');
adodb_date_test();
?>
-
ADODB Database Library (c) 2000-2003 John Lim. All rights reserved. Released under BSD and LGPL.
+ADODB Database Library (c) 2000-2004 John Lim. All rights reserved. Released under BSD and LGPL.
diff --git a/lib/adodb/tests/test2.php b/lib/adodb/tests/test2.php
index 266fdd82591..177aa8e94e9 100644
--- a/lib/adodb/tests/test2.php
+++ b/lib/adodb/tests/test2.php
@@ -8,7 +8,7 @@
PConnect("susetikus","tester","test","test"))
- die("Cannot connect to database");
-# select * from last table in DB
-$rs = $c1->Execute("select * from adoxyz order by 1");
+error_reporting(E_ALL);
+
+$path = dirname(__FILE__);
+
+include("$path/../adodb-exceptions.inc.php");
+include("$path/../adodb.inc.php");
+
+try {
+$db = NewADOConnection("oci8");
+$db->Connect('','scott','natsoft');
+$db->debug=1;
+
+$cnt = $db->GetOne("select count(*) from adoxyz");
+$rs = $db->Execute("select * from adoxyz order by id");
$i = 0;
-$max = $rs->RecordCount();
-if ($max == -1) "RecordCount returns -1
";
-while (!$rs->EOF and $i < $max) {
- $rs->Move($i);
- print_r( $rs->fields);
- print '
';
- $i++;
+foreach($rs as $k => $v) {
+ $i += 1;
+ echo $k; adodb_pr($v);
+ flush();
}
-?>
-
\ No newline at end of file
+
+if ($i != $cnt) die("actual cnt is $i, cnt should be $cnt\n");
+
+
+
+$rs = $db->Execute("select bad from badder");
+
+} catch (exception $e) {
+ adodb_pr($e);
+ $e = adodb_backtrace($e->trace);
+}
+
+?>
\ No newline at end of file
diff --git a/lib/adodb/tests/test4.php b/lib/adodb/tests/test4.php
index 7648ddd8bd7..9a261b13a10 100644
--- a/lib/adodb/tests/test4.php
+++ b/lib/adodb/tests/test4.php
@@ -1,7 +1,7 @@
qstr($record['lastname']);
$rs = $conn->Execute($sql); // Execute the query and get the existing record to update
if (!$rs) print "No record found!
";
+
$record = array(); // Initialize an array to hold the record data to update
// Set the values for the fields in the record
diff --git a/lib/adodb/tests/test5.php b/lib/adodb/tests/test5.php
index 3c1ef063db3..5308f2b1386 100644
--- a/lib/adodb/tests/test5.php
+++ b/lib/adodb/tests/test5.php
@@ -1,6 +1,6 @@
InitArray($array,$typearr);
+
+while (!$rs->EOF) {
+ print_r($rs->fields);echo "
";
+ $rs->MoveNext();
+}
+
+echo "
1 Seek
";
+$rs->Move(1);
+while (!$rs->EOF) {
+ print_r($rs->fields);echo "
";
+ $rs->MoveNext();
+}
+
+echo "
2 Seek
";
+$rs->Move(2);
+while (!$rs->EOF) {
+ print_r($rs->fields);echo "
";
+ $rs->MoveNext();
+}
+
+echo "
3 Seek
";
+$rs->Move(3);
+while (!$rs->EOF) {
+ print_r($rs->fields);echo "
";
+ $rs->MoveNext();
+}
+
+
+
+die();
+?>
\ No newline at end of file
diff --git a/lib/adodb/tests/testcache.php b/lib/adodb/tests/testcache.php
index 7881e836fe8..c926a2a32ed 100644
--- a/lib/adodb/tests/testcache.php
+++ b/lib/adodb/tests/testcache.php
@@ -2,7 +2,7 @@
debug=1;
print "Connecting $db->databaseType...
";
- $db->PConnect('tigress','adodb','natsoft','northwind');
-
- if (true or @$db->PConnect("mangrove", "sa", "natsoft", "ai")) {
+ $ok = $db->PConnect('tigress','adodb','natsoft','northwind');
+ //$rs = $db->Execute("exec sp_ddate");
+ //print_r($rs->fields);
+ //die();
+
+ if ($ok or @$db->PConnect("mangrove", "sa", "natsoft", "ai")) {
AutoDetect_MSSQL_Date_Order($db);
// $db->Execute('drop table adoxyz');
testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
@@ -271,7 +273,7 @@ if (!empty($testmssql) && !empty($testado)) { // ADO ACCESS MSSQL with OLEDB pro
//$db->debug=1;
$myDSN="SERVER=tigress;DATABASE=northwind;Trusted_Connection=yes";
//$myDSN='SERVER=(local)\NetSDK;DATABASE=northwind;';
- if ($db->PConnect($myDSN, "sa", "natsoft", 'SQLOLEDB'))
+ if ($db->PConnect($myDSN, "adodb", "natsoft", 'SQLOLEDB'))
testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
else print "ERROR: MSSQL test 2 requires a MS SQL 7 on a server='mangrove', userid='sa', password='', database='ai'";
diff --git a/lib/adodb/tests/testgenid.php b/lib/adodb/tests/testgenid.php
index f1f946349f8..05554dd29d7 100644
--- a/lib/adodb/tests/testgenid.php
+++ b/lib/adodb/tests/testgenid.php
@@ -1,6 +1,6 @@
PConnect('','scott','tiger');
- $db->debug = true;
+ $db->PConnect('','scott','natsoft');
+ $db->debug = 99;
+/*
+-- TEST PACKAGE
+CREATE OR REPLACE PACKAGE adodb AS
+TYPE TabType IS REF CURSOR RETURN tab%ROWTYPE;
+PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar);
+PROCEDURE data_out(input IN varchar, output OUT varchar);
+END adodb;
+/
- #---------------------------------------------------------------
- # EXAMPLE 1
- # explicitly use Parameter function
- #---------------------------------------------------------------
- $stmt = $db->Prepare("BEGIN adodb.open_tab(:RS,'%'); END;");
- $db->Parameter($stmt, $cur, 'RS', false, -1, OCI_B_CURSOR);
- $rs = $db->Execute($stmt);
+CREATE OR REPLACE PACKAGE BODY adodb AS
+PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar) IS
+ BEGIN
+ OPEN tabcursor FOR SELECT * FROM tab where tname like tablenames;
+ END open_tab;
+PROCEDURE data_out(input IN varchar, output OUT varchar) IS
+ BEGIN
+ output := 'Cinta Hati '||input;
+ END;
+END adodb;
+/
+*/
+ $stmt = $db->Prepare("BEGIN adodb.open_tab(:RS,'A%'); END;");
+ $db->InParameter($stmt, $cur, 'RS', -1, OCI_B_CURSOR);
+ $rs = $db->Execute($stmt);
+
if ($rs && !$rs->EOF) {
print "Test 1 RowCount: ".$rs->RecordCount()."";
} else {
print "Error in using Cursor Variables 1
";
}
- #---------------------------------------------------------------
- # EXAMPLE 2
- # Equivalent of above example 1 using ExecuteCursor($sql,$rsname)
- #---------------------------------------------------------------
- $rs = $db->ExecuteCursor(
- "BEGIN adodb.open_tab(:RS,'%'); END;", # pl/sql script
- 'RS'); # cursor name
-
- if ($rs && !$rs->EOF) {
- print "Test 2 RowCount: ".$rs->RecordCount()."
";
- rs2html($rs);
+
+ print "
Testing Stored Procedures for oci8
";
+
+ $stmt = $db->PrepareSP("BEGIN adodb.data_out(:a1, :a2); END;",true);
+ $a1 = 'Malaysia';
+ //$a2 = ''; # a2 doesn't even need to be defined!
+ $db->InParameter($stmt,$a1,'a1');
+ $db->OutParameter($stmt,$a2,'a2');
+ $rs = $db->Execute($stmt);
+ if ($rs) {
+ if ($a2 !== 'Cinta Hati Malaysia') print "Stored Procedure Error: a2 = $a2";
+ else echo "OK: a2=$a2
";
} else {
- print "Error in using Cursor Variables 2
";
+ print "Error in using Stored Procedure IN/Out Variables
";
}
+
+
+ $tname = 'A%';
+
+ $stmt = $db->PrepareSP('select * from tab where tname like :tablename');
+ $db->Parameter($stmt,$tname,'tablename');
+ $rs = $db->Execute($stmt);
+ rs2html($rs);
+
?>
\ No newline at end of file
diff --git a/lib/adodb/tests/testpaging.php b/lib/adodb/tests/testpaging.php
index b0bbcfd2fc7..3cf29aaf7d3 100644
--- a/lib/adodb/tests/testpaging.php
+++ b/lib/adodb/tests/testpaging.php
@@ -1,6 +1,6 @@
PHP ".PHP_VERSION."";
-
+
+
+### SETUP SESSION VARIABLES
$HTTP_SESSION_VARS['MONKEY'] = array('1','abc',44.41);
if (!isset($HTTP_GET_VARS['nochange'])) @$HTTP_SESSION_VARS['AVAR'] += 1;
+
+### START DISPLAY
+ print "
PHP ".PHP_VERSION."
";
print "\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}
";
+ print "
Cookies: ";
+ print_r($HTTP_COOKIE_VARS);
+
+### RANDOMLY PERFORM Garbage Collection
if (rand() % 10 == 0) {
- print "GC
";
+ print "
Garbage Collection
";
adodb_sess_gc(10);
print "Random session destroy
";
session_destroy();
}
- print "
";
- print_r($HTTP_COOKIE_VARS);
?>
\ No newline at end of file
diff --git a/lib/adodb/tests/tmssql.php b/lib/adodb/tests/tmssql.php
index a3b743ca1f4..e20db41ed29 100644
--- a/lib/adodb/tests/tmssql.php
+++ b/lib/adodb/tests/tmssql.php
@@ -1,65 +1,65 @@
-mssql";
- $db = mssql_connect('JAGUAR\vsdotnet','adodb','natsoft') or die('No Connection');
- mssql_select_db('northwind',$db);
-
- $rs = mssql_query('select getdate() as date',$db);
- $o = mssql_fetch_row($rs);
- print_r($o);
- mssql_free_result($rs);
-
- print "Delete
"; flush();
- $rs2 = mssql_query('delete from adoxyz',$db);
- $p = mssql_num_rows($rs2);
- mssql_free_result($rs2);
-
-}
-
-function tpear()
-{
-include_once('DB.php');
-
- print "PEAR
";
- $username = 'adodb';
- $password = 'natsoft';
- $hostname = 'JAGUAR\vsdotnet';
- $databasename = 'northwind';
-
- $dsn = "mssql://$username:$password@$hostname/$databasename";
- $conn = &DB::connect($dsn);
- print "date=".$conn->GetOne('select getdate()')."
";
- @$conn->query('create table tester (id integer)');
- print "Delete
"; flush();
- $rs = $conn->query('delete from tester');
- print "date=".$conn->GetOne('select getdate()')."
";
-}
-
-function tadodb()
-{
-include_once('../adodb.inc.php');
-
- print "ADOdb
";
- $conn = NewADOConnection('mssql');
- $conn->Connect('JAGUAR\vsdotnet','adodb','natsoft','northwind');
-// $conn->debug=1;
- print "date=".$conn->GetOne('select getdate()')."
";
- $conn->Execute('create table tester (id integer)');
- print "Delete
"; flush();
- $rs = $conn->Execute('delete from tester');
- print "date=".$conn->GetOne('select getdate()')."
";
-}
-?>
-mssql
-pear
-adodb
-mssql";
+ $db = mssql_connect('JAGUAR\vsdotnet','adodb','natsoft') or die('No Connection');
+ mssql_select_db('northwind',$db);
+
+ $rs = mssql_query('select getdate() as date',$db);
+ $o = mssql_fetch_row($rs);
+ print_r($o);
+ mssql_free_result($rs);
+
+ print "Delete
"; flush();
+ $rs2 = mssql_query('delete from adoxyz',$db);
+ $p = mssql_num_rows($rs2);
+ mssql_free_result($rs2);
+
+}
+
+function tpear()
+{
+include_once('DB.php');
+
+ print "PEAR
";
+ $username = 'adodb';
+ $password = 'natsoft';
+ $hostname = 'JAGUAR\vsdotnet';
+ $databasename = 'northwind';
+
+ $dsn = "mssql://$username:$password@$hostname/$databasename";
+ $conn = &DB::connect($dsn);
+ print "date=".$conn->GetOne('select getdate()')."
";
+ @$conn->query('create table tester (id integer)');
+ print "Delete
"; flush();
+ $rs = $conn->query('delete from tester');
+ print "date=".$conn->GetOne('select getdate()')."
";
+}
+
+function tadodb()
+{
+include_once('../adodb.inc.php');
+
+ print "ADOdb
";
+ $conn = NewADOConnection('mssql');
+ $conn->Connect('JAGUAR\vsdotnet','adodb','natsoft','northwind');
+// $conn->debug=1;
+ print "date=".$conn->GetOne('select getdate()')."
";
+ $conn->Execute('create table tester (id integer)');
+ print "Delete
"; flush();
+ $rs = $conn->Execute('delete from tester');
+ print "date=".$conn->GetOne('select getdate()')."
";
+}
+?>
+mssql
+pear
+adodb
+
\ No newline at end of file
diff --git a/lib/adodb/tips_portable_sql.htm b/lib/adodb/tips_portable_sql.htm
index e0dd414914f..fc438fb0ffd 100644
--- a/lib/adodb/tips_portable_sql.htm
+++ b/lib/adodb/tips_portable_sql.htm
@@ -8,7 +8,9 @@
Tips on Writing Portable SQL |
|
-
+ Updated 18 Sep 2003. Added Portable Native SQL section.
+
+
If you are writing an application that is used in multiple environments and
operating systems, you need to plan to support multiple databases. This article
is based on my experiences with multiple database systems, stretching from 4th
@@ -166,17 +168,18 @@ the correct placeholder (available since ADOdb 3.92):
$stmt = $DB->Prepare($sql);
$stmt = $DB->Execute($stmt,array('one','two'));
+
Portable Native SQL
ADOdb provides the following functions for portably generating SQL functions
as strings to be merged into your SQL statements (some are only available since
ADOdb 3.92):
-
+
- | Function |
+ Function |
Description |
- | DBDate($date) |
+ DBDate($date) |
Pass in a UNIX timestamp or ISO date and it will convert it to a date
string formatted for INSERT/UPDATE |
@@ -207,6 +210,26 @@ $stmt = $DB->Execute($stmt,array('one','two'));
Param($name) |
Generates bind placeholders, using ? or named conventions as appropriate. |
+ | $db->sysDate | Property that holds the SQL function that returns today's date |
+
+| $db->sysTimeStamp | Property that holds the SQL function that returns the current
+timestamp (date+time).
+ |
+
+
+| $db->concat_operator | Property that holds the concatenation operator
+ |
+
+| $db->length | Property that holds the name of the SQL strlen function.
+ |
+
+| $db->upperCase | Property that holds the name of the SQL strtoupper function.
+ |
+| $db->random | Property that holds the SQL to generate a random number between 0.00 and 1.00.
+ |
+
+| $db->substr | Property that holds the name of the SQL substring function.
+ |
DDL and Tuning
@@ -269,6 +292,9 @@ $conn->UpdateBlob('blobtable','blobcol',$blobvalue,'id=1');
ambiguities when you use the ANY and EXISTS operators. However if your database
has significant amounts of missing or unknown data, using nulls might be a good
idea.
+
+ ADOdb also supports a portable IfNull function, so you can define what to display
+ if the field contains a null.
Stored Procedures
Stored procedures are another problem area. Some databases allow recordsets
to be returned in a stored procedure (Microsoft SQL Server and Sybase), and
diff --git a/lib/adodb/toexport.inc.php b/lib/adodb/toexport.inc.php
index 05fd2036f7e..c5a63fc54e8 100644
--- a/lib/adodb/toexport.inc.php
+++ b/lib/adodb/toexport.inc.php
@@ -1,7 +1,7 @@
FieldTypesArray();
- foreach($fieldTypes as $o) {
+ reset($fieldTypes);
+ while(list(,$o) = each($fieldTypes)) {
$v = $o->name;
if ($escquote) $v = str_replace($quote,$escquotequote,$v);
diff --git a/lib/adodb/tohtml.inc.php b/lib/adodb/tohtml.inc.php
index cf08639b5fe..d42c7d8993d 100644
--- a/lib/adodb/tohtml.inc.php
+++ b/lib/adodb/tohtml.inc.php
@@ -1,6 +1,6 @@
FieldCount();
- $hdr = "
\n\n";
+ $hdr = "\n\n";
for ($i=0; $i < $ncols; $i++) {
$field = $rs->FetchField($i);
if ($zheaderarray) $fname = $zheaderarray[$i];
@@ -60,7 +60,7 @@ GLOBAL $gSQLMaxRows,$gSQLBlockRows;
if (strlen($fname)==0) $fname = ' ';
$hdr .= "| $fname | ";
}
-
+ $hdr .= "\n
";
if ($echo) print $hdr."\n\n";
else $html = $hdr;
diff --git a/lib/adodb/tute.htm b/lib/adodb/tute.htm
index 3f2261e62de..b060a98513b 100644
--- a/lib/adodb/tute.htm
+++ b/lib/adodb/tute.htm
@@ -1,290 +1,290 @@
-
-
-
-
- Tutorial: Moving from MySQL to ADODB
-
-
-
-Tutorial: Moving from MySQL to ADODB
-
- You say eether and I say eyether,
- You say neether and I say nyther;
- Eether, eyether, neether, nyther -
- Let's call the whole thing off !
-
- You like potato and I like po-tah-to,
- You like tomato and I like to-mah-to;
- Potato, po-tah-to, tomato, to-mah-to -
- Let's call the whole thing off !
-
-I love this song, especially the version with Louis Armstrong and Ella singing
- duet. It is all about how hard it is for two people in love to be compatible
- with each other. It's about compromise and finding a common ground, and that's
- what this article is all about.
-
PHP is all about creating dynamic web-sites with the least fuss and the most
- fun. To create these websites we need to use databases to retrieve login information,
- to splash dynamic news onto the web page and store forum postings. So let's
- say we were using the popular MySQL database for this. Your company has done
- such a fantastic job that the Web site is more popular than your wildest dreams.
- You find that MySQL cannot scale to handle the workload; time to switch databases.
-
Unfortunately in PHP every database is accessed slightly differently. To connect
- to MySQL, you would use mysql_connect(); when you decide to upgrade to
- Oracle or Microsoft SQL Server, you would use ocilogon() or mssql_connect()
- respectively. What is worse is that the parameters you use for the different
- connect functions are different also.. One database says po-tato, the other
- database says pota-to. Oh-oh.
-
Let's NOT call the whole thing off
-A database wrapper library such as ADODB comes in handy when you need to ensure portability. It provides
- you with a common API to communicate with any supported database so you don't have to call things off.
-
-
ADODB stands for Active Data Objects DataBase (sorry computer guys are sometimes
- not very original). ADODB currently supports MySQL, PostgreSQL, Oracle, Interbase,
- Microsoft SQL Server, Access, FoxPro, Sybase, ODBC and ADO. You can download
- ADODB from http://php.weblogs.com/adodb.
-
MySQL Example
-The most common database used with PHP is MySQL, so I guess you should be familiar
- with the following code. It connects to a MySQL server at localhost,
- database mydb, and executes an SQL select statement. The results are
- printed, one line per row.
-
$db = mysql_connect("localhost", "root", "password");
-mysql_select_db("mydb",$db);
-$result = mysql_query("SELECT * FROM employees",$db);
-if ($result === false) die("failed");
-while ($fields = mysql_fetch_row($result)) {
- for ($i=0, $max=sizeof($fields); $i < $max; $i++) {
- print $fields[$i].' ';
- }
- print "<br>\n";
-}
-
-The above code has been color-coded by section. The first section is the connection
- phase. The second is the execution of the SQL, and the last section is displaying
- the fields. The while loop scans the rows of the result, while the for
- loop scans the fields in one row.
-Here is the equivalent code in ADODB
- include("adodb.inc.php");
- $db = NewADOConnection('mysql');
- $db->Connect("localhost", "root", "password", "mydb");
- $result = $db->Execute("SELECT * FROM employees");
- if ($result === false) die("failed");
- while (!$result->EOF) {
- for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
- print $result->fields[$i].' ';
- $result->MoveNext();
- print "<br>\n";
- }
-
-Now porting to Oracle is as simple as changing the second line to NewADOConnection('oracle').
- Let's walk through the code...
-Connecting to the Database
-
-include("adodb.inc.php");
-$db = NewADOConnection('mysql');
-$db->Connect("localhost", "root", "password", "mydb");
-The connection code is a bit more sophisticated than MySQL's because our needs
- are more sophisticated. In ADODB, we use an object-oriented approach to managing
- the complexity of handling multiple databases. We have different classes to
- handle different databases. If you aren't familiar with object-oriented programing,
- don't worry -- the complexity is all hidden away in the NewADOConnection()
- function.
-To conserve memory, we only load the PHP code specific to the database you
- are connecting to. We do this by calling NewADOConnection(databasedriver).
- Legal database drivers include mysql, mssql, oracle, oci8, postgres, sybase,
- vfp, access, ibase and many others.
-Then we create a new instance of the connection class by calling NewADOConnection().
- Finally we connect to the database using $db->Connect().
-Executing the SQL
-$result = $db->Execute("SELECT *
- FROM employees");
- if ($result === false) die("failed");
-
-
-Sending the SQL statement to the server is straight forward. Execute() will
- return a recordset object on successful execution. You should check $result
- as we do above.
-
An issue that confuses beginners is the fact that we have two types of objects
- in ADODB, the connection object and the recordset object. When do we use each?
-
The connection object ($db) is responsible for connecting to the database,
- formatting your SQL and querying the database server. The recordset object ($result)
- is responsible for retrieving the results and formatting the reply as text or
- as an array.
-
The only thing I need to add is that ADODB provides several helper functions
- for making INSERT and UPDATE statements easier, which we will cover in the Advanced
- section.
-
Retrieving the Data
-
-while (!$result->EOF) {
- for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
- print $result->fields[$i].' ';
- $result->MoveNext();
- print "<br>\n";
-}
-The paradigm for getting the data is that it's like reading a file. For every
- line, we check first whether we have reached the end-of-file (EOF). While not
- end-of-file, loop through each field in the row. Then move to the next line
- (MoveNext) and repeat.
-
The $result->fields[] array is generated by the PHP database
- extension. Some database extensions do not index the array by field name.
- To force indexing by name - that is associative arrays -
- use the $ADODB_FETCH_MODE global variable.
-
- $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- $rs1 = $db->Execute('select * from table');
- $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
- $rs2 = $db->Execute('select * from table');
- print_r($rs1->fields); // shows array([0]=>'v0',[1] =>'v1')
- print_r($rs2->fields); // shows array(['col1']=>'v0',['col2'] =>'v1')
-
-
-As you can see in the above example, both recordsets store and use different fetch modes
-based on the $ADODB_FETCH_MODE setting when the recordset was created by Execute().
-ADOConnection
-Object that performs the connection to the database, executes SQL statements
- and has a set of utility functions for standardising the format of SQL statements
- for issues such as concatenation and date formats.
-
-Other Useful Functions
-$recordset->Move($pos) scrolls to that particular row. ADODB supports forward
- scrolling for all databases. Some databases will not support backwards scrolling.
- This is normally not a problem as you can always cache records to simulate backwards
- scrolling.
-
$recordset->RecordCount() returns the number of records accessed by the
- SQL statement. Some databases will return -1 because it is not supported.
-
$recordset->GetArray() returns the result as an array.
-
rs2html($recordset) is a function that is generates a HTML table based on the
- $recordset passed to it. An example with the relevant lines in bold:
-
include('adodb.inc.php');
- include('tohtml.inc.php'); /* includes the rs2html function */
- $conn = &ADONewConnection('mysql');
- $conn->PConnect('localhost','userid','password','database');
- $rs = $conn->Execute('select * from table');
- rs2html($rs); /* recordset to html table */
-There are many other helper functions that are listed in the documentation available at http://php.weblogs.com/adodb_manual.
-
Advanced Material
-Inserts and Updates
-Let's say you want to insert the following data into a database.
-
ID = 3
- TheDate=mktime(0,0,0,8,31,2001) /* 31st August 2001 */
- Note= sugar why don't we call it off
-
When you move to another database, your insert might no longer work.
-The first problem is that each database has a different default date format.
- MySQL expects YYYY-MM-DD format, while other databases have different defaults.
- ADODB has a function called DBDate() that addresses this issue by converting
- converting the date to the correct format.
-The next problem is that the don't in the Note needs to be quoted. In
- MySQL, we use don\'t but in some other databases (Sybase, Access, Microsoft
- SQL Server) we use don''t. The qstr() function addresses this issue.
-So how do we use the functions? Like this:
-$sql = "INSERT INTO table (id, thedate,note) values ("
- . $ID . ','
- . $db->DBDate($TheDate) .','
- . $db->qstr($Note).")";
-$db->Execute($sql);
-ADODB also supports $connection->Affected_Rows() (returns the
- number of rows affected by last update or delete) and $recordset->Insert_ID()
- (returns last autoincrement number generated by an insert statement). Be forewarned
- that not all databases support the two functions.
-
-MetaTypes
-You can find out more information about each of the fields (I use the words
- fields and columns interchangebly) you are selecting by calling the recordset
- method FetchField($fieldoffset). This will return an object with
- 3 properties: name, type and max_length.
-
For example:
-$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);
-
-Then $f0->name will hold 'adata', $f0->type
- will be set to 'date'. If the max_length is unknown, it will be set to
- -1.
-
One problem with handling different databases is that each database often calls
- the same type by a different name. For example a timestamp type is called
- datetime in one database and time in another. So ADODB has a special
- MetaType($type, $max_length) function that standardises the types
- to the following:
-
C: character and varchar types
- X: text or long character (eg. more than 255 bytes wide).
- B: blob or binary image
- D: date
- T: timestamp
- L: logical (boolean)
- I: integer
- N: numeric (float, double, money)
-
In the above date example,
-
$recordset = $conn->Execute("select adate from table");
- $f0 = $recordset->FetchField(0);
- $type = $recordset->MetaType($f0->type, $f0->max_length);
- print $type; /* should print 'D' */
-
-
Select Limit and Top Support
-
ADODB has a function called $connection->SelectLimit($sql,$nrows,$offset) that allows
-you to retrieve a subset of the recordset. This will take advantage of native
-SELECT TOP on Microsoft products and SELECT ... LIMIT with PostgreSQL and MySQL, and
-emulated if the database does not support it.
-
Caching Support
-
ADODB allows you to cache recordsets in your file system, and only requery the database
-server after a certain timeout period with $connection->CacheExecute($secs2cache,$sql) and
-$connection->CacheSelectLimit($secs2cache,$sql,$nrows,$offset).
-
PHP4 Session Handler Support
-
ADODB also supports PHP4 session handlers. You can store your session variables
- in a database for true scalability using ADODB. For further information, visit
- http://php.weblogs.com/adodb-sessions
-
Commercial Use Encouraged
-If you plan to write commercial PHP applications that you want to resell, you should consider ADODB. It has been released using the lesser GPL, which means you can legally include it in commercial applications, while keeping your code proprietary. Commercial use of ADODB is strongly encouraged! We are using it internally for this reason.
-
-
Conclusion
-As a thank you for finishing this article, here are the complete lyrics for
- let's call the whole thing off.
-
-
- Refrain
-
- You say eether and I say eyether,
- You say neether and I say nyther;
- Eether, eyether, neether, nyther -
- Let's call the whole thing off !
-
- You like potato and I like po-tah-to,
- You like tomato and I like to-mah-to;
- Potato, po-tah-to, tomato, to-mah-to -
- Let's call the whole thing off !
-
-But oh, if we call the whole thing off, then we must part.
-And oh, if we ever part, then that might break my heart.
-
- So, if you like pajamas and I like pa-jah-mas,
- I'll wear pajamas and give up pa-jah-mas.
- For we know we
- Need each other, so we
- Better call the calling off off.
- Let's call the whole thing off !
-
- Second Refrain
-
- You say laughter and I say lawfter,
- You say after and I say awfter;
- Laughter, lawfter, after, awfter -
- Let's call the whole thing off !
-
- You like vanilla and I like vanella,
- You, sa's'parilla and I sa's'parella;
- Vanilla, vanella, choc'late, strawb'ry -
- Let's call the whole thing off !
-
-But oh, if we call the whole thing off, then we must part.
-And oh, if we ever part, then that might break my heart.
-
- So, if you go for oysters and I go for ersters,
- I'll order oysters and cancel the ersters.
- For we know we
- Need each other, so we
- Better call the calling off off.
- Let's call the whole thing off !
-
-Song and lyrics by George and Ira Gershwin, introduced by Fred Astaire and Ginger Rogers
-in the film "Shall We Dance?"
-
-(c)2001-2002 John Lim.
-
-
-
+
+
+
+
+ Tutorial: Moving from MySQL to ADODB
+
+
+
+Tutorial: Moving from MySQL to ADODB
+
+ You say eether and I say eyether,
+ You say neether and I say nyther;
+ Eether, eyether, neether, nyther -
+ Let's call the whole thing off !
+
+ You like potato and I like po-tah-to,
+ You like tomato and I like to-mah-to;
+ Potato, po-tah-to, tomato, to-mah-to -
+ Let's call the whole thing off !
+
+I love this song, especially the version with Louis Armstrong and Ella singing
+ duet. It is all about how hard it is for two people in love to be compatible
+ with each other. It's about compromise and finding a common ground, and that's
+ what this article is all about.
+
PHP is all about creating dynamic web-sites with the least fuss and the most
+ fun. To create these websites we need to use databases to retrieve login information,
+ to splash dynamic news onto the web page and store forum postings. So let's
+ say we were using the popular MySQL database for this. Your company has done
+ such a fantastic job that the Web site is more popular than your wildest dreams.
+ You find that MySQL cannot scale to handle the workload; time to switch databases.
+
Unfortunately in PHP every database is accessed slightly differently. To connect
+ to MySQL, you would use mysql_connect(); when you decide to upgrade to
+ Oracle or Microsoft SQL Server, you would use ocilogon() or mssql_connect()
+ respectively. What is worse is that the parameters you use for the different
+ connect functions are different also.. One database says po-tato, the other
+ database says pota-to. Oh-oh.
+
Let's NOT call the whole thing off
+A database wrapper library such as ADODB comes in handy when you need to ensure portability. It provides
+ you with a common API to communicate with any supported database so you don't have to call things off.
+
+
ADODB stands for Active Data Objects DataBase (sorry computer guys are sometimes
+ not very original). ADODB currently supports MySQL, PostgreSQL, Oracle, Interbase,
+ Microsoft SQL Server, Access, FoxPro, Sybase, ODBC and ADO. You can download
+ ADODB from http://php.weblogs.com/adodb.
+
MySQL Example
+The most common database used with PHP is MySQL, so I guess you should be familiar
+ with the following code. It connects to a MySQL server at localhost,
+ database mydb, and executes an SQL select statement. The results are
+ printed, one line per row.
+
$db = mysql_connect("localhost", "root", "password");
+mysql_select_db("mydb",$db);
+$result = mysql_query("SELECT * FROM employees",$db);
+if ($result === false) die("failed");
+while ($fields = mysql_fetch_row($result)) {
+ for ($i=0, $max=sizeof($fields); $i < $max; $i++) {
+ print $fields[$i].' ';
+ }
+ print "<br>\n";
+}
+
+The above code has been color-coded by section. The first section is the connection
+ phase. The second is the execution of the SQL, and the last section is displaying
+ the fields. The while loop scans the rows of the result, while the for
+ loop scans the fields in one row.
+Here is the equivalent code in ADODB
+ include("adodb.inc.php");
+ $db = NewADOConnection('mysql');
+ $db->Connect("localhost", "root", "password", "mydb");
+ $result = $db->Execute("SELECT * FROM employees");
+ if ($result === false) die("failed");
+ while (!$result->EOF) {
+ for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
+ print $result->fields[$i].' ';
+ $result->MoveNext();
+ print "<br>\n";
+ }
+
+Now porting to Oracle is as simple as changing the second line to NewADOConnection('oracle').
+ Let's walk through the code...
+Connecting to the Database
+
+include("adodb.inc.php");
+$db = NewADOConnection('mysql');
+$db->Connect("localhost", "root", "password", "mydb");
+The connection code is a bit more sophisticated than MySQL's because our needs
+ are more sophisticated. In ADODB, we use an object-oriented approach to managing
+ the complexity of handling multiple databases. We have different classes to
+ handle different databases. If you aren't familiar with object-oriented programing,
+ don't worry -- the complexity is all hidden away in the NewADOConnection()
+ function.
+To conserve memory, we only load the PHP code specific to the database you
+ are connecting to. We do this by calling NewADOConnection(databasedriver).
+ Legal database drivers include mysql, mssql, oracle, oci8, postgres, sybase,
+ vfp, access, ibase and many others.
+Then we create a new instance of the connection class by calling NewADOConnection().
+ Finally we connect to the database using $db->Connect().
+Executing the SQL
+$result = $db->Execute("SELECT *
+ FROM employees");
+ if ($result === false) die("failed");
+
+
+Sending the SQL statement to the server is straight forward. Execute() will
+ return a recordset object on successful execution. You should check $result
+ as we do above.
+
An issue that confuses beginners is the fact that we have two types of objects
+ in ADODB, the connection object and the recordset object. When do we use each?
+
The connection object ($db) is responsible for connecting to the database,
+ formatting your SQL and querying the database server. The recordset object ($result)
+ is responsible for retrieving the results and formatting the reply as text or
+ as an array.
+
The only thing I need to add is that ADODB provides several helper functions
+ for making INSERT and UPDATE statements easier, which we will cover in the Advanced
+ section.
+
Retrieving the Data
+
+while (!$result->EOF) {
+ for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
+ print $result->fields[$i].' ';
+ $result->MoveNext();
+ print "<br>\n";
+}
+The paradigm for getting the data is that it's like reading a file. For every
+ line, we check first whether we have reached the end-of-file (EOF). While not
+ end-of-file, loop through each field in the row. Then move to the next line
+ (MoveNext) and repeat.
+
The $result->fields[] array is generated by the PHP database
+ extension. Some database extensions do not index the array by field name.
+ To force indexing by name - that is associative arrays -
+ use the $ADODB_FETCH_MODE global variable.
+
+ $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+ $rs1 = $db->Execute('select * from table');
+ $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
+ $rs2 = $db->Execute('select * from table');
+ print_r($rs1->fields); // shows array([0]=>'v0',[1] =>'v1')
+ print_r($rs2->fields); // shows array(['col1']=>'v0',['col2'] =>'v1')
+
+
+As you can see in the above example, both recordsets store and use different fetch modes
+based on the $ADODB_FETCH_MODE setting when the recordset was created by Execute().
+ADOConnection
+Object that performs the connection to the database, executes SQL statements
+ and has a set of utility functions for standardising the format of SQL statements
+ for issues such as concatenation and date formats.
+
+Other Useful Functions
+$recordset->Move($pos) scrolls to that particular row. ADODB supports forward
+ scrolling for all databases. Some databases will not support backwards scrolling.
+ This is normally not a problem as you can always cache records to simulate backwards
+ scrolling.
+
$recordset->RecordCount() returns the number of records accessed by the
+ SQL statement. Some databases will return -1 because it is not supported.
+
$recordset->GetArray() returns the result as an array.
+
rs2html($recordset) is a function that is generates a HTML table based on the
+ $recordset passed to it. An example with the relevant lines in bold:
+
include('adodb.inc.php');
+ include('tohtml.inc.php'); /* includes the rs2html function */
+ $conn = &ADONewConnection('mysql');
+ $conn->PConnect('localhost','userid','password','database');
+ $rs = $conn->Execute('select * from table');
+ rs2html($rs); /* recordset to html table */
+There are many other helper functions that are listed in the documentation available at http://php.weblogs.com/adodb_manual.
+
Advanced Material
+Inserts and Updates
+Let's say you want to insert the following data into a database.
+
ID = 3
+ TheDate=mktime(0,0,0,8,31,2001) /* 31st August 2001 */
+ Note= sugar why don't we call it off
+
When you move to another database, your insert might no longer work.
+The first problem is that each database has a different default date format.
+ MySQL expects YYYY-MM-DD format, while other databases have different defaults.
+ ADODB has a function called DBDate() that addresses this issue by converting
+ converting the date to the correct format.
+The next problem is that the don't in the Note needs to be quoted. In
+ MySQL, we use don\'t but in some other databases (Sybase, Access, Microsoft
+ SQL Server) we use don''t. The qstr() function addresses this issue.
+So how do we use the functions? Like this:
+$sql = "INSERT INTO table (id, thedate,note) values ("
+ . $ID . ','
+ . $db->DBDate($TheDate) .','
+ . $db->qstr($Note).")";
+$db->Execute($sql);
+ADODB also supports $connection->Affected_Rows() (returns the
+ number of rows affected by last update or delete) and $recordset->Insert_ID()
+ (returns last autoincrement number generated by an insert statement). Be forewarned
+ that not all databases support the two functions.
+
+MetaTypes
+You can find out more information about each of the fields (I use the words
+ fields and columns interchangebly) you are selecting by calling the recordset
+ method FetchField($fieldoffset). This will return an object with
+ 3 properties: name, type and max_length.
+
For example:
+$recordset = $conn->Execute("select adate from table");
$f0 = $recordset->FetchField(0);
+
+Then $f0->name will hold 'adata', $f0->type
+ will be set to 'date'. If the max_length is unknown, it will be set to
+ -1.
+
One problem with handling different databases is that each database often calls
+ the same type by a different name. For example a timestamp type is called
+ datetime in one database and time in another. So ADODB has a special
+ MetaType($type, $max_length) function that standardises the types
+ to the following:
+
C: character and varchar types
+ X: text or long character (eg. more than 255 bytes wide).
+ B: blob or binary image
+ D: date
+ T: timestamp
+ L: logical (boolean)
+ I: integer
+ N: numeric (float, double, money)
+
In the above date example,
+
$recordset = $conn->Execute("select adate from table");
+ $f0 = $recordset->FetchField(0);
+ $type = $recordset->MetaType($f0->type, $f0->max_length);
+ print $type; /* should print 'D' */
+
+
Select Limit and Top Support
+
ADODB has a function called $connection->SelectLimit($sql,$nrows,$offset) that allows
+you to retrieve a subset of the recordset. This will take advantage of native
+SELECT TOP on Microsoft products and SELECT ... LIMIT with PostgreSQL and MySQL, and
+emulated if the database does not support it.
+
Caching Support
+
ADODB allows you to cache recordsets in your file system, and only requery the database
+server after a certain timeout period with $connection->CacheExecute($secs2cache,$sql) and
+$connection->CacheSelectLimit($secs2cache,$sql,$nrows,$offset).
+
PHP4 Session Handler Support
+
ADODB also supports PHP4 session handlers. You can store your session variables
+ in a database for true scalability using ADODB. For further information, visit
+ http://php.weblogs.com/adodb-sessions
+
Commercial Use Encouraged
+If you plan to write commercial PHP applications that you want to resell, you should consider ADODB. It has been released using the lesser GPL, which means you can legally include it in commercial applications, while keeping your code proprietary. Commercial use of ADODB is strongly encouraged! We are using it internally for this reason.
+
+
Conclusion
+As a thank you for finishing this article, here are the complete lyrics for
+ let's call the whole thing off.
+
+
+ Refrain
+
+ You say eether and I say eyether,
+ You say neether and I say nyther;
+ Eether, eyether, neether, nyther -
+ Let's call the whole thing off !
+
+ You like potato and I like po-tah-to,
+ You like tomato and I like to-mah-to;
+ Potato, po-tah-to, tomato, to-mah-to -
+ Let's call the whole thing off !
+
+But oh, if we call the whole thing off, then we must part.
+And oh, if we ever part, then that might break my heart.
+
+ So, if you like pajamas and I like pa-jah-mas,
+ I'll wear pajamas and give up pa-jah-mas.
+ For we know we
+ Need each other, so we
+ Better call the calling off off.
+ Let's call the whole thing off !
+
+ Second Refrain
+
+ You say laughter and I say lawfter,
+ You say after and I say awfter;
+ Laughter, lawfter, after, awfter -
+ Let's call the whole thing off !
+
+ You like vanilla and I like vanella,
+ You, sa's'parilla and I sa's'parella;
+ Vanilla, vanella, choc'late, strawb'ry -
+ Let's call the whole thing off !
+
+But oh, if we call the whole thing off, then we must part.
+And oh, if we ever part, then that might break my heart.
+
+ So, if you go for oysters and I go for ersters,
+ I'll order oysters and cancel the ersters.
+ For we know we
+ Need each other, so we
+ Better call the calling off off.
+ Let's call the whole thing off !
+
+Song and lyrics by George and Ira Gershwin, introduced by Fred Astaire and Ginger Rogers
+in the film "Shall We Dance?"
+
+(c)2001-2002 John Lim.
+
+
+