imported ADOdb version 4.20 released 27 Feb 2004

This commit is contained in:
Ralf Becker 2004-03-15 22:17:52 +00:00
parent d8c602e654
commit 3df33d3ef6
127 changed files with 8961 additions and 2388 deletions

View File

@ -3,7 +3,7 @@ global $ADODB_INCLUDED_CSV;
$ADODB_INCLUDED_CSV = 1;
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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 @@ V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights res
*/
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;

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -18,19 +18,30 @@
*/
function Lens_ParseTest()
{
$str = "ACOL NUMBER(32,2) DEFAULT 'The \"cow\" (and Jim''s dog) jumps over the moon' PRIMARY, INTI INT AUTO DEFAULT 0";
$str = "`zcol ACOL` NUMBER(32,2) DEFAULT 'The \"cow\" (and Jim''s dog) jumps over the moon' PRIMARY, INTI INT AUTO DEFAULT 0";
print "<p>$str</p>";
$a= Lens_ParseArgs($str);
print "<pre>";
print_r($a);
print "</pre>";
}
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.
@ -64,6 +75,8 @@ 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,10 +157,12 @@ 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 $nameRegex = '\w';
var $schema = false;
var $serverInfo = array();
var $autoIncrement = false;
@ -169,14 +185,19 @@ class ADODB_DataDict {
return $this->connection->MetaTables();
}
function &MetaColumns($tab)
function &MetaColumns($tab, $upper=true, $schema=false)
{
return $this->connection->MetaColumns($tab);
return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema);
}
function &MetaPrimaryKeys($tab,$owner=false,$intkey=false)
{
return $this->connection->MetaPrimaryKeys($tab.$owner,$intkey);
return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey);
}
function &MetaIndexes($table, $primary = false, $owner = false)
{
return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
}
function MetaType($t,$len=-1,$fieldobj=false)
@ -184,6 +205,41 @@ class ADODB_DataDict {
return ADORecordSet::MetaType($t,$len,$fieldobj);
}
function NameQuote($name = NULL)
{
if (!is_string($name)) {
return FALSE;
}
$name = trim($name);
if ( !is_object($this->connection) ) {
return $name;
}
$quote = $this->connection->nameQuote;
// if name is of the form `name`, quote it
if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
return $quote . $matches[1] . $quote;
}
// if name contains special characters, quote it
if ( !preg_match('/^[' . $this->nameRegex . ']+$/', $name) ) {
return $quote . $name . $quote;
}
return $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)
{
@ -230,8 +286,12 @@ class ADODB_DataDict {
function CreateDatabase($dbname,$options=false)
{
$options = $this->_Options($options);
$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;
}
@ -241,8 +301,20 @@ 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));
if (!is_array($flds)) {
$flds = explode(',',$flds);
}
foreach($flds as $key => $fld) {
$flds[$key] = $this->NameQuote($fld);
}
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), $this->TableName($tabname)));
}
function SetSchema($schema)
@ -252,43 +324,43 @@ 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 . $this->NameQuote($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)));
}
/*
@ -301,7 +373,7 @@ class ADODB_DataDict {
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);
@ -368,7 +440,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);
@ -397,6 +471,9 @@ class ADODB_DataDict {
return false;
}
$fid = strtoupper(preg_replace('/^`(.+)`$/', '$1', $fname));
$fname = $this->NameQuote($fname);
if (!strlen($ftype)) {
if ($this->debug) ADOConnection::outp("Undefined TYPE for field '$fname'");
return false;
@ -437,12 +514,11 @@ class ADODB_DataDict {
$suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
$fname = str_pad($fname,16);
$lines[] = "$fname $ftype$suffix";
$lines[$fid] = $fname.' '.$ftype.$suffix;
if ($fautoinc) $this->autoIncrement = true;
} // foreach $flds
return array($lines,$pkey);
}
/*
@ -454,7 +530,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;
@ -473,14 +549,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;
@ -495,12 +585,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);
if ($sInc) $sql[] = $sInc;
}
if ( isset ($tableoptions['DROP']) ) {
return $sql;
}
}
$s = "CREATE TABLE $tabname (\n";
$s .= implode(",\n", $lines);
@ -544,38 +637,30 @@ class ADODB_DataDict {
return $newopts;
}
/*
"Florian Buzin [ easywe ]" <florian.buzin@easywe.de>
/*
"Florian Buzin [ easywe ]" <florian.buzin@easywe.de>
This function changes/adds new fields to your table. You
dont have to know if the col is new or not. It will check on its
own.
*/
function ChangeTableSQL($tablename, $flds,$tableoptions=false)
This function changes/adds new fields to your table. You don't
have to know if the col is new or not. It will check on its own.
*/
function ChangeTableSQL($tablename, $flds, $tableoptions = false)
{
if ($this->schema) $tabname = $this->schema.'.'.$tablename;
else $tabname = $tablename;
if ( !is_array($cols = &$this->MetaColumns($tablename)) ) {
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
}
$conn = &$this->connection;
if (!$conn) return false;
$colarr = &$conn->MetaColumns($tabname);
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);
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
$sql = array();
foreach($lines as $v) {
$f = explode(" ",$v);
if(!empty($cols[strtoupper($f[0])])){
$sql[] = "ALTER TABLE $tabname $this->alterCol $v";
}else{
$sql[] = "ALTER TABLE $tabname $this->addCol $v";
foreach ( $lines as $id => $v ) {
if ( isset($cols[$id]) && is_object($cols[$id]) ) {
$sql[] = $alter . $this->alterCol . ' ' . $v;
} else {
$sql[] = $alter . $this->addCol . ' ' . $v;
}
}
return $sql;
}
} // class

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.
@ -94,12 +94,12 @@ function adodb_error_pg($errormsg)
'/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => 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;

View File

@ -1,9 +1,9 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
*
* Set tabs to 4 for best viewing.
*
@ -16,7 +16,7 @@ if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_US
define('ADODB_ERROR_HANDLER','ADODB_Error_Handler');
/**
/**
* Default Error Handler. This will be called with the following params
*
* @param $dbms the RDBMS you are connecting to
@ -24,8 +24,9 @@ define('ADODB_ERROR_HANDLER','ADODB_Error_Handler');
* @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
*/
* @param $p2 $fn specific parameter - see below
* @param $thisConn $current connection object - can be false if no connection object created
*/
function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection)
{
if (error_reporting() == 0) return; // obey @ protocol

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.

View File

@ -0,0 +1,78 @@
<?php
/**
* @version V4.20 22 Feb 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.
*
* Set tabs to 4 for best viewing.
*
* Latest version is available at http://php.weblogs.com
*
* Exception-handling code using PHP5 exceptions (try-catch-throw).
*/
if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR);
define('ADODB_ERROR_HANDLER','adodb_throw');
class ADODB_Exception extends Exception {
var $dbms;
var $fn;
var $sql = '';
var $params = '';
var $host = '';
var $database = '';
function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
{
switch($fn) {
case 'EXECUTE':
$this->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;
if (!is_numeric($errno)) $errno = -1;
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);
}
?>

View File

@ -0,0 +1,56 @@
<?php
/*
V4.20 22 Feb 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.
Set tabs to 4.
PHP5 Iterator Class:
$rs = $db->Execute("select * from adoxyz");
foreach($rs as $k => $v) {
echo $k; print_r($v); echo "<br>";
}
*/
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);
}
}
?>

View File

@ -4,7 +4,7 @@ global $ADODB_INCLUDED_LIB;
$ADODB_INCLUDED_LIB = 1;
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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 @@ V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights res
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 "<p>Error=".$this->ErrorNo().'<p>';
$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) {
@ -340,7 +412,12 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
break;
default:
$val = $arrFields[$upperfname];
if (!is_numeric($val)) $val = (float) $val;
/*if (!is_numeric($val)) {
if (strncmp($val,'=',1) == 0) $val = substr($val,1);
else $val = (float) $val;
}*/
if (empty($val)) $val = '0';
$updateSQL .= $field->name . " = " . $val . ", ";
break;
};
@ -400,6 +477,7 @@ 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;
@ -407,7 +485,6 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false)
$fieldInsertedCount = 0;
// Loop through all of the fields in the recordset
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
@ -449,7 +526,11 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false)
break;
default:
$val = $arrFields[$upperfname];
if (!is_numeric($val)) $val = (float) $val;
/*if (!is_numeric($val)) {
if (strncmp($val,'=',1) == 0) $val = substr($val,1);
else $val = (float) $val;
}*/
if (empty($val)) $val = '0';
$values .= $val . ", ";
break;
};
@ -457,7 +538,8 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false)
};
// If there were any inserted fields then build the rest of the insert query.
if ($fieldInsertedCount > 0) {
if ($fieldInsertedCount <= 0) return false;
// Get the table name from the existing query.
preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
@ -470,9 +552,7 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false)
$insertSQL = "INSERT INTO " . $tableName[1] . " ( $fields ) VALUES ( $values )";
return $insertSQL;
} else {
return false;
};
}
?>

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -19,10 +19,6 @@
and no free support requests except for bug reports
will be entertained by the author.
My company also sells a commercial pagination
object at http://phplens.com/ with much more
functionality, including search, create, edit,
delete records.
*/
class ADODB_Pager {
var $id; // unique id for pager (defaults to 'adodb')

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.
@ -175,7 +175,7 @@ class DB
if($persist) $ok = $obj->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;
}

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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,6 +19,7 @@ V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights res
if (!defined(ADODB_DIR)) include_once(dirname(__FILE__).'/adodb.inc.php');
include_once(ADODB_DIR.'/tohtml.inc.php');
/* return microtime value as a float */
function adodb_microtime()
{
@ -32,6 +33,7 @@ function& adodb_log_sql(&$conn,$sql,$inputarr)
{
global $HTTP_SERVER_VARS;
$perf_table = adodb_perf::table();
$conn->fnExecute = false;
$t0 = microtime();
$rs =& $conn->Execute($sql,$inputarr);
@ -39,6 +41,7 @@ global $HTTP_SERVER_VARS;
if (!empty($conn->_logsql)) {
$conn->_logsql = false; // disable logsql error simulation
$dbT = $conn->databaseType;
$a0 = split(' ',$t0);
$a0 = (float)$a0[1]+(float)$a0[0];
@ -51,11 +54,18 @@ global $HTTP_SERVER_VARS;
if (!$rs) {
$errM = $conn->ErrorMsg();
$errN = $conn->ErrorNo();
$conn->lastInsID = 0;
$tracer = substr('ERROR: '.htmlspecialchars($errM),0,250);
} else {
$tracer = '';
$errM = '';
$errN = 0;
$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 .= '<br>'.$HTTP_SERVER_VARS['HTTP_HOST'];
@ -83,9 +93,9 @@ global $HTTP_SERVER_VARS;
$saved = $conn->debug;
$conn->debug = 0;
$dbT = $conn->databaseType;
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);
@ -95,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;
@ -114,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),
@ -161,6 +170,17 @@ class adodb_perf {
var $explain = true;
var $helpurl = "<a href=http://phplens.com/adodb/reference.functions.fnexecute.and.fncacheexecute.properties.html#logsql>LogSQL help</a>";
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()
@ -281,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 = '';
@ -294,10 +318,16 @@ Committed_AS: 348732 kB
$s .= sprintf("%4d",$k[0]).' &nbsp; '.strip_tags($k[1]).'<br>';
}
}
$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;
}
@ -310,7 +340,8 @@ Committed_AS: 348732 kB
$s = '<h3>Invalid SQL</h3>';
$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);
@ -320,6 +351,7 @@ Committed_AS: 348732 kB
return $s;
}
/*
This script identifies the longest running SQL
*/
@ -327,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 "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'])."\n";
$partial = !empty($HTTP_GET_VARS['part']);
echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
}
if (isset($HTTP_GET_VARS['sql'])) return;
@ -342,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
@ -354,14 +388,19 @@ Committed_AS: 348732 kB
$s = "<h3>Suspicious SQL</h3>
<font size=1>The following SQL have high average execution times</font><br>
<table border=1 bgcolor=white><tr><td><b>Avg Time</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
$max = $this->maxLength;
while (!$rs->EOF) {
$sql = trim($rs->fields[1]);
$prefix = "<a target=sql".rand()." href=\"?hidem=1&exps=1&sql=".rawurlencode($sql)."&x#explain\">";
$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 = "<a target=sql".rand()." href=\"?hidem=1&exps=1&sql=".$raw."&x#explain\">";
$suffix = "</a>";
if ($this->explain == false || strlen($prefix)>2000) {
if ($this->explain == false || strlen($prefix)>$max) {
$suffix = ' ... <i>String too long for GET parameter: '.strlen($prefix).'</i>';
$prefix = '';
$suffix = '';
}
$s .= "<tr><td>".round($rs->fields[0],6)."<td align=right>".$rs->fields[2]."<td><font size=-1>".$prefix.htmlspecialchars($sql).$suffix."</font>".
"<td>".$rs->fields[3]."<td>".$rs->fields[4]."</tr>";
@ -397,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 "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'])."\n";
$partial = !empty($HTTP_GET_VARS['part']);
echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
}
if (isset($HTTP_GET_VARS['sql'])) return;
@ -411,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
@ -423,12 +464,17 @@ Committed_AS: 348732 kB
$s = "<h3>Expensive SQL</h3>
<font size=1>Tuning the following SQL will reduce the server load substantially</font><br>
<table border=1 bgcolor=white><tr><td><b>Load</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
$max = $this->maxLength;
while (!$rs->EOF) {
$sql = $rs->fields[1];
$prefix = "<a target=sqle".rand()." href=\"?hidem=1&expe=1&sql=".rawurlencode($sql)."&x#explain\">";
$raw = urlencode($sql);
if (strlen($raw)>$max-100) {
$sql2 = substr($sql,0,$max-500);
$raw = urlencode($sql2).'&part='.crc32($sql);
}
$prefix = "<a target=sqle".rand()." href=\"?hidem=1&expe=1&sql=".$raw."&x#explain\">";
$suffix = "</a>";
if($this->explain == false || strlen($prefix>2000)) {
if($this->explain == false || strlen($prefix>$max)) {
$prefix = '';
$suffix = '';
}
@ -525,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;
@ -537,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);
@ -554,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';
@ -564,11 +612,14 @@ Committed_AS: 348732 kB
if ($do == 'viewsql') $form = "<td><form># SQL:<input type=hidden value=viewsql name=do> <input type=text size=4 name=nsql value=$nsql><input type=submit value=Go></td></form>";
else $form = "<td>&nbsp;</td>";
$allowsql = !defined('ADODB_PERF_NO_RUN_SQL');
if (empty($HTTP_GET_VARS['hidem']))
echo "<table border=1 width=100% bgcolor=lightyellow><tr><td colspan=2>
<b><a href=http://php.weblogs.com/adodb?perf=1>ADOdb</a> Performance Monitor</b> for $app</tr><tr><td>
<a href=?do=stats>Performance Stats</a> &nbsp; <a href=?do=viewsql>View SQL</a>
&nbsp; <a href=?do=tables>View Tables</a> &nbsp; <a href=?do=poll>Poll Stats</a>",
$allowsql ? ' &nbsp; <a href=?do=dosql>Run SQL</a>' : '',
"$form",
"</tr></table>";
@ -577,7 +628,7 @@ Committed_AS: 348732 kB
default:
case 'stats':
echo $this->HealthCheck();
$this->conn->debug=1;
echo $this->CheckMemory();
break;
case 'poll':
@ -588,6 +639,12 @@ Committed_AS: 348732 kB
echo "<pre>";
$this->Poll($pollsecs);
break;
case 'dosql':
if (!$allowsql) break;
$this->DoSQLForm();
break;
case 'viewsql':
if (empty($HTTP_GET_VARS['hidem']))
echo "&nbsp; <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
@ -743,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;
}
?>
<form method="POST" action="<?php echo $PHP_SELF ?>">
<table><tr>
<td> Form size: <input type="submit" value=" &lt; " name="SMALLER"><input type="submit" value=" &gt; &gt; " name="BIGGER">
</td>
<td align=right>
<input type="submit" value=" Run SQL Below " name="RUN"><input type=hidden name=do value=dosql>
</td></tr>
<tr>
<td colspan=2><textarea rows=<?php print $rows; ?> name="sql" cols="80"><?php print htmlspecialchars($sql) ?></textarea>
</td>
</tr>
</table>
</form>
<?php
if (!isset($HTTP_VARS['sql'])) return;
$sql = $this->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 "<p>".htmlspecialchars($sqls)."</p>";
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 "<table width=98% bgcolor=#C0C0FF><tr><td>&nbsp;</td></tr></table>";
rs2html($rs);
}
} else {
$e1 = (integer) $this->conn->ErrorNo();
$e2 = $this->conn->ErrorMsg();
if (($e1) || ($e2)) {
if (empty($e1)) $e1 = '-1'; // postgresql fix
print ' &nbsp; '.$e1.': '.$e2;
} else {
print "<p>No Recordset returned<br></p>";
}
}
} // 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;
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
/*
V4.20 22 Feb 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.
Set tabs to 4.
*/
class ADODB_BASE_RS {
}
?>

View File

@ -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()
</pre>
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);

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -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 V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim\@natsoft.com.my). All rights reserved.
@version V4.20 22 Feb 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','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>');
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,6 +63,34 @@
// GLOBAL SETUP
//==============================================================================================
$ADODB_EXTENSION = defined('ADODB_EXTENSION');
if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) {
define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>');
// allow [ ] @ ` " and . in table names
define('ADODB_TABLE_REGEX','([]0-9a-z_\"\`\.\@\[-]*)');
// 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) {
@ -97,8 +100,10 @@
} else {
define('ADODB_PHPVER',0x4000);
}
$ADODB_EXTENSION = defined('ADODB_EXTENSION');
//if (extension_loaded('dbx')) define('ADODB_DBX',1);
}
//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 = 'V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
$ADODB_vers = 'V4.20 22 Feb 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,16 +217,23 @@
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 = '';
var $uniqueOrderBy = false; /// All order by columns have to be unique
var $emptyDate = '&nbsp;';
var $emptyTimeStamp = '&nbsp;';
var $lastInsID = false;
//--
var $hasInsertID = false; /// supports autoincrement ID?
var $hasAffectedRows = false; /// supports affected rows for update/delete?
@ -240,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
@ -318,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;
@ -330,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
}
/**
@ -468,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);
}
/**
@ -586,15 +592,35 @@
}
/*
returns placeholder for parameter, eg.
Returns placeholder for parameter, eg.
$DB->Param('a')
will return ':a' for Oracle, and '?' for most other databases...
For databases that require positioned params, eg $1, $2, $3 for postgresql,
pass in Param(false) before setting the first parameter.
*/
function Param($name)
{
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');
@ -627,7 +653,6 @@
*/
function StartTrans($errfn = 'ADODB_TransMonitor')
{
if ($this->transOff > 0) {
$this->transOff += 1;
return;
@ -660,7 +685,10 @@
$this->transOff = 0;
if ($this->_transOK && $autoComplete) {
$this->CommitTrans();
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();
@ -717,7 +745,7 @@
$sqlarr = explode('?',$sql);
if (!$array_2d) $inputarr = array($inputarr);
while(list(,$arr) = each($inputarr)) {
foreach($inputarr as $arr) {
$sql = ''; $i = 0;
foreach($arr as $v) {
$sql .= $sqlarr[$i];
@ -732,18 +760,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;
}
@ -762,10 +789,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') ";
}
@ -782,7 +808,6 @@
else ADOConnection::outp( "<hr />\n($this->databaseType): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<hr />\n",false);
else
ADOConnection::outp( "=----\n($this->databaseType): ".($sqlTxt)." \n-----\n",false);
flush();
$this->_queryID = $this->_query($sql,$inputarr);
/*
@ -796,7 +821,6 @@
$err = $this->ErrorNo();
if ($err) {
ADOConnection::outp($err.': '.$emsg);
flush();
}
}
} else
@ -804,7 +828,6 @@
$e = $this->ErrorNo();
$m = $this->ErrorMsg();
ADOConnection::outp($e .': '. $m );
flush();
}
} else {
// non-debug version of query
@ -871,7 +894,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) {
@ -879,8 +901,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);
}
@ -897,8 +922,12 @@
*/
function Insert_ID()
{
if ($this->_logsql && $this->lastInsID) return $this->lastInsID;
if ($this->hasInsertID) return $this->_insertid();
if ($this->debug) ADOConnection::outp( '<p>Insert_ID error</p>');
if ($this->debug) {
ADOConnection::outp( '<p>Insert_ID error</p>');
adodb_backtrace();
}
return false;
}
@ -918,7 +947,6 @@
}
}
/**
* @return # rows affected by UPDATE/DELETE
*/
@ -926,7 +954,6 @@
{
if ($this->hasAffectedRows) {
if ($this->fnExecute === 'adodb_log_sql') {
if ($this->_logsql && $this->_affected !== false) return $this->_affected;
}
$val = $this->_affectedrows();
@ -983,6 +1010,8 @@
}
}
if (sizeof($p)) return $p;
if (function_exists('ADODB_VIEW_PRIMARYKEYS'))
return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner);
return false;
}
@ -1085,6 +1114,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
@ -1199,6 +1241,7 @@
$rv = false;
$rs = &$this->Execute($sql, $inputarr);
if ($rs) {
$rv = array();
if ($trim) {
while (!$rs->EOF) {
$rv[] = trim(reset($rs->fields));
@ -1307,8 +1350,8 @@
$ADODB_COUNTRECS = $crecs;
if ($rs) {
$arr = array();
if (!$rs->EOF) $arr = $rs->fields;
else $arr = array();
$rs->Close();
return $arr;
}
@ -1350,76 +1393,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 "<p>Error=".$this->ErrorNo().'<p>';
$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);
}
@ -1447,7 +1424,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);
@ -1793,23 +1770,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
@ -1930,12 +1890,21 @@
}
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.
*/
@ -1944,6 +1913,10 @@
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);
@ -1974,6 +1947,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
@ -2021,7 +2006,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);
}
@ -2041,12 +2026,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);
}
@ -2076,7 +2063,7 @@
function UnixTimeStamp($v)
{
if (!preg_match(
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]+(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
($v), $rr)) return false;
if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0;
@ -2110,6 +2097,49 @@
}
/**
*
* @param v is the character timestamp in YYYY-MM-DD hh:mm:ss format
* @param fmt is the format to apply to it, using date()
*
* @return a timestamp formated as user desires
*/
function UserTimeStamp($v,$fmt='Y-m-d H:i:s')
{
# 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;
if ($tt == 0) return $this->emptyTimeStamp;
return adodb_date($fmt,$tt);
}
/**
* Quotes a string, without prefixing nor appending quotes.
*/
function addq($s,$magicq=false)
{
if (!$magic_quotes) {
if ($this->replaceQuote[0] == '\\'){
// only since php 4.0.5
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
//$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s));
}
return str_replace("'",$this->replaceQuote,$s);
}
// undo magic quotes for "
$s = str_replace('\\"','"',$s);
if ($this->replaceQuote == "\\'") // ' already quoted, no need to change anything
return $s;
else {// change \' to '' for sybase/mssql
$s = str_replace('\\\\','\\',$s);
return str_replace("\\'",$this->replaceQuote,$s);
}
}
/**
* Correctly quotes a string so that all strings are escaped. We prefix and append
@ -2243,21 +2273,22 @@
// 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.
@ -2287,7 +2318,7 @@
var $_atLastPage = false; /** Added by Iván Oliva to implement recordset pagination */
var $_lastPageNo = -1;
var $_maxRecordCount = 0;
var $dateHasTime = false;
var $datetime = false;
/**
* Constructor
@ -2513,10 +2544,11 @@
*/
function UserTimeStamp($v,$fmt='Y-m-d H:i:s')
{
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;
if ($tt == 0) return $this->emptyTimeStamp;
if ($tt === 0) return $this->emptyTimeStamp;
return adodb_date($fmt,$tt);
}
@ -2566,7 +2598,7 @@
{
if (!preg_match(
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]+(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
($v), $rr)) return false;
if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) return 0;
@ -2770,12 +2802,13 @@
*/
function &GetRowAssoc($upper=1)
{
$record = array();
// if (!$this->fields) return $record;
if (!$this->bind) {
$this->GetAssocKeys($upper);
}
$record = array();
foreach($this->bind as $k => $v) {
$record[$k] = $this->fields[$v];
}
@ -3042,6 +3075,7 @@
'TIMESTAMPTZ' => 'T',
'T' => 'T',
##
'BOOL' => 'L',
'BOOLEAN' => 'L',
'BIT' => 'L',
'L' => 'L',
@ -3097,7 +3131,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';
@ -3117,7 +3151,7 @@
return 'B';
case 'D':
if (!empty($this->dateHasTime)) return 'T';
if (!empty($this->datetime)) return 'T';
return 'D';
default:
@ -3160,6 +3194,7 @@
if ($status != false) $this->_atLastPage = $status;
return $this->_atLastPage;
}
} // end class ADORecordSet
//==============================================================================================
@ -3203,7 +3238,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
@ -3220,8 +3255,10 @@
if ($colnames) {
$this->_skiprow1 = false;
$this->_colnames = $colnames;
} else $this->_colnames = $array[0];
} else {
$this->_skiprow1 = true;
$this->_colnames = $array[0];
}
$this->Init();
}
/**
@ -3291,7 +3328,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;
}
@ -3304,11 +3343,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;
}
@ -3321,13 +3360,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;
}
@ -3344,7 +3382,7 @@
//==============================================================================================
/**
* Synonym for ADOLoadCode.
* Synonym for ADOLoadCode. Private function. Do not use.
*
* @deprecated
*/
@ -3354,21 +3392,29 @@
}
/**
* 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 <Karsten.Kraus@web.de>
return @include_once(ADODB_DIR."/drivers/adodb-".$ADODB_Database.".inc.php");
@include_once(ADODB_DIR."/drivers/adodb-".$db.".inc.php");
$ADODB_LASTDB = $db;
$ok = class_exists("ADODB_" . $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;
}
/**
@ -3390,7 +3436,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;
@ -3403,30 +3449,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( "<p>ADONewConnection: Unable to load database driver '$db'</p>",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;
@ -3449,7 +3495,7 @@
if ($perf) $drivername = '';
break;
case 'db2':
if ($perf) break;
break;
default:
$drivername = 'generic';
break;
@ -3490,6 +3536,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();
@ -3516,8 +3563,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;
@ -3525,6 +3570,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;
@ -3548,21 +3595,37 @@
return $ok;
}
/*
Perform a print_r, with pre tags for better formatting.
*/
function adodb_pr($var)
{
if (isset($_SERVER['HTTP_USER_AGENT'])) {
echo " <pre>\n";print_r($var);echo "</pre>\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) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
$MAXSTRLEN = 64;
$s = '<pre align=left>';
$traceArr = debug_backtrace();
$s = ($html) ? '<pre align=left>' : '';
if (is_array($printOrArr)) $traceArr = $printOrArr;
else $traceArr = debug_backtrace();
array_shift($traceArr);
$tabs = sizeof($traceArr)-1;
@ -3571,9 +3634,9 @@
if ($levels < 0) break;
$args = array();
for ($i=0; $i < $tabs; $i++) $s .= ' &nbsp; ';
for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' &nbsp; ' : "\t";
$tabs -= 1;
$s .= '<font face="Courier New,Courier">';
if ($html) $s .= '<font face="Courier New,Courier">';
if (isset($arr['class'])) $s .= $arr['class'].'.';
if (isset($arr['args']))
foreach($arr['args'] as $v) {
@ -3589,16 +3652,17 @@
}
}
$s .= $arr['function'].'('.implode(', ',$args).')';
$s .= @sprintf("</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>",
$arr['line'],$arr['file'],$arr['file']);
$s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
$s .= "\n";
}
$s .= '</pre>';
if ($print) print $s;
}
if ($html) $s .= '</pre>';
if ($printOrArr) print $s;
return $s;
}
} // defined
?>

View File

@ -0,0 +1,157 @@
<?php
/**
* Helper functions to convert between ADODB recordset objects and XMLRPC values.
* Uses John Lim's AdoDB and Edd Dumbill's phpxmlrpc libs
*
* @author Daniele Baroncelli
* @author Gaetano Giunta
* @copyright (c) 2003 Giunta/Baroncelli. All rights reserved.
*
* @todo some more error checking here and there
* @todo document the xmlrpc-struct used to encode recordset info
*/
/**
* Include the main libraries
*/
require_once('xmlrpc.inc');
require_once('adodb.inc.php');
/**
* Builds an xmlrpc struct value out of an AdoDB recordset
*/
function rs2xmlrpcval(&$adodbrs) {
$numfields = $adodbrs->FieldCount();
$numrecords = $adodbrs->RecordCount();
// build structure holding recordset information
$fieldstruct = array();
for ($i = 0; $i < $numfields; $i++) {
$fld = $adodbrs->FetchField($i);
$fieldarray = array();
if (isset($fld->name))
$fieldarray["name"] = new xmlrpcval ($fld->name);
if (isset($fld->type))
$fieldarray["type"] = new xmlrpcval ($fld->type);
if (isset($fld->max_length))
$fieldarray["max_length"] = new xmlrpcval ($fld->max_length, "int");
if (isset($fld->not_null))
$fieldarray["not_null"] = new xmlrpcval ($fld->not_null, "boolean");
if (isset($fld->has_default))
$fieldarray["has_default"] = new xmlrpcval ($fld->has_default, "boolean");
if (isset($fld->default_value))
$fieldarray["default_value"] = new xmlrpcval ($fld->default_value);
$fieldstruct[$i] = new xmlrpcval ($fieldarray, "struct");
}
$fieldcount = new xmlrpcval ($numfields, "int");
$recordcount = new xmlrpcval ($numrecords, "int");
$sql = new xmlrpcval ($adodbrs->sql);
$fieldinfo = new xmlrpcval ($fieldstruct, "array");
$header = new xmlrpcval ( array(
"fieldcount" => $fieldcount,
"recordcount" => $recordcount,
"sql" => $sql,
"fieldinfo" => $fieldinfo
), "struct");
// build structure containing recordset data
$rows = array();
while (!$adodbrs->EOF) {
$columns = array();
// This should work on all cases of fetch mode: assoc, num, both or default
if ($adodbrs->fetchMode == 'ADODB_FETCH_BOTH' || count($adodbrs->fields) == 2 * $adodbrs->FieldCount())
for ($i = 0; $i < $numfields; $i++)
if ($columns[$i] === null)
$columns[$i] = new xmlrpcval ('');
else
$columns[$i] = xmlrpc_encode ($adodbrs->fields[$i]);
else
foreach ($adodbrs->fields as $val)
if ($val === null)
$columns[$i] = new xmlrpcval ('');
else
$columns[] = xmlrpc_encode ($val);
$rows[] = new xmlrpcval ($columns, "array");
$adodbrs->MoveNext();
}
$body = new xmlrpcval ($rows, "array");
// put it all together and build final xmlrpc struct
$xmlrpcrs = new xmlrpcval ( array(
"header" => $header,
"body" => $body,
), "struct");
return $xmlrpcrs;
}
/**
* Returns an xmlrpc struct value as string out of an AdoDB recordset
*/
function rs2xmlrpcstring (&$adodbrs) {
$xmlrpc = rs2xmlrpcval ($adodbrs);
if ($xmlrpc)
return $xmlrpc->serialize();
else
return null;
}
/**
* Given a well-formed xmlrpc struct object returns an AdoDB object
*
* @todo add some error checking on the input value
*/
function xmlrpcval2rs (&$xmlrpcval) {
$fields_array = array();
$data_array = array();
// rebuild column information
$header =& $xmlrpcval->structmem('header');
$numfields = $header->structmem('fieldcount');
$numfields = $numfields->scalarval();
$numrecords = $header->structmem('recordcount');
$numrecords = $numrecords->scalarval();
$sqlstring = $header->structmem('sql');
$sqlstring = $sqlstring->scalarval();
$fieldinfo =& $header->structmem('fieldinfo');
for ($i = 0; $i < $numfields; $i++) {
$temp =& $fieldinfo->arraymem($i);
$fld = new ADOFieldObject();
while (list($key,$value) = $temp->structeach()) {
if ($key == "name") $fld->name = $value->scalarval();
if ($key == "type") $fld->type = $value->scalarval();
if ($key == "max_length") $fld->max_length = $value->scalarval();
if ($key == "not_null") $fld->not_null = $value->scalarval();
if ($key == "has_default") $fld->has_default = $value->scalarval();
if ($key == "default_value") $fld->default_value = $value->scalarval();
} // while
$fields_array[] = $fld;
} // for
// fetch recordset information into php array
$body =& $xmlrpcval->structmem('body');
for ($i = 0; $i < $numrecords; $i++) {
$data_array[$i]= array();
$xmlrpcrs_row =& $body->arraymem($i);
for ($j = 0; $j < $numfields; $j++) {
$temp =& $xmlrpcrs_row->arraymem($j);
$data_array[$i][$j] = $temp->scalarval();
} // for j
} // for i
// finally build in-memory recordset object and return it
$rs = new ADORecordSet_array();
$rs->InitArrayFields($data_array,$fields_array);
return $rs;
}
?>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -13,6 +13,7 @@
class ADODB2_mssql extends ADODB_DataDict {
var $databaseType = 'mssql';
var $dropIndex = 'DROP INDEX %2$s.%1$s';
function MetaType($t,$len=-1,$fieldobj=false)
{
@ -70,7 +71,7 @@ class ADODB2_mssql extends ADODB_DataDict {
function AddColumnSQL($tabname, $flds)
{
if ($this->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 +83,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 +95,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 +198,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();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
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];
$s = "CREATE$unique$clustered INDEX $idxname ON $tabname ($flds)";
if (isset($idxoptions[$this->upperName])) $s .= $idxoptions[$this->upperName];
$sql[] = $s;
return $sql;

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -13,6 +13,10 @@
class ADODB2_mysql extends ADODB_DataDict {
var $databaseType = 'mysql';
var $alterCol = ' MODIFY COLUMN';
var $alterTableAddIndex = true;
var $dropTable = 'DROP TABLE IF EXISTS %s'; // requires mysql 3.22 or later
var $dropIndex = 'DROP INDEX %s ON %s';
function MetaType($t,$len=-1,$fieldobj=false)
{
@ -83,6 +87,7 @@ class ADODB2_mysql extends ADODB_DataDict {
case 'T': return 'DATETIME';
case 'L': return 'TINYINT';
case 'R':
case 'I': return 'INTEGER';
case 'I1': return 'TINYINT';
case 'I2': return 'SMALLINT';
@ -131,14 +136,38 @@ class ADODB2_mysql extends ADODB_DataDict {
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
//if (isset($idxoptions['REPLACE'])) $sql[] = "DROP INDEX IF EXISTS $idxname";
if (isset($idxoptions['FULLTEXT'])) $unique = ' FULLTEXT';
else if (isset($idxoptions['UNIQUE'])) $unique = ' UNIQUE';
else $unique = '';
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
if ($this->alterTableAddIndex) $sql[] = "ALTER TABLE $tabname DROP INDEX $idxname";
else $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);
if ($this->alterTableAddIndex) $s = "ALTER TABLE $tabname ADD $unique INDEX $idxname ";
else $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname;
$s .= ' (' . $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;

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -40,7 +40,7 @@ class ADODB2_oci8 extends ADODB_DataDict {
return 'X2';
case 'NCLOB':
case 'CLOB';
case 'CLOB':
return 'XL';
case 'LONG RAW':
@ -211,18 +211,37 @@ end;
function _IndexSQL($idxname, $tabname, $flds,$idxoptions)
{
if (isset($idxoptions['REPLACE'])) $sql[] = "DROP INDEX $idxname";
$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['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;

View File

@ -1,7 +1,7 @@
<?php
/**
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -16,6 +16,7 @@ class ADODB2_postgres extends ADODB_DataDict {
var $seqField = false;
var $seqPrefix = 'SEQ_';
var $addCol = ' ADD COLUMN';
var $quote = '"';
function MetaType($t,$len=-1,$fieldobj=false)
{
@ -107,12 +108,12 @@ class ADODB2_postgres extends ADODB_DataDict {
}
}
/* The following does not work - does anyone want to contribute code? */
/* The following does not work in Pg 6.0 - does anyone want to contribute code?
//"ALTER TABLE table ALTER COLUMN column SET DEFAULT mydef" and
//"ALTER TABLE table ALTER COLUMN column DROP DEFAULT mydef"
//"ALTER TABLE table ALTER COLUMN column SET NOT NULL" and
//"ALTER TABLE table ALTER COLUMN column DROP NOT NULL"
//"ALTER TABLE table ALTER COLUMN column DROP NOT NULL"*/
function AlterColumnSQL($tabname, $flds)
{
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported for PostgreSQL");
@ -135,7 +136,7 @@ class ADODB2_postgres extends ADODB_DataDict {
}
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= 'NOT NULL';
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
@ -180,15 +181,31 @@ CREATE [ UNIQUE ] INDEX index_name ON table
*/
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['HASH'])) $s .= 'USING HASH ';
if (isset($idxoptions[$this->upperName])) $s .= $idxoptions[$this->upperName];
$s .= "($flds)";
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
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;

View File

@ -0,0 +1,225 @@
<?php
/**
V4.20 22 Feb 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.
Set tabs to 4 for best viewing.
*/
class ADODB2_sybase extends ADODB_DataDict {
var $databaseType = 'sybase';
var $dropIndex = 'DROP INDEX %2$s.%1$s';
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 'INT':
case 'INTEGER': return 'I';
case 'BIT':
case 'TINYINT': return 'I1';
case 'SMALLINT': return 'I2';
case 'BIGINT': return 'I8';
case 'REAL':
case 'FLOAT': return 'F';
default: return parent::MetaType($t,$len,$fieldobj);
}
}
function ActualType($meta)
{
switch(strtoupper($meta)) {
case 'C': return 'VARCHAR';
case 'XL':
case 'X': return 'TEXT';
case 'C2': return 'NVARCHAR';
case 'X2': return 'NTEXT';
case 'B': return 'IMAGE';
case 'D': return 'DATETIME';
case 'T': return 'DATETIME';
case 'L': return 'BIT';
case 'I': return 'INT';
case 'I1': return 'TINYINT';
case 'I2': return 'SMALLINT';
case 'I4': return 'INT';
case 'I8': return 'BIGINT';
case 'F': return 'REAL';
case 'N': return 'NUMERIC';
default:
return $meta;
}
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$f = array();
list($lines,$pkey) = $this->_GenFields($flds);
$s = "ALTER TABLE $tabname $this->addCol";
foreach($lines as $v) {
$f[] = "\n $v";
}
$s .= implode(',',$f);
$sql[] = $s;
return $sql;
}
function AlterColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey) = $this->_GenFields($flds);
foreach($lines as $v) {
$sql[] = "ALTER TABLE $tabname $this->alterCol $v";
}
return $sql;
}
function DropColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
if (!is_array($flds)) $flds = explode(',',$flds);
$f = array();
$s = "ALTER TABLE $tabname";
foreach($flds as $v) {
$f[] = "\n$this->dropCol $v";
}
$s .= implode(',',$f);
$sql[] = $s;
return $sql;
}
// return string must begin with space
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fautoinc) $suffix .= ' DEFAULT AUTOINCREMENT';
if ($fnotnull) $suffix .= ' NOT NULL';
else if ($suffix == '') $suffix .= ' NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
/*
CREATE TABLE
[ database_name.[ owner ] . | owner. ] table_name
( { < column_definition >
| column_name AS computed_column_expression
| < table_constraint > ::= [ CONSTRAINT constraint_name ] }
| [ { PRIMARY KEY | UNIQUE } [ ,...n ]
)
[ ON { filegroup | DEFAULT } ]
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
< column_definition > ::= { column_name data_type }
[ COLLATE < collation_name > ]
[ [ DEFAULT constant_expression ]
| [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
]
[ ROWGUIDCOL]
[ < column_constraint > ] [ ...n ]
< column_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ NULL | NOT NULL ]
| [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
[ WITH FILLFACTOR = fillfactor ]
[ON {filegroup | DEFAULT} ] ]
]
| [ [ FOREIGN KEY ]
REFERENCES ref_table [ ( ref_column ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
]
| CHECK [ NOT FOR REPLICATION ]
( logical_expression )
}
< table_constraint > ::= [ CONSTRAINT constraint_name ]
{ [ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
{ ( column [ ASC | DESC ] [ ,...n ] ) }
[ WITH FILLFACTOR = fillfactor ]
[ ON { filegroup | DEFAULT } ]
]
| FOREIGN KEY
[ ( column [ ,...n ] ) ]
REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
[ ON DELETE { CASCADE | NO ACTION } ]
[ ON UPDATE { CASCADE | NO ACTION } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ]
( search_conditions )
}
*/
/*
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
[ WITH < index_option > [ ,...n] ]
[ ON filegroup ]
< index_option > :: =
{ PAD_INDEX |
FILLFACTOR = fillfactor |
IGNORE_DUP_KEY |
DROP_EXISTING |
STATISTICS_NORECOMPUTE |
SORT_IN_TEMPDB
}
*/
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
if ( isset($idxoptions['DROP']) )
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;
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -1,207 +1,245 @@
<html>
<head>
<title>ADODB Data Dictionary Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<XSTYLE
body,td {font-family:Arial,Helvetica,sans-serif;font-size:11pt}
pre {font-size:9pt}
.toplink {font-size:8pt}
/>
</head>
<body bgcolor="#FFFFFF">
<head>
<title>ADODB Data Dictionary Manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
body, td {
/*font-family: Arial, Helvetica, sans-serif;*/
font-size: 11pt;
}
pre {
font-size: 9pt;
}
.toplink {
font-size: 8pt;
}
</style>
</head>
<body bgcolor="#FFFFFF">
<h2>ADOdb Data Dictionary Library for PHP</h2>
<p> V3.94 13 Oct 2003 (c) 2000-2003 John Lim (<a href="mailto:jlim#natsoft.com.my">jlim#natsoft.com.my</a>)</p>
<p><font size=1>This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products.</font></p>
<p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb?dd=1>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual?dd=1>Other Docs</a>
<p>V4.20 22 Feb 2004 (c) 2000-2004 John Lim (<a href="mailto:jlim#natsoft.com.my">jlim#natsoft.com.my</a>).<br> AXMLS (c) 2004 ars Cognita, Inc</p>
<p><font size="1">This software is dual licensed using BSD-Style and LGPL. This means you can use it in compiled proprietary and commercial products.</font></p>
<p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb?dd=1>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual?dd=1>Other Docs</a></p>
<p>This documentation describes a PHP class library to automate the creation of tables,
indexes and foreign key constraints portably for multiple databases. Richard Tango-Lowy and Dan Cech
have been kind enough to contribute <a href=#xmlschema>AXMLS</a>, an XML schema system for defining databases.</p>
<p>Currently the following databases are supported:</p>
<p>
<b>Well-tested:</b> PostgreSQL, MySQL, Oracle, MSSQL.<br />
<b>Beta-quality:</b> DB2, Informix, Sybase, Interbase, Firebird.<br />
<b>Alpha-quality:</b> MS Access (does not support DEFAULT values) and generic ODBC.
</p>
<p>This documentation describes a class library to automate the creation of tables,
indexes and foreign key constraints portably for multiple databases.
<p>Currently the following databases are supported:
<p> Well-tested: PostgreSQL, MySQL, Oracle, MSSQL. <br>
Beta-quality: DB2, Informix, Sybase, Interbase, Firebird.<br>
Alpha-quality: MS Access (does not support DEFAULT values) and generic ODBC.</p>
<h3>Example Usage</h3>
<pre>include_once('adodb.inc.php');
<font color="#006600">
# First create a normal connection
</font>$db->NewADOConnection('mysql');
$db->Connect(...);
<br>
<font color="#006600"># Then create a data dictionary object, using this connection
</font>$dict = <strong>NewDataDictionary</strong>($db);
<pre>
include_once('adodb.inc.php');
<font color="#006600"># First create a normal connection</font>
$db->NewADOConnection('mysql');
$db->Connect(...);
<font color="#006600"># We have a portable declarative data dictionary format in ADOdb 3.50, similar to SQL.
# Field types use 1 character codes, and fields are separated by commas.
# The following example creates three fields: "col1", "col2" and "col3":</font>
$flds = "
<font color="#663300"><strong> col1 C(32) NOTNULL DEFAULT 'abc',
<font color="#006600"># Then create a data dictionary object, using this connection</font>
$dict = <strong>NewDataDictionary</strong>($db);
<font color="#006600"># We have a portable declarative data dictionary format in ADOdb, similar to SQL.
# Field types use 1 character codes, and fields are separated by commas.
# The following example creates three fields: "col1", "col2" and "col3":</font>
$flds = "
<font color="#663300"><strong> col1 C(32) NOTNULL DEFAULT 'abc',
col2 I DEFAULT 0,
col3 N(12.2)</strong></font>
";<br>
<font color="#006600"># We demonstrate creating tables and indexes</font>
$sqlarray = $dict-><strong>CreateTableSQL</strong>($tabname, $flds, $taboptarray);
$dict-><strong>ExecuteSQLArray</strong>($sqlarray);<br>
$idxflds = 'co11, col2';
$sqlarray = $dict-><strong>CreateIndexSQL</strong>($idxname, $tabname, $idxflds);
$dict-><strong>ExecuteSQLArray</strong>($sqlarray);
";
<font color="#006600"># We demonstrate creating tables and indexes</font>
$sqlarray = $dict-><strong>CreateTableSQL</strong>($tabname, $flds, $taboptarray);
$dict-><strong>ExecuteSQLArray</strong>($sqlarray);<br>
$idxflds = 'co11, col2';
$sqlarray = $dict-><strong>CreateIndexSQL</strong>($idxname, $tabname, $idxflds);
$dict-><strong>ExecuteSQLArray</strong>($sqlarray);
</pre>
<h3>Functions</h3>
<p><b>function CreateDatabase($dbname, $optionsarray=false)</b>
<p>Create a database with the name $dbname;
<p><b>function CreateTableSQL($tabname, $fldarray, $taboptarray=false)</b>
<h4>function CreateDatabase($dbname, $optionsarray=false)</h4>
<p>Create a database with the name $dbname;</p>
<h4>function CreateTableSQL($tabname, $fldarray, $taboptarray=false)</h4>
<pre>
RETURNS: an array of strings, the sql to be executed, or false
$tabname: name of table
$fldarray: string (or array) containing field info
$taboptarray: array containing table options
</pre>
<p>
The new format of $fldarray uses a free text format, where each field is comma-delimited.
The first token for each field is the field name, followed by the type and optional
field size. Then optional keywords in $otheroptions:
<pre> "$fieldname $type $colsize $otheroptions"</pre>
<p> 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:
<p>The new format of $fldarray uses a free text format, where each field is comma-delimited.
The first token for each field is the field name, followed by the type and optional
field size. Then optional keywords in $otheroptions:</p>
<pre> "$fieldname $type $colsize $otheroptions"</pre>
<p>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:</p>
<pre> array($fieldname, $type, [,$colsize] [,$otheroptions]*)</pre>
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.
<p>
Legal portable type codes include:
<p>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.</p>
<p>Legal portable type codes include:</p>
<pre>
C: varchar
X: Largest varchar size
XL: For Oracle, returns CLOB, otherwise same as 'X' above
C: varchar
X: Largest varchar size
XL: For Oracle, returns CLOB, otherwise same as 'X' above
C2: Multibyte varchar
X2: Multibyte varchar (largest size)
C2: Multibyte varchar
X2: Multibyte varchar (largest size)
B: BLOB (binary large object)<br>
D: Date (some databases do not support this, and we return a datetime type)
T: Datetime or Timestamp
L: Integer field suitable for storing booleans (0 or 1)
I: Integer (mapped to I4)
I1: 1-byte integer
I2: 2-byte integer
I4: 4-byte integer
I8: 8-byte integer
F: Floating point number
N: Numeric or decimal number
B: BLOB (binary large object)
D: Date (some databases do not support this, and we return a datetime type)
T: Datetime or Timestamp
L: Integer field suitable for storing booleans (0 or 1)
I: Integer (mapped to I4)
I1: 1-byte integer
I2: 2-byte integer
I4: 4-byte integer
I8: 8-byte integer
F: Floating point number
N: Numeric or decimal number
</pre>
<p> The $colsize field represents the size of the field. If a decimal number is
used, then it is assumed that the number following the dot is the precision,
so 6.2 means a number of size 6 digits and 2 decimal places. It is
recommended that the default for number types be represented as a string to
avoid any rounding errors.
<p>
The $otheroptions include the following keywords (case-insensitive):
<p>The $colsize field represents the size of the field. If a decimal number is used, then it is assumed that the number following the dot is the precision, so 6.2 means a number of size 6 digits and 2 decimal places. It is recommended that the default for number types be represented as a string to avoid any rounding errors.</p>
<p>The $otheroptions include the following keywords (case-insensitive):</p>
<pre>
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.
PRIMARY Same as KEY.
DEF Synonym for DEFAULT for lazy typists.
DEFAULT The default value. Character strings are auto-quoted unless
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
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.
</pre>
<p> The Data Dictonary accepts two formats, the older array specification: </p>
<p>The Data Dictonary accepts two formats, the older array specification:</p>
<pre>
$flds = array(
array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NotNull'),
array('ID', 'I' , 'AUTO'),
array('MYDATE', 'D' , 'DEFDATE'),
array('NAME', 'C' ,'32',
'CONSTRAINTS' => 'FOREIGN KEY REFERENCES reftable')
); </pre>
Or the simpler declarative format:
<pre> $flds = "
<font color="#660000"><strong> COLNAME DECIMAL(8.4) DEFAULT 0 NotNull,
ID I AUTO,
MYDATE D DEFDATE,
NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable' </strong></font>
";
$flds = array(
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')
);
</pre>
<p>
The $taboptarray is the 3rd parameter of the CreateTableSQL function.
This contains table specific settings. Legal keywords include:
<p>Or the simpler declarative format:</p>
<pre>
$flds = "<font color="#660000"><strong>
COLNAME DECIMAL(8.4) DEFAULT 0 NOTNULL,
id I AUTO,
`MY DATE` D DEFDATE,
NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable'</strong></font>
";
</pre>
<p>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.</p>
<p>The $taboptarray is the 3rd parameter of the CreateTableSQL function. This contains table specific settings. Legal keywords include:</p>
<ul>
<li>REPLACE <br>
Indicates that the previous table definition should be removed (dropped)together
with ALL data. See first example below.<br>
<li><b>REPLACE</b><br />
Indicates that the previous table definition should be removed (dropped)together with ALL data. See first example below.
</li>
<li><b>DROP</b><br />
Drop table. Useful for removing unused tables.
</li>
<li><b>CONSTRAINTS</b><br />
Define this as the key, with the constraint as the value. See the postgresql example below.
Additional constraints defined for the whole table. You will probably need to prefix this with a comma.
</li>
<li>CONSTRAINTS <br>
Define this as the key, with the constraint as the value. See the postgresql
example below. Additional constraints defined for the whole table. You
will probably need to prefix this with a comma. </li>
</ul>
<p> Database specific table options can be defined also using the name of the
database type as the array key. In the following example, <em>create the table
as ISAM with MySQL, and store the table in the &quot;users&quot; tablespace
if using Oracle</em>. And if the table already exists, drop the table first.
<pre> $taboptarray = array('mysql' => 'TYPE=ISAM', 'oci8' => 'tablespace users', 'REPLACE'); </pre>
<p>
You can also define foreignkey constraints. The following is syntax for
postgresql:<pre>
$taboptarray = array('constraints' =>
', FOREIGN KEY (col1) REFERENCES reftable (refcol)');
</pre>
<p><strong>function ChangeTableSQL($tabname, $flds)</strong>
<p>Database specific table options can be defined also using the name of the database type as the array key. In the following example, <em>create the table as ISAM with MySQL, and store the table in the &quot;users&quot; tablespace if using Oracle</em>. And because we specified REPLACE, drop the table first.</p>
<pre> $taboptarray = array('mysql' => 'TYPE=ISAM', 'oci8' => 'tablespace users', 'REPLACE');</pre>
<p>You can also define foreignkey constraints. The following is syntax for postgresql:
<pre> $taboptarray = array('constraints' => ', FOREIGN KEY (col1) REFERENCES reftable (refcol)');</pre>
<h4>function DropTableSQL($tabname)</h4>
<p>Returns the SQL to drop the specified table.</p>
<h4>function ChangeTableSQL($tabname, $flds)</h4>
<p>Checks to see if table exists, if table does not exist, behaves like CreateTableSQL.
If table exists, generates appropriate ALTER TABLE MODIFY COLUMN commands if
field already exists, or ALTER TABLE ADD $column if field does not exist.
field already exists, or ALTER TABLE ADD $column if field does not exist.</p>
<p>The class must be connected to the database for ChangeTableSQL to detect the
existance of the table. Idea and code contributed by Florian Buzin.
<p><b>function CreateIndexSQL($idxname, $tabname, $flds, $idxoptarray=false)</b>
<p>
existence of the table. Idea and code contributed by Florian Buzin.</p>
<h4>function CreateIndexSQL($idxname, $tabname, $flds, $idxoptarray=false)</h4>
<pre>
RETURNS: an array of strings, the sql to be executed, or false
<pre>
$idxname: name of index
$tabname: name of table
$flds: list of fields as a comma delimited string or an array of strings
$idxoptarray: array of index creation options
</pre>
<p> $idxoptarray is similar to $taboptarray in that index specific information can
be embedded in the array. Other options include:
<pre>
</pre>
<p>$idxoptarray is similar to $taboptarray in that index specific information can be embedded in the array. Other options include:</p>
<pre>
CLUSTERED Create clustered index (only mssql)
BITMAP Create bitmap index (only oci8)
UNIQUE Make unique index
FULLTEXT Make fulltext index (only mysql)
HASH Create hash index (only postgres)
</pre>
<p> <strong>function AddColumnSQL($tabname, $flds)</strong>
<p>Add one or more columns. Not guaranteed to work under all situations.
<p><strong>function AlterColumnSQL($tabname, $flds)</strong>
<p>Warning, not all databases support this feature.
<p> <strong>function DropColumnSQL($tabname, $flds)</strong>
<p>Drop 1 or more columns.
<p> <strong>function ExecuteSQLArray($sqlarray, $contOnError = true)</strong>
DROP Drop legacy index
</pre>
<h4>function DropIndexSQL ($idxname, $tabname = NULL)</h4>
<p>Returns the SQL to drop the specified index.</p>
<h4>function AddColumnSQL($tabname, $flds)</h4>
<p>Add one or more columns. Not guaranteed to work under all situations.</p>
<h4>function AlterColumnSQL($tabname, $flds)</h4>
<p>Warning, not all databases support this feature.</p>
<h4>function DropColumnSQL($tabname, $flds)</h4>
<p>Drop 1 or more columns.</p>
<h4>function SetSchema($schema)</h4>
<p>Set the schema.</p>
<h4>function &amp;MetaTables()</h4>
<h4>function &amp;MetaColumns($tab, $upper=true, $schema=false)</h4>
<h4>function &amp;MetaPrimaryKeys($tab,$owner=false,$intkey=false)</h4>
<h4>function &amp;MetaIndexes($table, $primary = false, $owner = false)</h4>
<p>These functions are wrappers for the corresponding functions in the connection object. However, the table names will be autoquoted by the TableName function (see below) before being passed to the connection object.</p>
<h4>function NameQuote($name = NULL)</h4>
<p>If the provided name is quoted with backquotes (`) or contains special characters, returns the name quoted with the appropriate quote character, otherwise the name is returned unchanged.</p>
<h4>function TableName($name)</h4>
<p>The same as NameQuote, but will prepend the current schema if specified</p>
<h4>function MetaType($t,$len=-1,$fieldobj=false)</h4>
<h4>function ActualType($meta)</h4>
<p>Convert between database-independent 'Meta' and database-specific 'Actual' type codes.</p>
<h4>function ExecuteSQLArray($sqlarray, $contOnError = true)</h4>
<pre>
RETURNS: 0 if failed, 1 if executed all but with errors, 2 if executed successfully
$sqlarray: an array of strings with sql code (no semicolon at the end of string)
$contOnError: if true, then continue executing even if error occurs
</pre>
<p>Executes an array of SQL strings returned by CreateTableSQL or CreateIndexSQL.
<hr><a name=xmlschema></a>
<h2>XML Schema</h2>
This is a class contributed by Richard Tango-Lowy that allows the user to quickly
and easily build a database using the excellent
ADODB database library and a simple XML formatted file.
<p>Executes an array of SQL strings returned by CreateTableSQL or CreateIndexSQL.</p>
<hr />
<H3>Quick Start</H3>
<P>First, create an XML database schema. Let's call it "schema.xml:"</P><PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
<a name=xmlschema></a>
<h2>ADOdb XML Schema (AXMLS)</h2>
<p>This is a class contributed by Richard Tango-Lowy and Dan Cech that allows the user to quickly
and easily build a database using the excellent ADODB database library and a simple XML formatted file.
You can <a href=http://sourceforge.net/projects/adodb-xmlschema/>download the latest version of AXMLS here</a>.</p>
<h3>Quick Start</h3>
<p>First, create an XML database schema. Let's call it "schema.xml:"</p>
<pre>
&lt;?xml version="1.0"?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
&lt;table name="mytable"&gt;
&lt;field name="row1" type="I"&gt;
&lt;descr&gt;An integer row that's a primary key and autoincrements&lt;/descr&gt;
@ -212,11 +250,11 @@ ADODB database library and a simple XML formatted file.
&lt;descr&gt;A 16 character varchar row that can't be null&lt;/descr&gt;
&lt;NOTNULL/&gt;
&lt;/field&gt;
&lt;/table&gt;
&lt;index name="myindex" table="mytable"&gt;
&lt;index name=&quot;myindex&quot;&gt;
&lt;col&gt;row1&lt;/col&gt;
&lt;col&gt;row2&lt;/col&gt;
&lt;/index&gt;
&lt;/table&gt;
&lt;sql&gt;
&lt;descr&gt;SQL to be executed only on specific platforms&lt;/descr&gt;
&lt;query platform="postgres|postgres7"&gt;
@ -226,41 +264,252 @@ ADODB database library and a simple XML formatted file.
insert into mytable ( row1, row2 ) values ( 12, 'different stuff' )
&lt;/query&gt;
&lt;/sql&gt;
&lt;/schema&gt;
</PRE><P>Create a new database using the appropriate tool for your platform.
&lt;/schema&gt;
</pre>
<p>Create a new database using the appropriate tool for your platform.<br />
Executing the following PHP code will create the a <i>mytable</i> and <i>myindex</i>
in the database and insert one row into <i>mytable</i> if the platform is postgres or mysql. </P><PRE>
include_once('/path/to/adodb.inc.php');
include_once('/path/to/adodb-xmlschema.inc.php');
in the database and insert one row into <i>mytable</i> if the platform is postgres or mysql.</p>
// To build the schema, start by creating a normal ADOdb connection:
$db->NewADOConnection( 'mysql' );
$db->Connect( ... );
<pre>
include_once('/path/to/adodb.inc.php');
include_once('/path/to/adodb-xmlschema.inc.php');
// Create the schema object and build the query array.
$schema = <B>new adoSchema</B>( $db );
<font color="#006600">// To build the schema, start by creating a normal ADOdb connection:</font>
$db->NewADOConnection( 'mysql' );
$db->Connect( ... );
// Optionally, set a prefix for newly-created tables. In this example
// the prefix "myprefix_" will result in a table named "myprefix_tablename".
//$schema-><B>setPrefix</B>( "myprefix_" );
<font color="#006600">// Create the schema object and build the query array.</font>
$schema = new <b>adoSchema</b>( $db );
// Build the SQL array
$sql = $schema-><B>ParseSchema</B>( "schema.xml" );
<font color="#006600">// Optionally, set a prefix for newly-created tables. In this example
// the prefix "myprefix_" will result in a table named "myprefix_tablename".</font>
$schema-><b>SetPrefix</b>( 'myprefix_' );
// Execute the SQL on the database
$result = $schema-><B>ExecuteSchema</B>( $sql );
<font color="#006600">// Build the SQL array</font>
$schema-><b>ParseSchema</b>( 'schema.xml' );
// Finally, clean up after the XML parser
// (PHP won't do this for you!)
$schema-><B>Destroy</B>();
<font color="#006600">// Execute the SQL on the database</font>
$result = $schema-><b>ExecuteSchema</b>();
</PRE>
<font color="#006600">// Finally, clean up after the XML parser
// (PHP won't do this for you!)</font>
$schema-><b>Destroy</b>();
</pre>
<h3>Using AXMLS in Your
Application</h3>
<p>
There are two steps involved in using
AXMLS in your application: first,
you must create a schema, or XML representation of your
database, and second, you must create the PHP code that will
parse and execute the schema.</p>
<p>Let's begin with a schema that describes a typical, if simplistic
user management table for an application.</p>
<pre class="listing"><pre>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
&lt;table name=&quot;users&quot;&gt;
&lt;desc&gt;A typical users table for our application.&lt;/desc&gt;
&lt;field name=&quot;userId&quot; type=&quot;I&quot;&gt;
&lt;descr&gt;A unique ID assigned to each user.&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name=&quot;userName&quot; type=&quot;C&quot; size=&quot;16&quot;&gt;&lt;NOTNULL/&gt;&lt;/field&gt;
&lt;index name=&quot;userName&quot;&gt;
&lt;descr&gt;Put a unique index on the user name&lt;/descr&gt;
&lt;col&gt;userName&lt;/col&gt;
&lt;UNIQUE/&gt;
&lt;/index&gt;
&lt;/table&gt;
&lt;sql&gt;
&lt;descr&gt;Insert some data into the users table.&lt;/descr&gt;
&lt;query&gt;insert into users (userName) values ( 'admin' )&lt;/query&gt;
&lt;query&gt;insert into users (userName) values ( 'Joe' )&lt;/query&gt;
&lt;/sql&gt;
&lt;/schema&gt;
</pre></pre>
<p>Let's take a detailed look at this schema.</p>
<p>The opening &lt;?xml version=&quot;1.0&quot;?&gt; tag is
required by XML. The &lt;schema&gt; tag
tells the parser that the enclosed markup defines an XML
schema. The version=&quot;0.2&quot; attribute sets
<em>the version of the AXMLS DTD used by the XML
schema.</em> <p>All versions of AXMLS prior
to version 1.0 have a schema version of &quot;0.1&quot;. The current
schema version is &quot;0.2&quot;.</p></p>
<pre class="listing"><pre>
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
...
&lt;/schema&gt;
</pre></pre>
<p>Next we define one or more tables. A table consists of a
fields (and other objects) enclosed by
&lt;table&gt; tags. The
name=&quot;&quot; attribute specifies the name of
the table that will be created in the database.</p>
<pre class="listing"><pre>
&lt;table name=&quot;users&quot;&gt;
&lt;desc&gt;A typical users table for our application.&lt;/desc&gt;
&lt;field name=&quot;userId&quot; type=&quot;I&quot;&gt;
&lt;descr&gt;A unique ID assigned to each user.&lt;/descr&gt;
&lt;KEY/&gt;
&lt;AUTOINCREMENT/&gt;
&lt;/field&gt;
&lt;field name=&quot;userName&quot; type=&quot;C&quot; size=&quot;16&quot;&gt;&lt;NOTNULL/&gt;&lt;/field&gt;
&lt;/table&gt;
</pre></pre>
<p>This table is called &quot;users&quot; and has a description and
two fields. The description is optional, and is currently
only for your own information; it is not applied to the
database.</p>
<p>The first &lt;field&gt; tag will create
a field named &quot;userId&quot; of type &quot;I&quot;, or integer. (See the
ADOdb Data Dictionary
documentation for a list of valid types.) This
&lt;field&gt; tag encloses two special
field options: &lt;KEY/&gt;, which
specifies this field as a primary key, and
&lt;AUTOINCREMENT/&gt;, which specifies
that the database engine should automatically fill this
field with the next available value when a new row is
inserted.</p>
<p>The second &lt;field&gt; tag will create
a field named &quot;userName&quot; of type &quot;C&quot;, or character, and of
length 16 characters. The &lt;NOTNULL/&gt;
option specifies that this field does not allow
NULLs.</p>
<p>There are two ways to add indexes to a table. The
simplest is to mark a field with the
&lt;KEY/&gt; option as described above; a
primary key is a unique index. The second and more powerful
method uses the &lt;index&gt; tags.</p>
<pre class="listing"><pre>
&lt;table name=&quot;users&quot;&gt;
...
&lt;index name=&quot;userName&quot;&gt;
&lt;descr&gt;Put a unique index on the user name&lt;/descr&gt;
&lt;col&gt;userName&lt;/col&gt;
&lt;UNIQUE/&gt;
&lt;/index&gt;
&lt;/table&gt;
</pre></pre>
<p>The &lt;index&gt; tag specifies that an
index should be created on the enclosing table. The
name=&quot;&quot; attribute provides the name of the
index that will be created in the database. The
description, as above, is for your information only. The
&lt;col&gt; tags list each column that
will be included in the index. Finally, the
&lt;UNIQUE/&gt; tag specifies that this
will be created as a unique index.</p>
<p>Finally, AXMLS allows you to include arbitrary SQL that
will be applied to the database when the schema is
executed.</p>
<pre class="listing"><pre>
&lt;sql&gt;
&lt;descr&gt;Insert some data into the users table.&lt;/descr&gt;
&lt;query&gt;insert into users (userName) values ( 'admin' )&lt;/query&gt;
&lt;query&gt;insert into users (userName) values ( 'Joe' )&lt;/query&gt;
&lt;/sql&gt;
</pre></pre>
<p>The &lt;sql&gt; tag encloses any number
of SQL queries that you define for your own use.</p>
<p>Now that we've defined an XML schema, you need to know how to
apply it to your database. Here's a simple PHP script that shows
how to load the schema.</p>
<p><pre class="listing"><pre>
&lt;?PHP
/* You must tell the script where to find the ADOdb and
* the AXMLS libraries.
*/
require( &quot;path_to_adodb/adodb.inc.php&quot;);
require( &quot;path_to_adodb/adodb-xmlschema.inc.php&quot; );
/* Configuration information. Define the schema filename,
* RDBMS platform (see the ADODB documentation for valid
* platform names), and database connection information here.
*/
$schemaFile = 'example.xml';
$platform = 'mysql';
$dbHost = 'localhost';
$dbName = 'database';
$dbUser = 'username';
$dbPassword = 'password';
/* Start by creating a normal ADODB connection.
*/
$db = ADONewConnection( $platform );
$db-&gt;Connect( $dbHost, $dbUser, $dbPassword, $dbName );
/* Use the database connection to create a new adoSchema object.
*/
$schema = new adoSchema( $db );
/* Call ParseSchema() to build SQL from the XML schema file.
* Then call ExecuteSchema() to apply the resulting SQL to
* the database.
*/
$sql = $schema-&gt;ParseSchema( $schemaFile );
$result = $schema-&gt;ExecuteSchema();
?&gt;
</pre></pre></p>
<p>Let's look at each part of the example in turn. After you
manually create the database, there are three steps required to
load (or upgrade) your schema.</p>
<p>First, create a normal ADOdb connection. The variables
and values here should be those required to connect to your
database.</p>
<pre class="listing"><pre>
$db = ADONewConnection( 'mysql' );
$db-&gt;Connect( 'host', 'user', 'password', 'database' );
</pre></pre>
<p>Second, create the adoSchema object that load and
manipulate your schema. You must pass an ADOdb database
connection object in order to create the adoSchema
object.</p>
<pre class="listing"><pre>
$schema = new adoSchema( $db );
</pre></pre>
<p>Third, call ParseSchema() to parse the
schema and then ExecuteSchema() to apply
it to the database. You must pass
ParseSchema() the path and filename of
your schema file.</p>
<pre class="listing"><pre>
$schema-&gt;ParseSchema( $schemaFile );
$schema-&gt;ExecuteSchema();
</pre></pre>
<p>Execute the above code and then log into your database. If you've
done all this right, you should see your tables, indexes, and
SQL.</p>
<p>You can find the source files for this tutorial in the
examples directory as
tutorial_shema.xml and
tutorial.php. See the class documentation for
a more detailed description of the adoSchema methods, including
methods and schema elements that are not described in this
tutorial.</p>
<H3>XML Schema Format:</H3>
<P>(See <a href="http://arscognita.com/xmlschema.dtd">ADOdb_schema.dtd</a> for the full specification)</P>
<P>(See <a href="xmlschema.dtd">xmlschema.dtd</a> for the full specification)</P>
<PRE>
&lt;?xml version="1.0"?&gt;
&lt;schema&gt;
&lt;?xml version="1.0"?&gt;
&lt;schema version=&quot;0.2&quot;&gt;
&lt;table name="tablename" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;field name="fieldname" type="datadict_type" size="size"&gt;
@ -269,29 +518,34 @@ $schema-><B>Destroy</B>();
&lt;AUTOINCREMENT/&gt;
&lt;DEFAULT value="value"/&gt;
&lt;/field&gt;
... <i>more fields</i>
&lt;/table&gt;
... <i>more tables</i>
<i> ... more fields</i>
&lt;index name="indexname" platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;col&gt;fieldname&lt;/col&gt;
... <i>more columns</i>
<i> ... more columns</i>
&lt;/index&gt;
... <i>more indices</i>
<i> ... more indexes</i>
&lt;/table&gt;
<i> ... more tables</i>
&lt;sql platform="platform1|platform2|..."&gt;
&lt;descr&gt;Optional description&lt;/descr&gt;
&lt;query platform="platform1|platform2|..."&gt;SQL query&lt;/query&gt;
... <i>more queries</i>
<i> ... more queries</i>
&lt;/sql&gt;
... <i>more SQL</i>
<i> ... more SQL</i>
&lt;/schema&gt;
</PRE>
<HR>
</pre>
<address>If you have any questions or comments, please email them to me at
<a href="mailto:richtl#arscognita.com">richtl#arscognita.com</a>.</address>
<h3>Upgrading</h3>
If your schema version is older, than XSLT is used to transform the schema to the newest version.
This means that if you are using an older XML schema format, you need to have the XSLT extension installed.
If you do not want to require your users to have the XSLT extension installed, make sure you
modify your XML schema to conform to the latest version.
<hr />
<address>If you have any questions or comments, please email them to Richard at richtl#arscognita.com.
</address>
</body>
</html>

View File

@ -7,7 +7,7 @@
<body>
<h3>The ADOdb Performance Monitoring Library</h3>
<p>V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my)</p>
<p>V4.20 22 Feb 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)</p>
<p><font size="1">This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products.</font></p>
<p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb?perf=1>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual?perf=1>Other Docs</a>
@ -27,6 +27,7 @@
<li>a list of all tables in the current database</li>
<li>an interface to continiously poll the server for key performance indicators
such as CPU, Hit Ratio, Disk I/O</li>
<li>a form where you can enter and run SQL interactively.</li>
</ul>
<li>Gives you an API to build database monitoring tools for a server farm, for
example calling <code>$perf->DBParameter('data cache hit ratio')</code> returns
@ -84,7 +85,13 @@ Thx to Fernando Ortiz for the informix module.
<p><font face="Courier New, Courier, mono">function <b>UI($pollsecs=5)</b></font></p>
<p>Creates a web-based user interface for performance monitoring. When you click on Poll,
server statistics will be displayed every $pollsecs seconds. See <a href="#usage">Usage</a>
above. Sample output follows below:</p>
above.
<p>Since 4.11, we allow users to enter and run SQL interactively via the "Run SQL" link. To disable
this for security reasons, set this constant before calling $perf->UI().
<p>
<pre>define('ADODB_PERF_NO_RUN_SQL',1);</pre>
<p>Sample output follows below:</p>
<table border=1 width=100% bgcolor=lightyellow><tr>
<td> <b><a href=http://php.weblogs.com/adodb?perf=1>ADOdb</a> Performance

View File

@ -11,14 +11,15 @@
<body bgcolor="#FFFFFF">
<h3>ADODB Session Management Manual</h3>
<p>
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my)
V4.20 22 Feb 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)
<p> <font size=1>This software is dual licensed using BSD-Style and LGPL. This
means you can use it in compiled proprietary and commercial products. </font>
<p>Useful ADOdb links: <a href=http://php.weblogs.com/adodb>Download</a> &nbsp; <a href=http://php.weblogs.com/adodb_manual>Other Docs</a>
<h3>Introduction</h3>
<p>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.
<p>
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.
<p>
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
<p>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.
<p><b>Important Upgrade Notice:</b> 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.
<h4>ADOdb Session Handler Features</h4>
<ul>
<li>Ability to define a notification function that is called when a session expires. Typically
used to detect session logout and release global resources.
<li>Optimization of database writes. We crc32 the session data and only perform an update
to the session data if there is a data change.
<li>Support for large amounts of session data with CLOBs (see adodb-session-clob.inc.php). Useful
<li>Support for large amounts of session data with CLOBs (see adodb-session-clob.php). Useful
for Oracle.
<li>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
<h3>Setup</h3>
<p>There are 3 session management files that you can use:
<pre>
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
<strong>Examples</strong>
<font color=#004040>
include('adodb/adodb.inc.php');
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-session.php');
<b> $ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';</b>
<b>include('adodb/session/adodb-session.php');</b>
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
#
# Test session vars, the following should increment on refresh
#
$_SESSION['AVAR'] += 1;
print "&lt;p>\$_SESSION['AVAR']={$_SESSION['AVAR']}&lt;/p>";
</font>
To force non-persistent connections, call adodb_session_open first before session_start():
<font color=#004040>
include('adodb/adodb.inc.php');
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-session.php');
adodb_sess_open(false,false,false);
<b> $ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';</b>
<b>include('adodb/session/adodb-session.php');
adodb_sess_open(false,false,false);</b>
session_start();
session_register('AVAR');
$HTTP_SESSION_VARS['AVAR'] += 1;
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
</font color=#004040>
To use a encrypted sessions, simply replace the file:
<font color=#004040>
include('adodb/adodb.inc.php');
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-cryptsession.php');
<b> $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');</b>
session_start();
</font>
And the same technique for adodb-session-clob.php:
<font color=#004040>
include('adodb/adodb.inc.php');
And the same technique for adodb-session-clob.inc.php:
<b> $ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';
GLOBAL $HTTP_SESSION_VARS;
include('adodb.inc.php');
include('adodb-session-clob.php');
include('adodb/session/adodb-session-clob.php');</b>
session_start();
</font>
<h4>Installation</h4>
1. Create this table in your database (syntax might vary depending on your db):
<a name=sessiontab></a>
<a name=sessiontab></a> <font color=#004040>
create table sessions (
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:
);</font>
For the adodb-session-clob.php version, create this:
<font color=#004040>
create table sessions (
SESSKEY char(32) not null,
EXPIRY int(11) unsigned not null,
EXPIREREF varchar(64),
DATA CLOB,
primary key (sesskey)
);
);</font>
2. Then define the following parameters. You can either modify
this file, or define them before this file is included:
<font color=#004040>
$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'
$ADODB_SESSION_TBL = 'sessions'; # setting this is optional
</font>
When the session is created, $<b>ADODB_SESS_CONN</b> holds the connection object.
3. Recommended is PHP 4.0.6 or later. There are documented
session bugs in earlier versions of PHP.
3. Recommended is PHP 4.0.6 or later. There are documented session bugs
in earlier versions of PHP.
</pre>
<h4>Notifications</h4>
If you want to receive notifications when a session expires, then
you can tag a session with an <a href="#sessiontab">EXPIREREF</a> 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
<h3>Notifications</h3>
<p>If you want to receive notification when a session expires, then
tag the session record with a <a href="#sessiontab">EXPIREREF</a> 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.
<p>
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:
<p>
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:
<pre> <font color=#004040>
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
</font></pre>
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.
<p>
Here is an example of a Notification function that deletes some records in the database
and temporary files:
<pre><font color=#004040>
function NotifyFn($expireref, $sesskey)
{
global $ADODB_SESS_CONN; # the session connection object
Then when the NotifyFn is called, we are passed the $USERID as the first
parameter, eg. NotifyFn($userid, $sesskey).
$user = $ADODB_SESS_CONN->qstr($expireref);
$ADODB_SESS_CONN->Execute("delete from shopping_cart where user=$user");
system("rm /work/tmpfiles/$expireref/*");
}</font>
</pre>
<p>
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.
<p>
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.
<h4>Compression/Encryption Schemes</h4>
Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and compression schemes are supported.
Currently, supported:
<pre>
MD5Crypt (crypt.inc.php)
MCrypt
Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)
GZip
BZip2
</pre>
These are stackable. E.g.
<pre>
ADODB_Session::filter(new ADODB_Compress_Bzip2());
ADODB_Session::filter(new ADODB_Encrypt_MD5());
</pre>
will compress and then encrypt the record in the database.
<p>
Also see the <a href=docs-adodb.htm>core ADOdb documentation</a>.
</body>

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -193,6 +193,9 @@ class ADODB_ado extends ADOConnection {
return $arr;
}
/* returns queryID or false */
function &_query($sql,$inputarr=false)
{
@ -543,15 +546,18 @@ class ADORecordSet_ado extends ADORecordSet {
switch($t) {
case 135: // timestamp
$this->fields[] = date('Y-m-d H:i:s',(integer)$f->value);
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;
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,6 +583,24 @@ 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;

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -27,6 +27,9 @@ class ADODB_ado_mssql extends ADODB_ado {
var $leftOuter = '*=';
var $rightOuter = '=*';
var $ansiOuter = true; // for mssql7 or later
var $substr = "substring";
var $length = 'len';
var $upperCase = 'upper';
//var $_inTransaction = 1; // always open recordsets, so no transaction problems.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -118,8 +118,6 @@ class ADODB_csv extends ADOConnection {
foreach($inputarr as $v) {
$sql .= $sqlarr[$i];
// from Ron Baldwin <ron.baldwin@sourceprose.com>
// Only quote string types
if (gettype($v) == 'string')
$sql .= $this->qstr($v);
else if ($v === null)

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -64,6 +64,22 @@ $db = NewADOConnection('db2');
$db->curMode = SQL_CUR_USE_ODBC;
$db->Connect($dsn, $userid, $pwd);
USING CLI INTERFACE
===================
I have had reports that the $host and $database params have to be reversed in
Connect() when using the CLI interface. From Halmai Csongor csongor.halmai#nexum.hu:
> The symptom is that if I change the database engine from postgres or any other to DB2 then the following
> connection command becomes wrong despite being described this version to be correct in the docs.
>
> $connection_object->Connect( $DATABASE_HOST, $DATABASE_AUTH_USER_NAME, $DATABASE_AUTH_PASSWORD, $DATABASE_NAME )
>
> In case of DB2 I had to swap the first and last arguments in order to connect properly.
*/
if (!defined('_ADODB_ODBC_LAYER')) {
@ -82,9 +98,8 @@ class ADODB_DB2 extends ADODB_odbc {
var $fmtTimeStamp = "'Y-m-d-H.i.s'";
var $ansiOuter = true;
var $identitySQL = 'values IDENTITY_VAL_LOCAL()';
var $_bindInputArray = true;
var $_bindInputArray = false;
var $upperCase = 'upper';
var $substr = 'substr';
function ADODB_DB2()
@ -116,35 +131,6 @@ class ADODB_DB2 extends ADODB_odbc {
if ($this->_autocommit) $this->BeginTrans();
return $this->GetOne("select 1 as ignore from $tables where $where for update");
}
/*
function &MetaTables($showSchema=false)
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
$qid = odbc_tables($this->_connectionID);
$rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
//print_r($rs);
$arr =& $rs->GetArray();
$rs->Close();
$arr2 = array();
//print_r($arr);
for ($i=0; $i < sizeof($arr); $i++) {
$row = $arr[$i];
if ($row[2] && strncmp($row[1],'SYS',3) != 0)
if ($showSchema) $arr2[] = $row[1].'.'.$row[2];
else $arr2[] = $row[2];
}
return $arr2;
}*/
function &MetaTables($ttype=false,$showSchema=false)
{
@ -243,20 +229,22 @@ class ADODB_DB2 extends ADODB_odbc {
}
function &SelectLimit($sql,$nrows=-1,$offset=-1)
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
{
if ($offset <= 0) {
// could also use " OPTIMIZE FOR $nrows ROWS "
if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY ";
return $this->Execute($sql,false);
$rs =& $this->Execute($sql,$inputArr);
} 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,$inputArr);
}
return $rs;
}
};

View File

@ -1,6 +1,6 @@
<?php
/*
@version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
@version V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -45,10 +45,12 @@ class ADODB_firebird extends ADODB_ibase {
$str .=($offset>=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;
}

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -28,13 +28,15 @@ class ADODB_ibase extends ADOConnection {
var $databaseType = "ibase";
var $dataProvider = "ibase";
var $replaceQuote = "''"; // string to use to replace quotes
var $ibase_timefmt = '%Y-%m-%d';
var $ibase_timefmt = '%Y-%m-%d'; // For hours,mins,secs change to '%Y-%m-%d %H:%M:%S';
var $fmtDate = "'Y-m-d'";
var $fmtTimeStamp = "'Y-m-d, H:i:s'";
var $concat_operator='||';
var $_transactionID;
var $metaTablesSQL = "select rdb\$relation_name from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
var $metaColumnsSQL = "select a.rdb\$field_name,b.rdb\$field_type,b.rdb\$field_length from rdb\$relation_fields a join rdb\$fields b on a.rdb\$field_source=b.rdb\$field_name where rdb\$relation_name ='%s'";
//OPN STUFF start
var $metaColumnsSQL = "select a.rdb\$field_name, a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";
//OPN STUFF end
var $ibasetrans;
var $hasGenID = true;
var $_bindInputArray = true;
@ -120,6 +122,60 @@ class ADODB_ibase 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);
}
$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
@ -260,8 +273,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 +347,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 +458,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;
}
$fld->type = $tt;
$fld->max_length = $rs->fields[2];
if (isset($rs->fields[2])) {
$fld->has_default = true;
$d = substr($rs->fields[2],strlen('default '));
switch ($fld->type)
{
case 'smallint':
case 'integer': $fld->default_value = (int) $d; break;
case 'char':
case 'blob':
case 'text':
case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
case 'double':
case 'float': $fld->default_value = (float) $d; break;
default: $fld->default_value = $d; break;
}
// case 35:$tt = 'TIMESTAMP'; break;
}
if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
$fld->sub_type = $rs->fields[5];
} else {
$fld->sub_type = null;
}
//OPN STUFF end
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
@ -517,6 +634,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++;
@ -594,6 +724,10 @@ 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,6 +738,8 @@ 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]);
}
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim. All rights reserved.
V4.20 22 Feb 2004 (c) 2000-2004 John Lim. 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.
@ -14,6 +14,8 @@ V3.94 13 Oct 2003 (c) 2000-2003 John Lim. All rights reserved.
*/
if (!defined('IFX_SCROLL')) define('IFX_SCROLL',1);
class ADODB_informix72 extends ADOConnection {
var $databaseType = "informix72";
var $dataProvider = "informix";
@ -40,6 +42,7 @@ class ADODB_informix72 extends ADOConnection {
var $_bindInputArray = true; // set to true if ADOConnection.Execute() permits binding of array parameters.
var $sysDate = 'TODAY';
var $sysTimeStamp = 'CURRENT';
var $cursorType = IFX_SCROLL; // IFX_SCROLL or IFX_HOLD or 0
function ADODB_informix72()
{
@ -56,6 +59,18 @@ class ADODB_informix72 extends ADOConnection {
}
}
function ServerInfo()
{
if (isset($this->version)) return $this->version;
$arr['description'] = $this->GetOne("select DBINFO('version','full') from systables where tabid = 1");
$arr['version'] = $this->GetOne("select DBINFO('version','major')||"."||DBINFO('version','minor') from systables where tabid = 1");
$this->version = $arr;
return $arr;
}
function _insertid()
{
$sqlca =ifx_getsqlca($this->lastQuery);
@ -116,7 +131,9 @@ class ADODB_informix72 extends ADOConnection {
function ErrorNo()
{
return ifx_error();
preg_match("/.*SQLCODE=([^\]]*)/",ifx_error(),$parse); //!EOS
if (is_array($parse) && isset($parse[1])) return (int)$parse[1];
return 0;
}
@ -177,7 +194,11 @@ class ADODB_informix72 extends ADOConnection {
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('ifx_connect')) return false;
$dbs = $argDatabasename . "@" . $argHostname;
if ($argHostname) putenv("INFORMIXSERVER=$argHostname");
putenv("INFORMIXSERVER=".trim($argHostname));
$this->_connectionID = ifx_connect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
@ -187,14 +208,17 @@ 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;
putenv("INFORMIXSERVER=".trim($argHostname));
$this->_connectionID = ifx_pconnect($dbs,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;
}
/*
// ifx_do does not accept bind parameters - wierd ???
// ifx_do does not accept bind parameters - weird ???
function Prepare($sql)
{
$stmt = ifx_prepare($sql);
@ -223,10 +247,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 {

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -75,6 +75,7 @@ class ADODB_mssql extends ADOConnection {
var $fmtTimeStamp = "'Y-m-d h:i:sA'";
var $hasInsertID = true;
var $substr = "substring";
var $length = 'len';
var $upperCase = 'upper';
var $hasAffectedRows = true;
var $metaDatabasesSQL = "select name from sysdatabases where name <> '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)
{
@ -236,7 +241,7 @@ class ADODB_mssql extends ADOConnection {
break;
case 'H':
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':
@ -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
@ -565,7 +574,14 @@ order by constraint_name, referenced_table_name, keyno";
if (is_string($v)) {
$len = strlen($v);
if ($len == 0) $len = 1;
if ($len > 4000 ) {
// NVARCHAR is max 4000 chars. Let's use NTEXT
$decl .= "@P$i NTEXT";
} else {
$decl .= "@P$i NVARCHAR($len)";
}
$params .= "@P$i=N". (strncmp($v,"'",1)==0? $v : $this->qstr($v));
} else if (is_integer($v)) {
$decl .= "@P$i INT";

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -34,8 +34,8 @@ class ADODB_mysql extends ADOConnection {
var $forceNewConnect = false;
var $poorAffectedRows = true;
var $clientFlags = 0;
var $dbxDriver = 1;
var $substr = "substring";
var $nameQuote = '`'; /// string to use to quote identifiers and names
function ADODB_mysql()
{
@ -43,7 +43,7 @@ class ADODB_mysql extends ADOConnection {
function ServerInfo()
{
$arr['description'] = $this->GetOne("select version()");
$arr['description'] = ADOConnection::GetOne("select version()");
$arr['version'] = ADOConnection::_findvers($arr['description']);
return $arr;
}
@ -68,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 INDEX 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)
{
@ -127,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));
@ -144,6 +202,7 @@ class ADODB_mysql extends ADOConnection {
if ($rs) $rs->Close();
$this->_logsql = $savelog;
return $this->genID;
}
@ -239,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);
@ -319,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];
@ -326,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") {
@ -365,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;
}
@ -483,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 */
@ -574,6 +644,7 @@ class ADORecordSet_mysql extends ADORecordSet{
case 'BLOB':
case 'MEDIUMBLOB':
return !empty($fieldobj->binary) ? 'B' : 'X';
case 'YEAR':
case 'DATE': return 'D';

View File

@ -0,0 +1,828 @@
<?php
/*
V4.20 22 Feb 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.
Set tabs to 8.
MySQL code that does not support transactions. Use mysqlt if you need transactions.
Requires mysql client. Works on Windows and Unix.
21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl)
Based on adodb 3.40
*/
if (! defined("_ADODB_MYSQL_LAYER")) {
define("_ADODB_MYSQL_LAYER", 1 );
class ADODB_mysqli extends ADOConnection {
var $databaseType = 'mysqli';
var $dataProvider = 'native';
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL = "SHOW TABLES";
var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
var $hasLimit = true;
var $hasMoveFirst = true;
var $hasGenID = true;
var $upperCase = 'upper';
var $isoDates = true; // accepts dates in ISO format
var $sysDate = 'CURDATE()';
var $sysTimeStamp = 'NOW()';
var $hasTransactions = false;
var $forceNewConnect = false;
var $poorAffectedRows = true;
var $clientFlags = 0;
var $executeOnly = true;
var $substr = "substring";
var $nameQuote = '`'; /// string to use to quote identifiers and names
//var $_bindInputArray = true;
function ADODB_mysqli()
{
if(!extension_loaded("mysqli"))
{
trigger_error("You must have the MySQLi extension.", E_USER_ERROR);
}
}
function IfNull( $field, $ifNull )
{
return " IFNULL($field, $ifNull) "; // if MySQL
}
function ServerInfo()
{
$arr['description'] = $this->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';
}
}
}
}
?>

View File

@ -1,7 +1,7 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/*
version V3.94 13 Oct 2003 (c) 2000-2003 John Lim. All rights reserved.
version V4.20 22 Feb 2004 (c) 2000-2004 John Lim. All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
@ -33,9 +33,8 @@ year entries allows you to become year-2000 compliant. For example:
NLS_DATE_FORMAT='RR-MM-DD'
You can also modify the date format using the ALTER SESSION command.
*/
class ADODB_oci8 extends ADOConnection {
var $databaseType = 'oci8';
var $dataProvider = 'oci8';
@ -55,8 +54,7 @@ class ADODB_oci8 extends ADOConnection {
var $_genSeqSQL = "CREATE SEQUENCE %s START WITH %s";
var $_dropSeqSQL = "DROP SEQUENCE %s";
var $hasAffectedRows = true;
var $upperCase = 'upper';
var $substr = 'substr';
var $random = "abs(mod(DBMS_RANDOM.RANDOM,10000001)/10000000)";
var $noNullStrings = false;
var $connectSID = false;
var $_bind = false;
@ -150,6 +148,9 @@ NATSOFT.DOMAIN =
*/
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$mode=0)
{
if (!function_exists('OCIPLogon')) return false;
$this->_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)
{
@ -215,7 +218,7 @@ NATSOFT.DOMAIN =
function _affectedrows()
{
if (is_resource($this->_stmt)) return OCIRowCount($this->_stmt);
if (is_resource($this->_stmt)) return @OCIRowCount($this->_stmt);
return 0;
}
@ -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
@ -497,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;
}
}
@ -588,18 +594,18 @@ NATSOFT.DOMAIN =
$stmt = $this->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
*/
function Prepare($sql)
function Prepare($sql,$cursor=false)
{
static $BINDNUM = 0;
$stmt = OCIParse($this->_connectionID,$sql);
if (!$stmt) return $sql; // error in statement, let Execute() handle the error
if (!$stmt) return false;
$BINDNUM += 1;
if (@OCIStatementType($stmt) == 'BEGIN') {
return array($sql,$stmt,0,$BINDNUM,OCINewCursor($this->_connectionID));
return array($sql,$stmt,0,$BINDNUM, ($cursor) ? OCINewCursor($this->_connectionID) : false);
}
return array($sql,$stmt,0,$BINDNUM);
@ -622,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);
}
}
@ -710,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);
}
@ -792,10 +799,10 @@ 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;
@ -1062,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();
@ -1101,7 +1111,7 @@ class ADORecordset_oci8 extends ADORecordSet {
function _fetch()
{
return OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
return @OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
}
/* close() only needs to be called if you are worried about using too much memory while your script
@ -1136,7 +1146,7 @@ class ADORecordset_oci8 extends ADORecordSet {
case 'NCLOB':
case 'LONG':
case 'LONG VARCHAR':
case 'CLOB';
case 'CLOB':
return 'X';
case 'LONG RAW':

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim. All rights reserved.
V4.20 22 Feb 2004 (c) 2000-2004 John Lim. 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.
@ -35,14 +35,14 @@ class ADODB_oci8po extends ADODB_oci8 {
return '?';
}
function Prepare($sql)
function Prepare($sql,$cursor=false)
{
$sqlarr = explode('?',$sql);
$sql = $sqlarr[0];
for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
$sql .= ':'.($i-1) . $sqlarr[$i];
}
return ADODB_oci8::Prepare($sql);
return ADODB_oci8::Prepare($sql,$cursor);
}
// emulate handling of parameters ? ?, replacing with :bind0 :bind1
@ -112,10 +112,18 @@ class ADORecordset_oci8po extends ADORecordset_oci8 {
// 10% speedup to move MoveNext to child class
function MoveNext()
{
if (!$this->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) {
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;
}

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -156,6 +156,9 @@ class ADODB_odbc extends ADOConnection {
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
{
global $php_errormsg;
if (!function_exists('odbc_connect')) return false;
if ($this->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,6 +358,8 @@ 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]);
@ -449,7 +456,7 @@ class ADODB_odbc extends ADOConnection {
if (! $this->_bindInputArray) return $sql; // no binding
$stmt = odbc_prepare($this->_connectionID,$sql);
if (!$stmt) {
// print "Prepare Error for ($sql) ".$this->ErrorMsg()."<br>";
// we don't know whether odbc driver is parsing prepared stmts, so just return sql
return $sql;
}
return array($sql,$stmt,false);
@ -519,8 +526,6 @@ class ADODB_odbc extends ADOConnection {
} else
$this->_errorMsg = $php_errormsg;
}
return $stmtid;
}
@ -632,7 +637,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);

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -31,6 +31,7 @@ class ADODB_odbc_mssql extends ADODB_odbc {
var $rightOuter = '=*';
var $upperCase = 'upper';
var $substr = 'substring';
var $length = 'len';
var $ansiOuter = true; // for mssql7 or later
var $identitySQL = 'select @@IDENTITY'; // 'select SCOPE_IDENTITY'; # for mssql 2000
var $hasInsertID = true;
@ -157,9 +158,11 @@ order by constraint_name, referenced_table_name, keyno";
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
@ -196,7 +199,7 @@ order by constraint_name, referenced_table_name, keyno";
break;
case 'H':
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
break;
case 'i':

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -69,8 +69,17 @@ class ADODB_postgres64 extends ADOConnection{
FROM pg_class c, pg_attribute a,pg_type t
WHERE relkind = 'r' AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
AND a.attnum > 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,11 @@ 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
var $_bindInputArray = false; // requires postgresql 7.3+ and ability to modify database
// The last (fmtTimeStamp is not entirely correct:
// PostgreSQL also has support for time zones,
@ -348,6 +360,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 +371,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,19 +382,23 @@ 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));
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;
@ -453,8 +471,7 @@ select viewname,'V' from pg_views where viewname like $mask";
// Freek
if (is_array($keys)) {
reset ($keys);
while (list($x,$key) = each($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)
@ -463,14 +480,77 @@ select viewname,'V' from pg_views where viewname like $mask";
}
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
else $retarr[strtoupper($fld->name)] = $fld;
else $retarr[($upper) ? strtoupper($fld->name) : $fld->name] = $fld;
$rs->MoveNext();
}
$rs->Close();
return $retarr;
}
return false;
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
@ -480,6 +560,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) {
@ -492,8 +575,6 @@ select viewname,'V' from pg_views where viewname like $mask";
if ($host[0]) $str = "host=".adodb_addslashes($host[0]);
else $str = 'host=localhost';
if (isset($host[1])) $str .= " port=$host[1]";
} else {
$str = 'host=localhost';
}
if ($user) $str .= " user=".$user;
if ($pwd) $str .= " password=".$pwd;
@ -535,15 +616,43 @@ select viewname,'V' from pg_views where viewname like $mask";
return $this->_connect($str,$user,$pwd,$db,1);
}
// returns queryID or false
function _query($sql,$inputarr)
{
/*
if (is_array($sql)) {
if (!$sql[1]) {
$sqltxt = $sql[0];
$plan = $sql[1] = 'P'.md5($sqltxt);
if ($inputarr) {
/*
It appears that PREPARE/EXECUTE is slower for many queries.
For query executed 1000 times:
"select id,firstname,lastname from adoxyz
where firstname not like ? and lastname not like ? and id = ?"
with plan = 1.51861286163 secs
no plan = 1.26903700829 secs
*/
$plan = 'P'.md5($sql);
$execp = '';
foreach($inputarr as $v) {
if ($execp) $execp .= ',';
if (is_string($v)) {
if (strncmp($v,"'",1) !== 0) $execp .= $this->qstr($v);
} else {
$execp .= $v;
}
}
if ($execp) $exsql = "EXECUTE $plan ($execp)";
else $exsql = "EXECUTE $plan";
$rez = @pg_exec($this->_connectionID,$exsql);
if (!$rez) {
# Perhaps plan does not exist? Prepare/compile plan.
$params = '';
foreach($inputarr as $v) {
if ($params) $params .= ',';
@ -555,40 +664,26 @@ select viewname,'V' from pg_views where viewname like $mask";
$params .= "REAL";
}
}
$sqlarr = explode('?',$sqltxt);
$sqltxt = '';
$sqlarr = explode('?',$sql);
//print_r($sqlarr);
$sql = '';
$i = 1;
foreach($sqlarr as $v) {
$sqltxt .= $v.'$'.$i;
$sql .= $v.' $'.$i;
$i++;
}
$s = "PREPARE $plan ($params) AS ".substr($sqltxt,0,strlen($sqltxt)-2);
adodb_pr($s);
$s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
//adodb_pr($s);
pg_exec($this->_connectionID,$s);
echo $this->ErrorMsg();
}
$rez = pg_exec($this->_connectionID,$exsql);
} else {
$plan = $sql[1];
}
$params = '';
foreach($inputarr as $v) {
if ($params) $params .= ',';
if (is_string($v)) {
if (strncmp($v,"'",1) !== 0) $params .= $this->qstr($v.'TEST');
} else {
$params .= $v;
}
}
if ($params) $sql = "EXECUTE $plan ($params)";
else $sql = "EXECUTE $plan";
adodb_pr(">>>>>".$sql);
pg_exec($this->_connectionID,$s);
}*/
$this->_errorMsg = false;
//adodb_backtrace();
$rez = pg_exec($this->_connectionID,$sql);
}
// check if no data returned, then no need to create real recordset
if ($rez && pg_numfields($rez) <= 0) {
if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
@ -689,7 +784,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()
@ -754,10 +850,6 @@ class ADORecordSet_postgres64 extends ADORecordSet{
}
if ($this->fetchMode == PGSQL_ASSOC || $this->fetchMode == PGSQL_BOTH) {
foreach($this->_blobArr as $k => $v) {
if (!isset($this->fields[$v])) {
$this->fields = false;
return;
}
$this->fields[$v] = ADORecordSet_postgres64::_decode($this->fields[$v]);
}
}
@ -770,9 +862,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;
}
}
@ -784,11 +875,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));
}

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -24,16 +24,19 @@ class ADODB_postgres7 extends ADODB_postgres64 {
$this->ADODB_postgres64();
}
// the following should be compat with postgresql 7.2,
// which makes obsolete the LIMIT limit,offset syntax
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : '';
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;
}
/*
function Prepare($sql)
@ -45,7 +48,44 @@ class ADODB_postgres7 extends ADODB_postgres64 {
return $sql;
}
*/
function MetaForeignKeys($table, $owner=false, $upper=false)
// from Edward Jaramilla, improved version - works on pg 7.4
function MetaForeignKeys($table, $owner=false, $upper=false)
{
$sql = 'SELECT t.tgargs as args
FROM
pg_trigger t,pg_class c,pg_proc p
WHERE
t.tgenabled AND
t.tgrelid = c.oid AND
t.tgfoid = p.oid AND
p.proname = \'RI_FKey_check_ins\' AND
c.relname = \''.strtolower($table).'\'
ORDER BY
t.tgrelid';
$rs = $this->Execute($sql);
if ($rs && !$rs->EOF) {
$arr =& $rs->GetArray();
$a = array();
foreach($arr as $v)
{
$data = explode(chr(0), $v['args']);
if ($upper) {
$a[strtoupper($data[2])][] = strtoupper($data[4].'='.$data[5]);
} else {
$a[$data[2]][] = $data[4].'='.$data[5];
}
}
return $a;
}
return false;
}
function xMetaForeignKeys($table, $owner=false, $upper=false)
{
$sql = '
@ -135,7 +175,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;
}
}

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,6 +1,6 @@
<?php
/*
version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights
version V4.20 22 Feb 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,

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -26,6 +26,7 @@ class ADODB_sqlite extends ADOConnection {
var $metaTablesSQL = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
var $sysDate = "adodb_date('Y-m-d')";
var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')";
var $fmtTimeStamp = "'Y-m-d H:i:s'";
function ADODB_sqlite()
{
@ -126,6 +127,8 @@ class ADODB_sqlite extends ADOConnection {
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sqlite_open')) return false;
$this->_connectionID = sqlite_open($argHostname);
if ($this->_connectionID === false) return false;
$this->_createFunctions();
@ -135,6 +138,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 +161,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;
}
/*

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim. All rights reserved.
V4.20 22 Feb 2004 (c) 2000-2004 John Lim. 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.
@ -24,14 +24,14 @@ class ADODB_sybase extends ADOConnection {
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL="select name from sysobjects where type='U' or type='V'";
var $metaColumnsSQL = "SELECT c.name,t.name,c.length FROM syscolumns c, systypes t, sysobjects o WHERE o.name='%s' and t.xusertype=c.xusertype and o.id=c.id";
// see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
var $metaColumnsSQL = "SELECT c.column_name, c.column_type, c.width FROM syscolumn c, systable t WHERE t.table_name='%s' AND c.table_id=t.table_id AND t.table_type='BASE'";
/*
"select c.name,t.name,c.length from
syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
where o.name='%s'";
*/
var $concat_operator = '+';
var $sysDate = 'GetDate()';
var $arrayClass = 'ADORecordSet_array_sybase';
var $sysDate = 'GetDate()';
var $leftOuter = '*=';
@ -112,6 +112,8 @@ class ADODB_sybase extends ADOConnection {
// returns true or false
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
{
if (!function_exists('sybase_connect')) return false;
$this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
if ($this->_connectionID === false) return false;
if ($argDatabasename) return $this->SelectDB($argDatabasename);
@ -120,6 +122,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);
@ -140,14 +144,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;
@ -233,6 +238,23 @@ class ADODB_sybase extends ADOConnection {
}
return $s;
}
# Added 2003-10-07 by Chris Phillipson
# Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
# to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
function MetaPrimaryKeys($table)
{
$sql = "SELECT c.column_name " .
"FROM syscolumn c, systable t " .
"WHERE t.table_name='$table' AND c.table_id=t.table_id " .
"AND t.table_type='BASE' " .
"AND c.pkey = 'Y' " .
"ORDER BY c.column_id";
$a = $this->GetCol($sql);
if ($a && sizeof($a)>0) return $a;
return false;
}
}
/*--------------------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -0,0 +1,35 @@
<?php
// Catalan language
// contributed by "Josep Lladonosa" jlladono#pie.xtec.es
$ADODB_LANG_ARRAY = array (
'LANG' => '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'
);
?>

View File

@ -0,0 +1,35 @@
<?php
// Chinese language file contributed by "Cuiyan (cysoft)" cysoft#php.net.
// Encode by GB2312
// Simplified Chinese
$ADODB_LANG_ARRAY = array (
'LANG' => '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 => '没有合适的权限'
);
?>

View File

@ -0,0 +1,33 @@
<?php
// contributed by "Heinz Hombergs" <opn@hhombergs.de>
$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&ouml;schen',
DB_ERROR_CANNOT_DROP => 'Tabelle oder Index konnte nicht gel&ouml;scht werden',
DB_ERROR_CONSTRAINT => 'Constraint Verletzung',
DB_ERROR_DIVZERO => 'Division durch Null',
DB_ERROR_INVALID => 'ung&uml;ltig',
DB_ERROR_INVALID_DATE => 'ung&uml;ltiges Datum oder Zeit',
DB_ERROR_INVALID_NUMBER => 'ung&uml;ltige Zahl',
DB_ERROR_MISMATCH => 'Unvertr&auml;glichkeit',
DB_ERROR_NODBSELECTED => 'keine Dantebank ausgew&auml;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&uml;tzt',
DB_ERROR_VALUE_COUNT_ON_ROW => 'Anzahl der zur&uml;ckgelieferten Felder entspricht nicht der Anzahl der Felder in der Abfrage',
DB_ERROR_INVALID_DSN => 'ung&uml;ltiger DSN',
DB_ERROR_CONNECT_FAILED => 'Verbindung konnte nicht hergestellt werden',
0 => 'kein Fehler', // DB_OK
DB_ERROR_NEED_MORE_DATA => 'Nicht gen&uml;gend Daten geliefert',
DB_ERROR_EXTENSION_NOT_FOUND=> 'erweiterung nicht gefunden',
DB_ERROR_NOSUCHDB => 'keine Datenbank',
DB_ERROR_ACCESS_VIOLATION => 'ungen&uml;gende Rechte'
);
?>

View File

@ -28,6 +28,6 @@ $ADODB_LANG_ARRAY = array (
DB_ERROR_NEED_MORE_DATA => 'donn&eacute;es fournies insuffisantes',
DB_ERROR_EXTENSION_NOT_FOUND=> 'extension non trouv&eacute;e',
DB_ERROR_NOSUCHDB => 'base de donn&eacute;es inconnue',
DB_ERROR_ACCESS_VIOLATION => 'droits ynsuffisants'
DB_ERROR_ACCESS_VIOLATION => 'droits insuffisants'
);
?>

View File

@ -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'
);
?>

View File

@ -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

View File

@ -1,4 +1,245 @@
<h3>Old Changelog</h3>
<p><b>3.50 19 May 2003</b></p>
<p>Fixed mssql compat with FreeTDS. FreeTDS does not implement mssql_fetch_assoc().
<p>Merged back connection and recordset code into adodb.inc.php.
<p>ADOdb sessions using oracle clobs contributed by achim.gosse#ddd.de. See adodb-session-clob.php.
<p>Added /s modifier to preg_match everywhere, which ensures that regex does not
stop at /n. Thx Pao-Hsi Huang.
<p>Fixed error in metacolumns() for mssql.
<p>Added time format support for SQLDate.
<p>Image => B added to metatype.
<p>MetaType now checks empty($this->blobSize) instead of empty($this).
<p>Datadict has beta support for informix, sybase (mapped to mssql), db2 and generic
(which is a fudge).
<p>BlobEncode for postgresql uses pg_escape_bytea, if available. Needed for compat
with 7.3.
<p>Added $ADODB_LANG, to support multiple languages in MetaErrorMsg().
<p>Datadict can now parse table definition as declarative text.
<p>For DataDict, oci8 autoincrement trigger missing semi-colon. Fixed.
<p>For DataDict, when REPLACE flag enabled, drop sequence in datadict for autoincrement
field in postgres and oci8.s
<p>Postgresql defaults to template1 database if no database defined in connect/pconnect.
<p>We now clear _resultid in postgresql if query fails.
<p><b>3.40 19 May 2003</b></p>
<p>Added insert_id for odbc_mssql.
<p>Modified postgresql UpdateBlobFile() because it did not work in safe mode.
<p>Now connection object is passed to raiseErrorFn as last parameter. Needed by
StartTrans().
<p>Added StartTrans() and CompleteTrans(). It is recommended that you do not modify
transOff, but use the above functions.
<p>oci8po now obeys ADODB_ASSOC_CASE settings.
<p>Added virtualized error codes, using PEAR DB equivalents. Requires you to manually
include adodb-error.inc.php yourself, with MetaError() and MetaErrorMsg($errno).
<p>GetRowAssoc for mysql and pgsql were flawed. Fix by Ross Smith.
<p>Added to datadict types I1, I2, I4 and I8. Changed datadict type 'T' to map
to timestamp instead of datetime for postgresql.
<p>Error handling in ExecuteSQLArray(), adodb-datadict.inc.php did not work.
<p>We now auto-quote postgresql connection parameters when building connection
string.
<p>Added session expiry notification.
<p>We now test with odbc mysql - made some changes to odbc recordset constructor.
<p>MetaColumns now special cases access and other databases for odbc.
<p><b>3.31 17 March 2003</b></p>
<p>Added row checking for _fetch in postgres.
<p>Added Interval type to MetaType for postgres.
<p>Remapped postgres driver to call postgres7 driver internally.
<p>Adorecordset_array::getarray() did not return array when nRows >= 0.
<p>Postgresql: at times, no error message returned by pg_result_error() but error
message returned in pg_last_error(). Recoded again.
<p>Interbase blob's now use chunking for updateblob.
<p>Move() did not set EOF correctly. Reported by Jorma T.
<p>We properly support mysql timestamp fields when we are creating mysql tables
using the data-dict interface.
<p>Table regex includes backticks character now.
<p><b>3.30 3 March 2003</b></p>
<p>Added $ADODB_EXTENSION and $ADODB_COMPAT_FETCH constant.
<p>Made blank1stItem configurable using syntax "value:text" in GetMenu/GetMenu2.
Thx to Gabriel Birke.
<p>Previously ADOdb differed from the Microsoft standard because it did not define
what to set $this->fields when EOF was reached. Now at EOF, ADOdb sets $this->fields
to false for all databases, which is consist with Microsoft's implementation.
Postgresql and mysql have always worked this way (in 3.11 and earlier). If you
are experiencing compatibility problems (and you are not using postgresql nor
mysql) on upgrading to 3.30, try setting the global variables $ADODB_COUNTRECS
= true (which is the default) and $ADODB_FETCH_COMPAT = true (this is a new
global variable).
<p>We now check both pg_result_error and pg_last_error as sometimes pg_result_error
does not display anything. Iman Mayes
<p> We no longer check for magic quotes gpc in Quote().
<p> Misc fixes for table creation in adodb-datadict.inc.php. Thx to iamsure.
<p> Time calculations use adodb_time library for all negative timestamps due to
problems in Red Hat 7.3 or later. Formerly, only did this for Windows.
<p> In mssqlpo, we now check if $sql in _query is a string before we change ||
to +. This is to support prepared stmts.
<p> Move() and MoveLast() internals changed to support to support EOF and $this->fields
change.
<p> Added ADODB_FETCH_BOTH support to mssql. Thx to Angel Fradejas afradejas#mediafusion.es
<p> We now check if link resource exists before we run mysql_escape_string in
qstr().
<p> Before we flock in csv code, we check that it is not a http url.
<p><b>3.20 17 Feb 2003</b></p>
<p>Added new Data Dictionary classes for creating tables and indexes. Warning
- this is very much alpha quality code. The API can still change. See adodb/tests/test-datadict.php
for more info.
<p>We now ignore $ADODB_COUNTRECS for mysql, because PHP truncates incomplete
recordsets when mysql_unbuffered_query() is called a second time.
<p>Now postgresql works correctly when $ADODB_COUNTRECS = false.
<p>Changed _adodb_getcount to properly support SELECT DISTINCT.
<p>Discovered that $ADODB_COUNTRECS=true has some problems with prepared queries
- suspect PHP bug.
<p>Now GetOne and GetRow run in $ADODB_COUNTRECS=false mode for better performance.
<p>Added support for mysql_real_escape_string() and pg_escape_string() in qstr().
<p>Added an intermediate variable for mysql _fetch() and MoveNext() to store fields,
to prevent overwriting field array with boolean when mysql_fetch_array() returns
false.
<p>Made arrays for getinsertsql and getupdatesql case-insensitive. Suggested by
Tim Uckun" tim#diligence.com
<p><b>3.11 11 Feb 2003</b></p>
<p>Added check for ADODB_NEVER_PERSIST constant in PConnect(). If defined, then
PConnect() will actually call non-persistent Connect().
<p>Modified interbase to properly work with Prepare().
<p>Added $this->ibase_timefmt to allow you to change the date and time format.
<p>Added support for $input_array parameter in CacheFlush().
<p>Added experimental support for dbx, which was then removed when i found that
it was slower than using native calls.
<p>Added MetaPrimaryKeys for mssql and ibase/firebird.
<p>Added new $trim parameter to GetCol and CacheGetCol
<p>Uses updated adodb-time.inc.php 0.06.
<p><b>3.10 27 Jan 2003</b>
<p>Added adodb_date(), adodb_getdate(), adodb_mktime() and adodb-time.inc.php.
<p>For interbase, added code to handle unlimited number of bind parameters. From
Daniel Hasan daniel#hasan.cl.
<p>Added BlobDecode and UpdateBlob for informix. Thx to Fernando Ortiz.
<p>Added constant ADODB_WINDOWS. If defined, means that running on Windows.
<p>Added constant ADODB_PHPVER which stores php version as a hex num. Removed
$ADODB_PHPVER variable.
<p>Felho Bacsi reported a minor white-space regular expression problem in GetInsertSQL.
<p>Modified ADO to use variant to store _affectedRows
<p>Changed ibase to use base class Replace(). Modified base class Replace() to
support ibase.
<p>Changed odbc to auto-detect when 0 records returned is wrong due to bad odbc
drivers.
<p>Changed mssql to use datetimeconvert ini setting only when 4.30 or later (does
not work in 4.23).
<p>ExecuteCursor($stmt, $cursorname, $params) now accepts a new $params array
of additional bind parameters -- William Lovaton walovaton#yahoo.com.mx.
<p>Added support for sybase_unbuffered_query if ADODB_COUNTRECS == false. Thx
to chuck may.
<p>Fixed FetchNextObj() bug. Thx to Jorma Tuomainen.
<p>We now use SCOPE_IDENTITY() instead of @@IDENTITY for mssql - thx to marchesini#eside.it
<p>Changed postgresql movenext logic to prevent illegal row number from being
passed to pg_fetch_array().
<p>Postgresql initrs bug found by "Bogdan RIPA" bripa#interakt.ro $f1 accidentally
named $f
<p><b>3.00 6 Jan 2003</b>
<p>Fixed adodb-pear.inc.php syntax error.
<p>Improved _adodb_getcount() to use SELECT COUNT(*) FROM ($sql) for languages
that accept it.
<p>Fixed _adodb_getcount() caching error.
<p>Added sql to retrive table and column info for odbc_mssql.
<p><strong>2.91 3 Jan 2003</strong>
<p>Revised PHP version checking to use $ADODB_PHPVER with legal values 0x4000,
0x4050, 0x4200, 0x4300.
<p>Added support for bytea fields and oid blobs in postgres by allowing BlobDecode()
to detect and convert non-oid fields. Also added BlobEncode to postgres when
you want to encode oid blobs.
<p>Added blobEncodeType property for connections to inform phpLens what encoding
method to use for blobs.
<p>Added BlobDecode() and BlobEncode() to base ADOConnection class.
<p>Added umask() to _gencachename() when creating directories.
<p>Added charPage for ado drivers, so you can set the code page.
<pre>
$conn->charPage = CP_UTF8;
$conn->Connect($dsn);
</pre>
<p>Modified _seek in mysql to check for num rows=0.
<p>Added to metatypes new informix types for IDS 9.30. Thx Fernando Ortiz.
<p>_maxrecordcount returned in CachePageExecute $rsreturn
<p>Fixed sybase cacheselectlimit( ) problems
<p>MetaColumns() max_length should use precision for types X and C for ms access.
Fixed.
<p>Speedup of odbc non-SELECT sql statements.
<p>Added support in MetaColumns for Wide Char types for ODBC. We halve max_length
if unicode/wide char.
<p>Added 'B' to types handled by GetUpdateSQL/GetInsertSQL.
<p>Fixed warning message in oci8 driver with $persist variable when using PConnect.
<p><b>2.90 11 Dec 2002</b>
<p>Mssql and mssqlpo and oci8po now support ADODB_ASSOC_CASE.
<p>Now MetaType() can accept a field object as the first parameter.
<p>New $arr = $db-&gt;ServerInfo( ) function. Returns $arr['description'] which
is the string description, and $arr['version'].
<p>PostgreSQL and MSSQL speedups for insert/updates.
<p> Implemented new SetFetchMode() that removes the need to use $ADODB_FETCH_MODE.
Each connection has independant fetchMode.
<p>ADODB_ASSOC_CASE now defaults to 2, use native defaults. This is because we
would break backward compat for too many applications otherwise.
<p>Patched encrypted sessions to use replace()
<p>The qstr function supports quoting of nulls when escape character is \
<p>Rewrote bits and pieces of session code to check for time synch and improve
reliability.
<p>Added property ADOConnection::hasTransactions = true/false;
<p>Added CreateSequence and DropSequence functions
<p>Found misplaced MoveNext() in adodb-postgres.inc.php. Fixed.
<p>Sybase SelectLimit not reliable because 'set rowcount' not cached - fixed.
<p>Moved ADOConnection to adodb-connection.inc.php and ADORecordSet to adodb-recordset.inc.php.
This allows us to use doxygen to generate documentation. Doxygen doesn't like
the classes in the main adodb.inc.php file for some mysterious reason.
<p><b>2.50, 14 Nov 2002</b>
<p>Added transOff and transCnt properties for disabling (transOff = true) and
tracking transaction status (transCnt>0).
<p>Added inputarray handling into _adodb_pageexecute_all_rows - "Ross Smith" RossSmith#bnw.com.
<p>Fixed postgresql inconsistencies in date handling.
<p>Added support for mssql_fetch_assoc.
<p>Fixed $ADODB_FETCH_MODE bug in odbc MetaTables() and MetaPrimaryKeys().
<p>Accidentally declared UnixDate() twice, making adodb incompatible with php
4.3.0. Fixed.
<p>Fixed pager problems with some databases that returned -1 for _currentRow on
MoveLast() by switching to MoveNext() in adodb-lib.inc.php.
<p>Also fixed uninited $discard in adodb-lib.inc.php.
<p><b>2.43, 25 Oct 2002</b></p>
Added ADODB_ASSOC_CASE constant to better support ibase and odbc field names.
<p>Added support for NConnect() for oracle OCINLogin.
<p>Fixed NumCols() bug.
<p>Changed session handler to use Replace() on write.
<p>Fixed oci8 SelectLimit aggregate function bug again.
<p>Rewrote pivoting code.
<p><b>2.42, 4 Oct 2002</b></p>
<p>Fixed ibase_fetch() problem with nulls. Also interbase now does automatic blob
decoding, and is backward compatible. Suggested by Heinz Hombergs heinz#hhombergs.de.
<p>Fixed postgresql MoveNext() problems when called repeatedly after EOF. Also
suggested by Heinz Hombergs.
<p>PageExecute() does not rewrite queries if SELECT DISTINCT is used. Requested
by hans#velum.net
<p>Added additional fixes to oci8 SelectLimit handling with aggregate functions
- thx to Christian Bugge for reporting the problem.
<p><b>2.41, 2 Oct 2002</b></p>
<p>Fixed ADODB_COUNTRECS bug in odbc. Thx to Joshua Zoshi jzoshi#hotmail.com.
<p>Increased buffers for adodb-csvlib.inc.php for extremely long sql from 8192
to 32000.
<p>Revised pivottable.inc.php code. Added better support for aggregate fields.
<p>Fixed mysql text/blob types problem in MetaTypes base class - thx to horacio
degiorgi.
<p>Added SQLDate($fmt,$date) function, which allows an sql date format string
to be generated - useful for group by's.
<p>Fixed bug in oci8 SelectLimit when offset>100.
<p><b>2.40 4 Sept 2002</b></p>
<p>Added new NLS_DATE_FORMAT property to oci8. Suggested by Laurent NAVARRO ln#altidev.com
<p>Now use bind parameters in oci8 selectlimit for better performance.
<p>Fixed interbase replaceQuote for dialect != 1. Thx to "BEGUIN Pierre-Henri
- INFOCOB" phb#infocob.com.
<p>Added white-space check to QA.
<p>Changed unixtimestamp to support fractional seconds (we always round down/floor
the seconds). Thanks to beezly#beezly.org.uk.
<p>Now you can set the trigger_error type your own user-defined type in adodb-errorhandler.inc.php.
Suggested by Claudio Bustos clbustos#entelchile.net.
<p>Added recordset filters with rsfilter.inc.php.
<p>$conn->_rs2rs does not create a new recordset when it detects it is of type
array. Some trickery there as there seems to be a bug in Zend Engine
<p>Added render_pagelinks to adodb-pager.inc.php. Code by "Pablo Costa" pablo#cbsp.com.br.
<p>MetaType() speedup in adodb.inc.php by using hashing instead of switch. Best
performance if constant arrays are supported, as they are in PHP5.
<p>adodb-session.php now updates only the expiry date if the crc32 check indicates
that the data has not been modified.
<p><b>2.31 20 Aug 2002</b></p>
<p>Made changes to pivottable.inc.php due to daniel lucuzaeu's suggestions (we sum the pivottable column if desired).
<p>Fixed ErrorNo() in postgres so it does not depend on _errorMsg property.

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -59,9 +59,19 @@ class perf_db2 extends adodb_perf{
$this->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();

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -71,8 +71,21 @@ class perf_mssql extends adodb_perf{
$this->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 = '<p><b>Explain</b>: '.htmlspecialchars($sql).'</p>';
$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;
}

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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,13 +83,32 @@ class perf_mysql extends adodb_perf{
$this->conn =& $conn;
}
function Explain($sql)
function Explain($sql,$partial=false)
{
if (strtoupper(substr(trim($sql),0,6)) !== 'SELECT') return '<p>Unable to EXPLAIN non-select statement</p>';
$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 = '<p><b>Explain</b>: '.htmlspecialchars($sql).'</p>';
$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,10 @@ 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];
$rs->Close();
$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)) {

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -48,6 +48,15 @@ class perf_oci8 extends ADODB_perf{
from v\$rowcache",
'increase <i>shared_pool_size</i> 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',
"select value from v\$sysstat where name='physical reads'"),
@ -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 = "<p><b>Explain</b>: ".htmlspecialchars($sql)."</p>";
$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 = "<h3>Data Cache Estimate</h3>";
if ($rs->EOF) {
$s .= "<p>Cache that is 50% of current size is still too big</p>";
} 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 "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'])."\n";
$partial = empty($HTTP_GET_VARS['part']);
echo "<a name=explain></a>".$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 "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'])."\n";
$partial = empty($HTTP_GET_VARS['part']);
echo "<a name=explain></a>".$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);

View File

@ -1,7 +1,7 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -88,10 +88,21 @@ class perf_postgres extends adodb_perf{
$this->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 = '<p><b>Explain</b>: '.htmlspecialchars($sql).'</p>';
$rs = $this->conn->Execute('EXPLAIN '.$sql);
$this->conn->LogSQL($save);
@ -102,7 +113,7 @@ class perf_postgres extends adodb_perf{
$rs->MoveNext();
}
$s .= '</pre>';
$s .= $this->Tracer($sql);
$s .= $this->Tracer($sql,$partial);
return $s;
}
}

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.
@ -71,7 +71,8 @@
if ($showcount)
$sel .= "\n\tSUM(1) as Total";
else
$sel = substr($sel,0,strlen($sel)-2);
$sql = "SELECT $sel \nFROM $tables $where \nGROUP BY $rowfields";
return $sql;

View File

@ -1,6 +1,6 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.

View File

@ -1,7 +1,7 @@
<?php
/**
* @version V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
* @version V4.20 22 Feb 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.

View File

@ -0,0 +1,120 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
if (!function_exists('bzcompress')) {
trigger_error('bzip2 functions are not available', E_USER_ERROR);
return 0;
}
/*
*/
class ADODB_Compress_Bzip2 {
/**
*/
var $_block_size = null;
/**
*/
var $_work_level = null;
/**
*/
var $_min_length = 1;
/**
*/
function getBlockSize() {
return $this->_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;
?>

View File

@ -0,0 +1,94 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
if (!function_exists('gzcompress')) {
trigger_error('gzip functions are not available', E_USER_ERROR);
return 0;
}
/*
*/
class ADODB_Compress_Gzip {
/**
*/
var $_level = null;
/**
*/
var $_min_length = 1;
/**
*/
function getLevel() {
return $this->_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;
?>

View File

@ -0,0 +1,25 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
/*
This file is provided for backwards compatibility purposes
*/
require_once dirname(__FILE__) . '/adodb-session.php';
require_once ADODB_SESSION . '/adodb-encrypt-md5.php';
ADODB_Session::filter(new ADODB_Encrypt_MD5());
?>

View File

@ -0,0 +1,110 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
if (!function_exists('mcrypt_encrypt')) {
trigger_error('Mcrypt functions are not available', E_USER_ERROR);
return 0;
}
/**
*/
class ADODB_Encrypt_MCrypt {
/**
*/
var $_cipher;
/**
*/
var $_mode;
/**
*/
var $_source;
/**
*/
function getCipher() {
return $this->_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;
?>

View File

@ -0,0 +1,38 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
include_once ADODB_SESSION . '/crypt.inc.php';
/**
*/
class ADODB_Encrypt_MD5 {
/**
*/
function write($data, $key) {
$md5crypt =& new MD5Crypt();
return $md5crypt->encrypt($data, $key);
}
/**
*/
function read($data, $key) {
$md5crypt =& new MD5Crypt();
return $md5crypt->decrypt($data, $key);
}
}
return 1;
?>

View File

@ -0,0 +1,50 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
@define('HORDE_BASE', dirname(dirname(dirname(__FILE__))) . '/horde');
if (!is_dir(HORDE_BASE)) {
trigger_error(sprintf('Directory not found: \'%s\'', HORDE_BASE), E_USER_ERROR);
return 0;
}
include_once HORDE_BASE . '/lib/Horde.php';
include_once HORDE_BASE . '/lib/Secret.php';
/**
NOTE: On Windows 2000 SP4 with PHP 4.3.1, MCrypt 2.4.x, and Apache 1.3.28,
the session didn't work properly.
This may be resolved with 4.3.3.
*/
class ADODB_Encrypt_Secret {
/**
*/
function write($data, $key) {
return Secret::write($key, $data);
}
/**
*/
function read($data, $key) {
return Secret::read($key, $data);
}
}
return 1;
?>

View File

@ -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

View File

@ -0,0 +1,24 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
/*
This file is provided for backwards compatibility purposes
*/
require_once dirname(__FILE__) . '/adodb-session.php';
ADODB_Session::clob('CLOB');
?>

View File

@ -0,0 +1,817 @@
<?php
// $CVSHeader$
/*
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Set tabs to 4 for best viewing.
*/
/*
You may want to rename the 'data' field to 'session_data' as
'data' appears to be a reserved word for one or more of the following:
ANSI SQL
IBM DB2
MS SQL Server
Postgres
SAP
If you do, then execute:
ADODB_Session::dataFieldName('session_data');
*/
if (!defined('_ADODB_LAYER')) {
require_once realpath(dirname(__FILE__) . '/../adodb.inc.php');
}
if (defined('ADODB_SESSION')) return 1;
define('ADODB_SESSION', dirname(__FILE__));
/*!
\static
*/
class ADODB_Session {
/////////////////////
// getter/setter methods
/////////////////////
/*!
*/
function driver($driver = null) {
static $_driver = 'mysql';
static $set = false;
if (!is_null($driver)) {
$_driver = trim($driver);
$set = true;
} elseif (!$set) {
// backwards compatibility
if (isset($GLOBALS['ADODB_SESSION_DRIVER'])) {
return $GLOBALS['ADODB_SESSION_DRIVER'];
}
}
return $_driver;
}
/*!
*/
function host($host = null) {
static $_host = 'localhost';
static $set = false;
if (!is_null($host)) {
$_host = trim($host);
$set = true;
} elseif (!$set) {
// backwards compatibility
if (isset($GLOBALS['ADODB_SESSION_CONNECT'])) {
return $GLOBALS['ADODB_SESSION_CONNECT'];
}
}
return $_host;
}
/*!
*/
function user($user = null) {
static $_user = 'root';
static $set = false;
if (!is_null($user)) {
$_user = trim($user);
$set = true;
} elseif (!$set) {
// backwards compatibility
if (isset($GLOBALS['ADODB_SESSION_USER'])) {
return $GLOBALS['ADODB_SESSION_USER'];
}
}
return $_user;
}
/*!
*/
function password($password = null) {
static $_password = '';
static $set = false;
if (!is_null($password)) {
$_password = $password;
$set = true;
} elseif (!$set) {
// backwards compatibility
if (isset($GLOBALS['ADODB_SESSION_PWD'])) {
return $GLOBALS['ADODB_SESSION_PWD'];
}
}
return $_password;
}
/*!
*/
function database($database = null) {
static $_database = 'xphplens_2';
static $set = false;
if (!is_null($database)) {
$_database = trim($database);
$set = true;
} elseif (!$set) {
// backwards compatibility
if (isset($GLOBALS['ADODB_SESSION_DB'])) {
return $GLOBALS['ADODB_SESSION_DB'];
}
}
return $_database;
}
/*!
*/
function persist($persist = null) {
static $_persist = true;
if (!is_null($persist)) {
$_persist = trim($persist);
}
return $_persist;
}
/*!
*/
function lifetime($lifetime = null) {
static $_lifetime;
static $set = false;
if (!is_null($lifetime)) {
$_lifetime = (int) $lifetime;
$set = true;
} elseif (!$set) {
// backwards compatibility
if (isset($GLOBALS['ADODB_SESS_LIFE'])) {
return $GLOBALS['ADODB_SESS_LIFE'];
}
}
if (!$_lifetime) {
$_lifetime = ini_get('session.gc_maxlifetime');
if ($_lifetime <= 1) {
// bug in PHP 4.0.3 pl 1 -- how about other versions?
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $lifetime</h3>";
$_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 "<br />\$rs is null or false<br />\n";
return;
}
//echo "<br />\nAffected_Rows=",$conn->Affected_Rows(),"<br />\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('<p>Session: connection failed</p>', 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 '<p>Session: Only updating date - crc32 not changed</p>';
}
$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('<p>Session Replace: ' . $conn->ErrorMsg() . '</p>', 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("<p><b>Garbage Collection</b>: $sql</p>");
}
}
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
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("<p>$msg</p>");
}
}
}
}
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);
}
?>

View File

@ -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)
);

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -80,7 +80,8 @@ GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESS_LIFE,
$ADODB_SESS_DEBUG,
$ADODB_SESS_INSERT,
$ADODB_SESSION_EXPIRE_NOTIFY;
$ADODB_SESSION_EXPIRE_NOTIFY,
$ADODB_SESSION_TBL;
//$ADODB_SESS_DEBUG = true;
@ -237,7 +238,8 @@ function adodb_sess_gc($maxlifetime) {
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
$t = time();
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
@ -245,9 +247,12 @@ function adodb_sess_gc($maxlifetime) {
$ref = $rs->fields[0];
$key = $rs->fields[1];
$fn($ref,$key);
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
//$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$rs->Close();
$ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < $t");
$ADODB_SESS_CONN->CommitTrans();
}
} else {

View File

@ -1,6 +1,6 @@
<?php
/*
V3.92 2 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -110,7 +110,8 @@ GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESS_DEBUG,
$ADODB_SESSION_EXPIRE_NOTIFY,
$ADODB_SESSION_CRC,
$ADODB_SESSION_USE_LOBS;
$ADODB_SESSION_USE_LOBS,
$ADODB_SESSION_TBL;
if (!isset($ADODB_SESSION_USE_LOBS)) $ADODB_SESSION_USE_LOBS = 'CLOB';
@ -356,7 +357,8 @@ function adodb_sess_gc($maxlifetime)
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
$t = time();
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
@ -367,11 +369,14 @@ function adodb_sess_gc($maxlifetime)
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$rs->Close();
//$ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < $t");
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time();
$ADODB_SESS_CONN->Execute($qry);
$ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p><b>Garbage Collection</b>: $qry</p>");
}

View File

@ -1,6 +1,6 @@
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.
@ -119,7 +119,8 @@ GLOBAL $ADODB_SESSION_CONNECT,
$ADODB_SESS_LIFE,
$ADODB_SESS_DEBUG,
$ADODB_SESSION_EXPIRE_NOTIFY,
$ADODB_SESSION_CRC;
$ADODB_SESSION_CRC,
$ADODB_SESSION_TBL;
$ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
@ -314,7 +315,8 @@ function adodb_sess_gc($maxlifetime)
reset($ADODB_SESSION_EXPIRE_NOTIFY);
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$rs =& $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
$t = time();
$rs =& $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
@ -325,7 +327,10 @@ function adodb_sess_gc($maxlifetime)
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
$rs->MoveNext();
}
$rs->Close();
$ADODB_SESS_CONN->CommitTrans();
}
} else {
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time();

View File

@ -0,0 +1,64 @@
<?php
// Session Encryption by Ari Kuorikoski <ari.kuorikoski@finebyte.com>
class MD5Crypt{
function keyED($txt,$encrypt_key)
{
$encrypt_key = md5($encrypt_key);
$ctr=0;
$tmp = "";
for ($i=0;$i<strlen($txt);$i++){
if ($ctr==strlen($encrypt_key)) $ctr=0;
$tmp.= substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1);
$ctr++;
}
return $tmp;
}
function Encrypt($txt,$key)
{
srand((double)microtime()*1000000);
$encrypt_key = md5(rand(0,32000));
$ctr=0;
$tmp = "";
for ($i=0;$i<strlen($txt);$i++)
{
if ($ctr==strlen($encrypt_key)) $ctr=0;
$tmp.= substr($encrypt_key,$ctr,1) .
(substr($txt,$i,1) ^ substr($encrypt_key,$ctr,1));
$ctr++;
}
return base64_encode($this->keyED($tmp,$key));
}
function Decrypt($txt,$key)
{
$txt = $this->keyED(base64_decode($txt),$key);
$tmp = "";
for ($i=0;$i<strlen($txt);$i++){
$md5 = substr($txt,$i,1);
$i++;
$tmp.= (substr($txt,$i,1) ^ $md5);
}
return $tmp;
}
function RandPass()
{
$randomPassword = "";
srand((double)microtime()*1000000);
for($i=0;$i<8;$i++)
{
$randnumber = rand(48,120);
while (($randnumber >= 58 && $randnumber <= 64) || ($randnumber >= 91 && $randnumber <= 96))
{
$randnumber = rand(48,120);
}
$randomPassword .= chr($randnumber);
}
return $randomPassword;
}
}
?>

View File

@ -8,7 +8,7 @@
<body>
<?php
/*
V3.94 13 Oct 2003 (c) 2000-2003 John Lim (jlim@natsoft.com.my). All rights reserved.
V4.20 22 Feb 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.

View File

@ -2,7 +2,7 @@
<body bgcolor=white>
<?php
/**
* V3.94 13 Oct 2003 (c) 2001-2002 John Lim (jlim@natsoft.com.my). All rights reserved.
* V4.20 22 Feb 2004 (c) 2001-2002 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.

Some files were not shown because too many files have changed in this diff Show More