adodb5/adodb-active-record.inc.php 100666 0 0 40721 10750035616 12356 _dbat
$_ADODB_ACTIVE_DBS = array();
$ACTIVE_RECORD_SAFETY = true;
$ADODB_ACTIVE_DEFVALS = false;
class ADODB_Active_DB {
var $db; // ADOConnection
var $tables; // assoc array of ADODB_Active_Table objects, indexed by tablename
}
class ADODB_Active_Table {
var $name; // table name
var $flds; // assoc array of adofieldobjs, indexed by fieldname
var $keys; // assoc array of primary keys, indexed by fieldname
var $_created; // only used when stored as a cached file
}
// returns index into $_ADODB_ACTIVE_DBS
function ADODB_SetDatabaseAdapter(&$db)
{
global $_ADODB_ACTIVE_DBS;
foreach($_ADODB_ACTIVE_DBS as $k => $d) {
if (PHP_VERSION >= 5) {
if ($d->db === $db) return $k;
} else {
if ($d->db->_connectionID === $db->_connectionID && $db->database == $d->db->database)
return $k;
}
}
$obj = new ADODB_Active_DB();
$obj->db = $db;
$obj->tables = array();
$_ADODB_ACTIVE_DBS[] = $obj;
return sizeof($_ADODB_ACTIVE_DBS)-1;
}
class ADODB_Active_Record {
var $_dbat; // associative index pointing to ADODB_Active_DB eg. $ADODB_Active_DBS[_dbat]
var $_table; // tablename, if set in class definition then use it as table name
var $_tableat; // associative index pointing to ADODB_Active_Table, eg $ADODB_Active_DBS[_dbat]->tables[$this->_tableat]
var $_where; // where clause set in Load()
var $_saved = false; // indicates whether data is already inserted.
var $_lasterr = false; // last error message
var $_original = false; // the original values loaded or inserted, refreshed on update
static function UseDefaultValues($bool=null)
{
global $ADODB_ACTIVE_DEFVALS;
if (isset($bool)) $ADODB_ACTIVE_DEFVALS = $bool;
return $ADODB_ACTIVE_DEFVALS;
}
// should be static
static function SetDatabaseAdapter(&$db)
{
return ADODB_SetDatabaseAdapter($db);
}
public function __set($name, $value)
{
$name = str_replace(' ', '_', $name);
$this->$name = $value;
}
// php5 constructor
function __construct($table = false, $pkeyarr=false, $db=false)
{
global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS;
if ($db == false && is_object($pkeyarr)) {
$db = $pkeyarr;
$pkeyarr = false;
}
if (!$table) {
if (!empty($this->_table)) $table = $this->_table;
else $table = $this->_pluralize(get_class($this));
}
if ($db) {
$this->_dbat = ADODB_Active_Record::SetDatabaseAdapter($db);
} else
$this->_dbat = sizeof($_ADODB_ACTIVE_DBS)-1;
if ($this->_dbat < 0) $this->Error("No database connection set; use ADOdb_Active_Record::SetDatabaseAdapter(\$db)",'ADODB_Active_Record::__constructor');
$this->_table = $table;
$this->_tableat = $table; # reserved for setting the assoc value to a non-table name, eg. the sql string in future
$this->UpdateActiveTable($pkeyarr);
}
function __wakeup()
{
$class = get_class($this);
new $class;
}
function _pluralize($table)
{
$ut = strtoupper($table);
$len = strlen($table);
$lastc = $ut[$len-1];
$lastc2 = substr($ut,$len-2);
switch ($lastc) {
case 'S':
return $table.'es';
case 'Y':
return substr($table,0,$len-1).'ies';
case 'X':
return $table.'es';
case 'H':
if ($lastc2 == 'CH' || $lastc2 == 'SH')
return $table.'es';
default:
return $table.'s';
}
}
//////////////////////////////////
// update metadata
function UpdateActiveTable($pkeys=false,$forceUpdate=false)
{
global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS , $ADODB_CACHE_DIR, $ADODB_ACTIVE_CACHESECS;
global $ADODB_ACTIVE_DEFVALS;
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$table = $this->_table;
$tables = $activedb->tables;
$tableat = $this->_tableat;
if (!$forceUpdate && !empty($tables[$tableat])) {
$tobj = $tables[$tableat];
foreach($tobj->flds as $name => $fld) {
if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value))
$this->$name = $fld->default_value;
else
$this->$name = null;
}
return;
}
$db = $activedb->db;
$fname = $ADODB_CACHE_DIR . '/adodb_' . $db->databaseType . '_active_'. $table . '.cache';
if (!$forceUpdate && $ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR && file_exists($fname)) {
$fp = fopen($fname,'r');
@flock($fp, LOCK_SH);
$acttab = unserialize(fread($fp,100000));
fclose($fp);
if ($acttab->_created + $ADODB_ACTIVE_CACHESECS - (abs(rand()) % 16) > time()) {
// abs(rand()) randomizes deletion, reducing contention to delete/refresh file
// ideally, you should cache at least 32 secs
$activedb->tables[$table] = $acttab;
//if ($db->debug) ADOConnection::outp("Reading cached active record file: $fname");
return;
} else if ($db->debug) {
ADOConnection::outp("Refreshing cached active record file: $fname");
}
}
$activetab = new ADODB_Active_Table();
$activetab->name = $table;
$cols = $db->MetaColumns($table);
if (!$cols) {
$this->Error("Invalid table name: $table",'UpdateActiveTable');
return false;
}
$fld = reset($cols);
if (!$pkeys) {
if (isset($fld->primary_key)) {
$pkeys = array();
foreach($cols as $name => $fld) {
if (!empty($fld->primary_key)) $pkeys[] = $name;
}
} else
$pkeys = $this->GetPrimaryKeys($db, $table);
}
if (empty($pkeys)) {
$this->Error("No primary key found for table $table",'UpdateActiveTable');
return false;
}
$attr = array();
$keys = array();
switch($ADODB_ASSOC_CASE) {
case 0:
foreach($cols as $name => $fldobj) {
$name = strtolower($name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value))
$this->$name = $fldobj->default_value;
else
$this->$name = null;
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[strtolower($name)] = strtolower($name);
}
break;
case 1:
foreach($cols as $name => $fldobj) {
$name = strtoupper($name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value))
$this->$name = $fldobj->default_value;
else
$this->$name = null;
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[strtoupper($name)] = strtoupper($name);
}
break;
default:
foreach($cols as $name => $fldobj) {
$name = ($fldobj->name);
if ($ADODB_ACTIVE_DEFVALS && isset($fldobj->default_value))
$this->$name = $fldobj->default_value;
else
$this->$name = null;
$attr[$name] = $fldobj;
}
foreach($pkeys as $k => $name) {
$keys[$name] = $cols[$name]->name;
}
break;
}
$activetab->keys = $keys;
$activetab->flds = $attr;
if ($ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR) {
$activetab->_created = time();
$s = serialize($activetab);
if (!function_exists('adodb_write_file')) include(ADODB_DIR.'/adodb-csvlib.inc.php');
adodb_write_file($fname,$s);
}
$activedb->tables[$table] = $activetab;
}
function GetPrimaryKeys(&$db, $table)
{
return $db->MetaPrimaryKeys($table);
}
// error handler for both PHP4+5.
function Error($err,$fn)
{
global $_ADODB_ACTIVE_DBS;
$fn = get_class($this).'::'.$fn;
$this->_lasterr = $fn.': '.$err;
if ($this->_dbat < 0) $db = false;
else {
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$db = $activedb->db;
}
if (function_exists('adodb_throw')) {
if (!$db) adodb_throw('ADOdb_Active_Record', $fn, -1, $err, 0, 0, false);
else adodb_throw($db->databaseType, $fn, -1, $err, 0, 0, $db);
} else
if (!$db || $db->debug) ADOConnection::outp($this->_lasterr);
}
// return last error message
function ErrorMsg()
{
if (!function_exists('adodb_throw')) {
if ($this->_dbat < 0) $db = false;
else $db = $this->DB();
// last error could be database error too
if ($db && $db->ErrorMsg()) return $db->ErrorMsg();
}
return $this->_lasterr;
}
function ErrorNo()
{
if ($this->_dbat < 0) return -9999; // no database connection...
$db = $this->DB();
return (int) $db->ErrorNo();
}
// retrieve ADOConnection from _ADODB_Active_DBs
function DB()
{
global $_ADODB_ACTIVE_DBS;
if ($this->_dbat < 0) {
$false = false;
$this->Error("No database connection set: use ADOdb_Active_Record::SetDatabaseAdaptor(\$db)", "DB");
return $false;
}
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$db = $activedb->db;
return $db;
}
// retrieve ADODB_Active_Table
function TableInfo()
{
global $_ADODB_ACTIVE_DBS;
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$table = $activedb->tables[$this->_tableat];
return $table;
}
// set a numeric array (using natural table field ordering) as object properties
function Set(&$row)
{
global $ACTIVE_RECORD_SAFETY;
$db = $this->DB();
if (!$row) {
$this->_saved = false;
return false;
}
$this->_saved = true;
$table = $this->TableInfo();
if ($ACTIVE_RECORD_SAFETY && sizeof($table->flds) != sizeof($row)) {
#
$bad_size = TRUE;
if (sizeof($row) == 2 * sizeof($table->flds)) {
// Only keep string keys
$keys = array_filter(array_keys($row), 'is_string');
if (sizeof($keys) == sizeof($table->flds))
$bad_size = FALSE;
}
if ($bad_size) {
$this->Error("Table structure of $this->_table has changed","Load");
return false;
}
#
}
else
$keys = array_keys($row);
#
reset($keys);
$this->_original = array();
foreach($table->flds as $name=>$fld) {
$value = $row[current($keys)];
$this->$name = $value;
$this->_original[] = $value;
next($keys);
}
#
return true;
}
// get last inserted id for INSERT
function LastInsertID(&$db,$fieldname)
{
if ($db->hasInsertID)
$val = $db->Insert_ID($this->_table,$fieldname);
else
$val = false;
if (is_null($val) || $val === false) {
// this might not work reliably in multi-user environment
return $db->GetOne("select max(".$fieldname.") from ".$this->_table);
}
return $val;
}
// quote data in where clause
function doquote(&$db, $val,$t)
{
switch($t) {
case 'D':
case 'T':
if (empty($val)) return 'null';
case 'C':
case 'X':
if (is_null($val)) return 'null';
if (strncmp($val,"'",1) != 0 && substr($val,strlen($val)-1,1) != "'") {
return $db->qstr($val);
break;
}
default:
return $val;
break;
}
}
// generate where clause for an UPDATE/SELECT
function GenWhere(&$db, &$table)
{
$keys = $table->keys;
$parr = array();
foreach($keys as $k) {
$f = $table->flds[$k];
if ($f) {
$parr[] = $k.' = '.$this->doquote($db,$this->$k,$db->MetaType($f->type));
}
}
return implode(' and ', $parr);
}
//------------------------------------------------------------ Public functions below
function Load($where,$bindarr=false)
{
$db = $this->DB(); if (!$db) return false;
$this->_where = $where;
$save = $db->SetFetchMode(ADODB_FETCH_NUM);
$row = $db->GetRow("select * from ".$this->_table.' WHERE '.$where,$bindarr);
$db->SetFetchMode($save);
return $this->Set($row);
}
// false on error
function Save()
{
if ($this->_saved) $ok = $this->Update();
else $ok = $this->Insert();
return $ok;
}
// false on error
function Insert()
{
$db = $this->DB(); if (!$db) return false;
$cnt = 0;
$table = $this->TableInfo();
$valarr = array();
$names = array();
$valstr = array();
foreach($table->flds as $name=>$fld) {
$val = $this->$name;
if(!is_null($val) || !array_key_exists($name, $table->keys)) {
$valarr[] = $val;
$names[] = $name;
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
}
if (empty($names)){
foreach($table->flds as $name=>$fld) {
$valarr[] = null;
$names[] = $name;
$valstr[] = $db->Param($cnt);
$cnt += 1;
}
}
$sql = 'INSERT INTO '.$this->_table."(".implode(',',$names).') VALUES ('.implode(',',$valstr).')';
$ok = $db->Execute($sql,$valarr);
if ($ok) {
$this->_saved = true;
$autoinc = false;
foreach($table->keys as $k) {
if (is_null($this->$k)) {
$autoinc = true;
break;
}
}
if ($autoinc && sizeof($table->keys) == 1) {
$k = reset($table->keys);
$this->$k = $this->LastInsertID($db,$k);
}
}
$this->_original = $valarr;
return !empty($ok);
}
function Delete()
{
$db = $this->DB(); if (!$db) return false;
$table = $this->TableInfo();
$where = $this->GenWhere($db,$table);
$sql = 'DELETE FROM '.$this->_table.' WHERE '.$where;
$ok = $db->Execute($sql);
return $ok ? true : false;
}
// returns an array of active record objects
function Find($whereOrderBy,$bindarr=false,$pkeysArr=false)
{
$db = $this->DB(); if (!$db || empty($this->_table)) return false;
$arr = $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr);
return $arr;
}
// returns 0 on error, 1 on update, 2 on insert
function Replace()
{
global $ADODB_ASSOC_CASE;
$db = $this->DB(); if (!$db) return false;
$table = $this->TableInfo();
$pkey = $table->keys;
foreach($table->flds as $name=>$fld) {
$val = $this->$name;
/*
if (is_null($val)) {
if (isset($fld->not_null) && $fld->not_null) {
if (isset($fld->default_value) && strlen($fld->default_value)) continue;
else {
$this->Error("Cannot update null into $name","Replace");
return false;
}
}
}*/
if (is_null($val) && !empty($fld->auto_increment)) {
continue;
}
$t = $db->MetaType($fld->type);
$arr[$name] = $this->doquote($db,$val,$t);
$valarr[] = $val;
}
if (!is_array($pkey)) $pkey = array($pkey);
if ($ADODB_ASSOC_CASE == 0)
foreach($pkey as $k => $v)
$pkey[$k] = strtolower($v);
elseif ($ADODB_ASSOC_CASE == 1)
foreach($pkey as $k => $v)
$pkey[$k] = strtoupper($v);
$ok = $db->Replace($this->_table,$arr,$pkey);
if ($ok) {
$this->_saved = true; // 1= update 2=insert
if ($ok == 2) {
$autoinc = false;
foreach($table->keys as $k) {
if (is_null($this->$k)) {
$autoinc = true;
break;
}
}
if ($autoinc && sizeof($table->keys) == 1) {
$k = reset($table->keys);
$this->$k = $this->LastInsertID($db,$k);
}
}
$this->_original = $valarr;
}
return $ok;
}
// returns 0 on error, 1 on update, -1 if no change in data (no update)
function Update()
{
$db = $this->DB(); if (!$db) return false;
$table = $this->TableInfo();
$where = $this->GenWhere($db, $table);
if (!$where) {
$this->error("Where missing for table $table", "Update");
return false;
}
$valarr = array();
$neworig = array();
$pairs = array();
$i = -1;
$cnt = 0;
foreach($table->flds as $name=>$fld) {
$i += 1;
$val = $this->$name;
$neworig[] = $val;
if (isset($table->keys[$name])) {
continue;
}
if (is_null($val)) {
if (isset($fld->not_null) && $fld->not_null) {
if (isset($fld->default_value) && strlen($fld->default_value)) continue;
else {
$this->Error("Cannot set field $name to NULL","Update");
return false;
}
}
}
if (isset($this->_original[$i]) && $val == $this->_original[$i]) {
continue;
}
$valarr[] = $val;
$pairs[] = $name.'='.$db->Param($cnt);
$cnt += 1;
}
if (!$cnt) return -1;
$sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where;
$ok = $db->Execute($sql,$valarr);
if ($ok) {
$this->_original = $neworig;
return 1;
}
return 0;
}
function GetAttributeNames()
{
$table = $this->TableInfo();
if (!$table) return false;
return array_keys($table->flds);
}
};
?> adodb5/adodb-csvlib.inc.php 100666 0 0 20373 10750035616 11112 FieldCount() : 0;
if ($sql) $sql = urlencode($sql);
// metadata setup
if ($max <= 0 || $rs->dataProvider == 'empty') { // is insert/update/delete
if (is_object($conn)) {
$sql .= ','.$conn->Affected_Rows();
$sql .= ','.$conn->Insert_ID();
} else
$sql .= ',,';
$text = "====-1,0,$sql\n";
return $text;
}
$tt = ($rs->timeCreated) ? $rs->timeCreated : time();
## changed format from ====0 to ====1
$line = "====1,$tt,$sql\n";
if ($rs->databaseType == 'array') {
$rows = $rs->_array;
} else {
$rows = array();
while (!$rs->EOF) {
$rows[] = $rs->fields;
$rs->MoveNext();
}
}
for($i=0; $i < $max; $i++) {
$o = $rs->FetchField($i);
$flds[] = $o;
}
$savefetch = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode;
$class = $rs->connection->arrayClass;
$rs2 = new $class();
$rs2->sql = $rs->sql;
$rs2->oldProvider = $rs->dataProvider;
$rs2->InitArrayFields($rows,$flds);
$rs2->fetchMode = $savefetch;
return $line.serialize($rs2);
}
/**
* Open CSV file and convert it into Data.
*
* @param url file/ftp/http url
* @param err returns the error message
* @param timeout dispose if recordset has been alive for $timeout secs
*
* @return recordset, or false if error occured. If no
* error occurred in sql INSERT/UPDATE/DELETE,
* empty recordset is returned
*/
function csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
{
$false = false;
$err = false;
$fp = @fopen($url,'rb');
if (!$fp) {
$err = $url.' file/URL not found';
return $false;
}
@flock($fp, LOCK_SH);
$arr = array();
$ttl = 0;
if ($meta = fgetcsv($fp, 32000, ",")) {
// check if error message
if (strncmp($meta[0],'****',4) === 0) {
$err = trim(substr($meta[0],4,1024));
fclose($fp);
return $false;
}
// check for meta data
// $meta[0] is -1 means return an empty recordset
// $meta[1] contains a time
if (strncmp($meta[0], '====',4) === 0) {
if ($meta[0] == "====-1") {
if (sizeof($meta) < 5) {
$err = "Corrupt first line for format -1";
fclose($fp);
return $false;
}
fclose($fp);
if ($timeout > 0) {
$err = " Illegal Timeout $timeout ";
return $false;
}
$rs = new $rsclass($val=true);
$rs->fields = array();
$rs->timeCreated = $meta[1];
$rs->EOF = true;
$rs->_numOfFields = 0;
$rs->sql = urldecode($meta[2]);
$rs->affectedrows = (integer)$meta[3];
$rs->insertid = $meta[4];
return $rs;
}
# Under high volume loads, we want only 1 thread/process to _write_file
# so that we don't have 50 processes queueing to write the same data.
# We use probabilistic timeout, ahead of time.
#
# -4 sec before timeout, give processes 1/32 chance of timing out
# -2 sec before timeout, give processes 1/16 chance of timing out
# -1 sec after timeout give processes 1/4 chance of timing out
# +0 sec after timeout, give processes 100% chance of timing out
if (sizeof($meta) > 1) {
if($timeout >0){
$tdiff = (integer)( $meta[1]+$timeout - time());
if ($tdiff <= 2) {
switch($tdiff) {
case 4:
case 3:
if ((rand() & 31) == 0) {
fclose($fp);
$err = "Timeout 3";
return $false;
}
break;
case 2:
if ((rand() & 15) == 0) {
fclose($fp);
$err = "Timeout 2";
return $false;
}
break;
case 1:
if ((rand() & 3) == 0) {
fclose($fp);
$err = "Timeout 1";
return $false;
}
break;
default:
fclose($fp);
$err = "Timeout 0";
return $false;
} // switch
} // if check flush cache
}// (timeout>0)
$ttl = $meta[1];
}
//================================================
// new cache format - use serialize extensively...
if ($meta[0] === '====1') {
// slurp in the data
$MAXSIZE = 128000;
$text = fread($fp,$MAXSIZE);
if (strlen($text)) {
while ($txt = fread($fp,$MAXSIZE)) {
$text .= $txt;
}
}
fclose($fp);
$rs = unserialize($text);
if (is_object($rs)) $rs->timeCreated = $ttl;
else {
$err = "Unable to unserialize recordset";
//echo htmlspecialchars($text),' !--END--!
';
}
return $rs;
}
$meta = false;
$meta = fgetcsv($fp, 32000, ",");
if (!$meta) {
fclose($fp);
$err = "Unexpected EOF 1";
return $false;
}
}
// Get Column definitions
$flds = array();
foreach($meta as $o) {
$o2 = explode(':',$o);
if (sizeof($o2)!=3) {
$arr[] = $meta;
$flds = false;
break;
}
$fld = new ADOFieldObject();
$fld->name = urldecode($o2[0]);
$fld->type = $o2[1];
$fld->max_length = $o2[2];
$flds[] = $fld;
}
} else {
fclose($fp);
$err = "Recordset had unexpected EOF 2";
return $false;
}
// slurp in the data
$MAXSIZE = 128000;
$text = '';
while ($txt = fread($fp,$MAXSIZE)) {
$text .= $txt;
}
fclose($fp);
@$arr = unserialize($text);
//var_dump($arr);
if (!is_array($arr)) {
$err = "Recordset had unexpected EOF (in serialized recordset)";
if (get_magic_quotes_runtime()) $err .= ". Magic Quotes Runtime should be disabled!";
return $false;
}
$rs = new $rsclass();
$rs->timeCreated = $ttl;
$rs->InitArrayFields($arr,$flds);
return $rs;
}
/**
* Save a file $filename and its $contents (normally for caching) with file locking
* Returns true if ok, false if fopen/fwrite error, 0 if rename error (eg. file is locked)
*/
function adodb_write_file($filename, $contents,$debug=false)
{
# http://www.php.net/bugs.php?id=9203 Bug that flock fails on Windows
# So to simulate locking, we assume that rename is an atomic operation.
# First we delete $filename, then we create a $tempfile write to it and
# rename to the desired $filename. If the rename works, then we successfully
# modified the file exclusively.
# What a stupid need - having to simulate locking.
# Risks:
# 1. $tempfile name is not unique -- very very low
# 2. unlink($filename) fails -- ok, rename will fail
# 3. adodb reads stale file because unlink fails -- ok, $rs timeout occurs
# 4. another process creates $filename between unlink() and rename() -- ok, rename() fails and cache updated
if (strncmp(PHP_OS,'WIN',3) === 0) {
// skip the decimal place
$mtime = substr(str_replace(' ','_',microtime()),2);
// getmypid() actually returns 0 on Win98 - never mind!
/apps/includes/adodb-old/$tmpname = $filename.uniqid($mtime).getmypid();
if (!($fd = @fopen(/apps/includes/adodb-old/$tmpname,'w'))) return false;
if (fwrite($fd,$contents)) $ok = true;
else $ok = false;
fclose($fd);
if ($ok) {
chmod(/apps/includes/adodb-old/$tmpname,0644);
// the tricky moment
@unlink($filename);
if (!@rename(/apps/includes/adodb-old/$tmpname,$filename)) {
unlink(/apps/includes/adodb-old/$tmpname);
$ok = 0;
}
if (!$ok) {
if ($debug) ADOConnection::outp( " Rename /apps/includes/adodb-old/$tmpname ".($ok? 'ok' : 'failed'));
}
}
return $ok;
}
if (!($fd = @fopen($filename, 'a'))) return false;
if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
if (fwrite( $fd, $contents )) $ok = true;
else $ok = false;
fclose($fd);
chmod($filename,0644);
}else {
fclose($fd);
if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename \n");
$ok = false;
}
return $ok;
}
?> adodb5/adodb-datadict.inc.php 100666 0 0 65210 10750035616 11404 $str
";
$a= Lens_ParseArgs($str);
print "
";
print_r($a);
print "
";
}
if (!function_exists('ctype_alnum')) {
function ctype_alnum($text) {
return preg_match('/^[a-z0-9]*$/i', $text);
}
}
//Lens_ParseTest();
/**
Parse arguments, treat "text" (text) and 'text' as quotation marks.
To escape, use "" or '' or ))
Will read in "abc def" sans quotes, as: abc def
Same with 'abc def'.
However if `abc def`, then will read in as `abc def`
@param endstmtchar Character that indicates end of statement
@param tokenchars Include the following characters in tokens apart from A-Z and 0-9
@returns 2 dimensional array containing parsed tokens.
*/
function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
{
$pos = 0;
$intoken = false;
$stmtno = 0;
$endquote = false;
$tokens = array();
$tokens[$stmtno] = array();
$max = strlen($args);
$quoted = false;
$tokarr = array();
while ($pos < $max) {
$ch = substr($args,$pos,1);
switch($ch) {
case ' ':
case "\t":
case "\n":
case "\r":
if (!$quoted) {
if ($intoken) {
$intoken = false;
$tokens[$stmtno][] = implode('',$tokarr);
}
break;
}
$tokarr[] = $ch;
break;
case '`':
if ($intoken) $tokarr[] = $ch;
case '(':
case ')':
case '"':
case "'":
if ($intoken) {
if (empty($endquote)) {
$tokens[$stmtno][] = implode('',$tokarr);
if ($ch == '(') $endquote = ')';
else $endquote = $ch;
$quoted = true;
$intoken = true;
$tokarr = array();
} else if ($endquote == $ch) {
$ch2 = substr($args,$pos+1,1);
if ($ch2 == $endquote) {
$pos += 1;
$tokarr[] = $ch2;
} else {
$quoted = false;
$intoken = false;
$tokens[$stmtno][] = implode('',$tokarr);
$endquote = '';
}
} else
$tokarr[] = $ch;
}else {
if ($ch == '(') $endquote = ')';
else $endquote = $ch;
$quoted = true;
$intoken = true;
$tokarr = array();
if ($ch == '`') $tokarr[] = '`';
}
break;
default:
if (!$intoken) {
if ($ch == $endstmtchar) {
$stmtno += 1;
$tokens[$stmtno] = array();
break;
}
$intoken = true;
$quoted = false;
$endquote = false;
$tokarr = array();
}
if ($quoted) $tokarr[] = $ch;
else if (ctype_alnum($ch) || strpos($tokenchars,$ch) !== false) $tokarr[] = $ch;
else {
if ($ch == $endstmtchar) {
$tokens[$stmtno][] = implode('',$tokarr);
$stmtno += 1;
$tokens[$stmtno] = array();
$intoken = false;
$tokarr = array();
break;
}
$tokens[$stmtno][] = implode('',$tokarr);
$tokens[$stmtno][] = $ch;
$intoken = false;
}
}
$pos += 1;
}
if ($intoken) $tokens[$stmtno][] = implode('',$tokarr);
return $tokens;
}
class ADODB_DataDict {
var $connection;
var $debug = false;
var $dropTable = 'DROP TABLE %s';
var $renameTable = 'RENAME TABLE %s TO %s';
var $dropIndex = 'DROP INDEX %s';
var $addCol = ' ADD';
var $alterCol = ' ALTER COLUMN';
var $dropCol = ' DROP COLUMN';
var $renameColumn = 'ALTER TABLE %s RENAME COLUMN %s TO %s'; // table, old-column, new-column, column-definitions (not used by default)
var $nameRegex = '\w';
var $nameRegexBrackets = 'a-zA-Z0-9_\(\)';
var $schema = false;
var $serverInfo = array();
var $autoIncrement = false;
var $dataProvider;
var $invalidResizeTypes4 = array('CLOB','BLOB','TEXT','DATE','TIME'); // for changetablesql
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.
function GetCommentSQL($table,$col)
{
return false;
}
function SetCommentSQL($table,$col,$cmt)
{
return false;
}
function MetaTables()
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaTables();
}
function MetaColumns($tab, $upper=true, $schema=false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema);
}
function MetaPrimaryKeys($tab,$owner=false,$intkey=false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey);
}
function MetaIndexes($table, $primary = false, $owner = false)
{
if (!$this->connection->IsConnected()) return array();
return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
}
function MetaType($t,$len=-1,$fieldobj=false)
{
static $typeMap = array(
'VARCHAR' => 'C',
'VARCHAR2' => 'C',
'CHAR' => 'C',
'C' => 'C',
'STRING' => 'C',
'NCHAR' => 'C',
'NVARCHAR' => 'C',
'VARYING' => 'C',
'BPCHAR' => 'C',
'CHARACTER' => 'C',
'INTERVAL' => 'C', # Postgres
'MACADDR' => 'C', # postgres
##
'LONGCHAR' => 'X',
'TEXT' => 'X',
'NTEXT' => 'X',
'M' => 'X',
'X' => 'X',
'CLOB' => 'X',
'NCLOB' => 'X',
'LVARCHAR' => 'X',
##
'BLOB' => 'B',
'IMAGE' => 'B',
'BINARY' => 'B',
'VARBINARY' => 'B',
'LONGBINARY' => 'B',
'B' => 'B',
##
'YEAR' => 'D', // mysql
'DATE' => 'D',
'D' => 'D',
##
'UNIQUEIDENTIFIER' => 'C', # MS SQL Server
##
'TIME' => 'T',
'TIMESTAMP' => 'T',
'DATETIME' => 'T',
'TIMESTAMPTZ' => 'T',
'T' => 'T',
'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
##
'BOOL' => 'L',
'BOOLEAN' => 'L',
'BIT' => 'L',
'L' => 'L',
##
'COUNTER' => 'R',
'R' => 'R',
'SERIAL' => 'R', // ifx
'INT IDENTITY' => 'R',
##
'INT' => 'I',
'INT2' => 'I',
'INT4' => 'I',
'INT8' => 'I',
'INTEGER' => 'I',
'INTEGER UNSIGNED' => 'I',
'SHORT' => 'I',
'TINYINT' => 'I',
'SMALLINT' => 'I',
'I' => 'I',
##
'LONG' => 'N', // interbase is numeric, oci8 is blob
'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
'DECIMAL' => 'N',
'DEC' => 'N',
'REAL' => 'N',
'DOUBLE' => 'N',
'DOUBLE PRECISION' => 'N',
'SMALLFLOAT' => 'N',
'FLOAT' => 'N',
'NUMBER' => 'N',
'NUM' => 'N',
'NUMERIC' => 'N',
'MONEY' => 'N',
## informix 9.2
'SQLINT' => 'I',
'SQLSERIAL' => 'I',
'SQLSMINT' => 'I',
'SQLSMFLOAT' => 'N',
'SQLFLOAT' => 'N',
'SQLMONEY' => 'N',
'SQLDECIMAL' => 'N',
'SQLDATE' => 'D',
'SQLVCHAR' => 'C',
'SQLCHAR' => 'C',
'SQLDTIME' => 'T',
'SQLINTERVAL' => 'N',
'SQLBYTES' => 'B',
'SQLTEXT' => 'X',
## informix 10
"SQLINT8" => 'I8',
"SQLSERIAL8" => 'I8',
"SQLNCHAR" => 'C',
"SQLNVCHAR" => 'C',
"SQLLVARCHAR" => 'X',
"SQLBOOL" => 'L'
);
if (!$this->connection->IsConnected()) {
$t = strtoupper($t);
if (isset($typeMap[$t])) return $typeMap[$t];
return 'N';
}
return $this->connection->MetaType($t,$len,$fieldobj);
}
function NameQuote($name = NULL,$allowBrackets=false)
{
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
$regex = ($allowBrackets) ? $this->nameRegexBrackets : $this->nameRegex;
if ( !preg_match('/^[' . $regex . ']+$/', $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)
{
$rez = 2;
$conn = $this->connection;
$saved = $conn->debug;
foreach($sql as $line) {
if ($this->debug) $conn->debug = true;
$ok = $conn->Execute($line);
$conn->debug = $saved;
if (!$ok) {
if ($this->debug) ADOConnection::outp($conn->ErrorMsg());
if (!$continueOnError) return 0;
$rez = 1;
}
}
return $rez;
}
/**
Returns the actual type given a character code.
C: varchar
X: CLOB (character large object) or largest varchar size if CLOB is not supported
C2: Multibyte varchar
X2: Multibyte CLOB
B: BLOB (binary large object)
D: Date
T: Date-time
L: Integer field suitable for storing booleans (0 or 1)
I: Integer
F: Floating point number
N: Numeric or decimal number
*/
function ActualType($meta)
{
return $meta;
}
function CreateDatabase($dbname,$options=false)
{
$options = $this->_Options($options);
$sql = array();
$s = 'CREATE DATABASE ' . $this->NameQuote($dbname);
if (isset($options[$this->upperName]))
$s .= ' '.$options[$this->upperName];
$sql[] = $s;
return $sql;
}
/*
Generates the SQL to create index. Returns an array of sql strings.
*/
function CreateIndexSQL($idxname, $tabname, $flds, $idxoptions = false)
{
if (!is_array($flds)) {
$flds = explode(',',$flds);
}
foreach($flds as $key => $fld) {
# some indexes can use partial fields, eg. index first 32 chars of "name" with NAME(32)
$flds[$key] = $this->NameQuote($fld,$allowBrackets=true);
}
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)
{
$this->schema = $schema;
}
function AddColumnSQL($tabname, $flds)
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
foreach($lines as $v) {
$sql[] = $alter . $v;
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
/**
* Change the definition of one column
*
* As some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
* to allow, recreating the table and copying the content over to the new table
* @param string $tabname table-name
* @param string $flds column-name and type for the changed column
* @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
* @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$tabname = $this->TableName ($tabname);
$sql = array();
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
foreach($lines as $v) {
$sql[] = $alter . $v;
}
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
/**
* Rename one column
*
* Some DBM's can only do this together with changeing the type of the column (even if that stays the same, eg. mysql)
* @param string $tabname table-name
* @param string $oldcolumn column-name to be renamed
* @param string $newcolumn new column-name
* @param string $flds='' complete column-defintion-string like for AddColumnSQL, only used by mysql atm., default=''
* @return array with SQL strings
*/
function RenameColumnSQL($tabname,$oldcolumn,$newcolumn,$flds='')
{
$tabname = $this->TableName ($tabname);
if ($flds) {
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
list(,$first) = each($lines);
list(,$column_def) = split("[\t ]+",$first,2);
}
return array(sprintf($this->renameColumn,$tabname,$this->NameQuote($oldcolumn),$this->NameQuote($newcolumn),$column_def));
}
/**
* Drop one column
*
* Some DBM's can't do that on there own, you need to supply the complete defintion of the new table,
* to allow, recreating the table and copying the content over to the new table
* @param string $tabname table-name
* @param string $flds column-name and type for the changed column
* @param string $tableflds='' complete defintion of the new table, eg. for postgres, default ''
* @param array/string $tableoptions='' options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
$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 . $this->NameQuote($v);
}
return $sql;
}
function DropTableSQL($tabname)
{
return array (sprintf($this->dropTable, $this->TableName($tabname)));
}
function RenameTableSQL($tabname,$newname)
{
return array (sprintf($this->renameTable, $this->TableName($tabname),$this->TableName($newname)));
}
/**
Generate the SQL to create table. Returns an array of sql strings.
*/
function CreateTableSQL($tabname, $flds, $tableoptions=array())
{
list($lines,$pkey,$idxs) = $this->_GenFields($flds, true);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$taboptions = $this->_Options($tableoptions);
$tabname = $this->TableName ($tabname);
$sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
// ggiunta - 2006/10/12 - KLUDGE:
// if we are on autoincrement, and table options includes REPLACE, the
// autoincrement sequence has already been dropped on table creation sql, so
// we avoid passing REPLACE to trigger creation code. This prevents
// creating sql that double-drops the sequence
if ($this->autoIncrement && isset($taboptions['REPLACE']))
unset($taboptions['REPLACE']);
$tsql = $this->_Triggers($tabname,$taboptions);
foreach($tsql as $s) $sql[] = $s;
if (is_array($idxs)) {
foreach($idxs as $idx => $idxdef) {
$sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']);
$sql = array_merge($sql, $sql_idxs);
}
}
return $sql;
}
function _GenFields($flds,$widespacing=false)
{
if (is_string($flds)) {
$padding = ' ';
$txt = $flds.$padding;
$flds = array();
$flds0 = Lens_ParseArgs($txt,',');
$hasparam = false;
foreach($flds0 as $f0) {
$f1 = array();
foreach($f0 as $token) {
switch (strtoupper($token)) {
case 'INDEX':
$f1['INDEX'] = '';
// fall through intentionally
case 'CONSTRAINT':
case 'DEFAULT':
$hasparam = $token;
break;
default:
if ($hasparam) $f1[$hasparam] = $token;
else $f1[] = $token;
$hasparam = false;
break;
}
}
// 'index' token without a name means single column index: name it after column
if (array_key_exists('INDEX', $f1) && $f1['INDEX'] == '') {
$f1['INDEX'] = isset($f0['NAME']) ? $f0['NAME'] : $f0[0];
// check if column name used to create an index name was quoted
if (($f1['INDEX'][0] == '"' || $f1['INDEX'][0] == "'" || $f1['INDEX'][0] == "`") &&
($f1['INDEX'][0] == substr($f1['INDEX'], -1))) {
$f1['INDEX'] = $f1['INDEX'][0].'idx_'.substr($f1['INDEX'], 1, -1).$f1['INDEX'][0];
}
else
$f1['INDEX'] = 'idx_'.$f1['INDEX'];
}
// reset it, so we don't get next field 1st token as INDEX...
$hasparam = false;
$flds[] = $f1;
}
}
$this->autoIncrement = false;
$lines = array();
$pkey = array();
$idxs = array();
foreach($flds as $fld) {
$fld = _array_change_key_case($fld);
$fname = false;
$fdefault = false;
$fautoinc = false;
$ftype = false;
$fsize = false;
$fprec = false;
$fprimary = false;
$fnoquote = false;
$fdefts = false;
$fdefdate = false;
$fconstraint = false;
$fnotnull = false;
$funsigned = false;
$findex = '';
$funiqueindex = false;
//-----------------
// Parse attributes
foreach($fld as $attr => $v) {
if ($attr == 2 && is_numeric($v)) $attr = 'SIZE';
else if (is_numeric($attr) && $attr > 1 && !is_numeric($v)) $attr = strtoupper($v);
switch($attr) {
case '0':
case 'NAME': $fname = $v; break;
case '1':
case 'TYPE': $ty = $v; $ftype = $this->ActualType(strtoupper($v)); break;
case 'SIZE':
$dotat = strpos($v,'.'); if ($dotat === false) $dotat = strpos($v,',');
if ($dotat === false) $fsize = $v;
else {
$fsize = substr($v,0,$dotat);
$fprec = substr($v,$dotat+1);
}
break;
case 'UNSIGNED': $funsigned = true; break;
case 'AUTOINCREMENT':
case 'AUTO': $fautoinc = true; $fnotnull = true; break;
case 'KEY':
// a primary key col can be non unique in itself (if key spans many cols...)
case 'PRIMARY': $fprimary = $v; $fnotnull = true; /*$funiqueindex = true;*/ break;
case 'DEF':
case 'DEFAULT': $fdefault = $v; break;
case 'NOTNULL': $fnotnull = $v; break;
case 'NOQUOTE': $fnoquote = $v; break;
case 'DEFDATE': $fdefdate = $v; break;
case 'DEFTIMESTAMP': $fdefts = $v; break;
case 'CONSTRAINT': $fconstraint = $v; break;
// let INDEX keyword create a 'very standard' index on column
case 'INDEX': $findex = $v; break;
case 'UNIQUE': $funiqueindex = true; break;
} //switch
} // foreach $fld
//--------------------
// VALIDATE FIELD INFO
if (!strlen($fname)) {
if ($this->debug) ADOConnection::outp("Undefined NAME");
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;
} else {
$ftype = strtoupper($ftype);
}
$ftype = $this->_GetSize($ftype, $ty, $fsize, $fprec);
if ($ty == 'X' || $ty == 'X2' || $ty == 'B') $fnotnull = false; // some blob types do not accept nulls
if ($fprimary) $pkey[] = $fname;
// some databases do not allow blobs to have defaults
if ($ty == 'X') $fdefault = false;
// build list of indexes
if ($findex != '') {
if (array_key_exists($findex, $idxs)) {
$idxs[$findex]['cols'][] = ($fname);
if (in_array('UNIQUE', $idxs[$findex]['opts']) != $funiqueindex) {
if ($this->debug) ADOConnection::outp("Index $findex defined once UNIQUE and once not");
}
if ($funiqueindex && !in_array('UNIQUE', $idxs[$findex]['opts']))
$idxs[$findex]['opts'][] = 'UNIQUE';
}
else
{
$idxs[$findex] = array();
$idxs[$findex]['cols'] = array($fname);
if ($funiqueindex)
$idxs[$findex]['opts'] = array('UNIQUE');
else
$idxs[$findex]['opts'] = array();
}
}
//--------------------
// CONSTRUCT FIELD SQL
if ($fdefts) {
if (substr($this->connection->databaseType,0,5) == 'mysql') {
$ftype = 'TIMESTAMP';
} else {
$fdefault = $this->connection->sysTimeStamp;
}
} else if ($fdefdate) {
if (substr($this->connection->databaseType,0,5) == 'mysql') {
$ftype = 'TIMESTAMP';
} else {
$fdefault = $this->connection->sysDate;
}
} else if ($fdefault !== false && !$fnoquote) {
if ($ty == 'C' or $ty == 'X' or
( substr($fdefault,0,1) != "'" && !is_numeric($fdefault))) {
if (($ty == 'D' || $ty == 'T') && strtolower($fdefault) != 'null') {
// convert default date into database-aware code
if ($ty == 'T')
{
$fdefault = $this->connection->DBTimeStamp($fdefault);
}
else
{
$fdefault = $this->connection->DBDate($fdefault);
}
}
else
if (strlen($fdefault) != 1 && substr($fdefault,0,1) == ' ' && substr($fdefault,strlen($fdefault)-1) == ' ')
$fdefault = trim($fdefault);
else if (strtolower($fdefault) != 'null')
$fdefault = $this->connection->qstr($fdefault);
}
}
$suffix = $this->_CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
// add index creation
if ($widespacing) $fname = str_pad($fname,24);
// check for field names appearing twice
if (array_key_exists($fid, $lines)) {
ADOConnection::outp("Field '$fname' defined twice");
}
$lines[$fid] = $fname.' '.$ftype.$suffix;
if ($fautoinc) $this->autoIncrement = true;
} // foreach $flds
return array($lines,$pkey,$idxs);
}
/**
GENERATE THE SIZE PART OF THE DATATYPE
$ftype is the actual type
$ty is the type defined originally in the DDL
*/
function _GetSize($ftype, $ty, $fsize, $fprec)
{
if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) {
$ftype .= "(".$fsize;
if (strlen($fprec)) $ftype .= ",".$fprec;
$ftype .= ')';
}
return $ftype;
}
// return string must begin with space
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
if ($fnotnull) $suffix .= ' NOT NULL';
if ($fconstraint) $suffix .= ' '.$fconstraint;
return $suffix;
}
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
{
$sql = array();
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;
}
function _DropAutoIncrement($tabname)
{
return false;
}
function _TableSQL($tabname,$lines,$pkey,$tableoptions)
{
$sql = array();
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);
if (sizeof($pkey)>0) {
$s .= ",\n PRIMARY KEY (";
$s .= implode(", ",$pkey).")";
}
if (isset($tableoptions['CONSTRAINTS']))
$s .= "\n".$tableoptions['CONSTRAINTS'];
if (isset($tableoptions[$this->upperName.'_CONSTRAINTS']))
$s .= "\n".$tableoptions[$this->upperName.'_CONSTRAINTS'];
$s .= "\n)";
if (isset($tableoptions[$this->upperName])) $s .= $tableoptions[$this->upperName];
$sql[] = $s;
return $sql;
}
/**
GENERATE TRIGGERS IF NEEDED
used when table has auto-incrementing field that is emulated using triggers
*/
function _Triggers($tabname,$taboptions)
{
return array();
}
/**
Sanitize options, so that array elements with no keys are promoted to keys
*/
function _Options($opts)
{
if (!is_array($opts)) return array();
$newopts = array();
foreach($opts as $k => $v) {
if (is_numeric($k)) $newopts[strtoupper($v)] = $v;
else $newopts[strtoupper($k)] = $v;
}
return $newopts;
}
/**
"Florian Buzin [ easywe ]"
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)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($this->connection->fetchMode !== false) $savem = $this->connection->SetFetchMode(false);
// check table exists
$save_handler = $this->connection->raiseErrorFn;
$this->connection->raiseErrorFn = '';
$cols = $this->MetaColumns($tablename);
$this->connection->raiseErrorFn = $save_handler;
if (isset($savem)) $this->connection->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
if ( empty($cols)) {
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
}
if (is_array($flds)) {
// Cycle through the update fields, comparing
// existing fields to fields to update.
// if the Metatype and size is exactly the
// same, ignore - by Mark Newham
$holdflds = array();
foreach($flds as $k=>$v) {
if ( isset($cols[$k]) && is_object($cols[$k]) ) {
// If already not allowing nulls, then don't change
$obj = $cols[$k];
if (isset($obj->not_null) && $obj->not_null)
$v = str_replace('NOT NULL','',$v);
$c = $cols[$k];
$ml = $c->max_length;
$mt = $this->MetaType($c->type,$ml);
if ($ml == -1) $ml = '';
if ($mt == 'X') $ml = $v['SIZE'];
if (($mt != $v['TYPE']) || $ml != $v['SIZE']) {
$holdflds[$k] = $v;
}
} else {
$holdflds[$k] = $v;
}
}
$flds = $holdflds;
}
// already exists, alter table instead
list($lines,$pkey,$idxs) = $this->_GenFields($flds);
// genfields can return FALSE at times
if ($lines == null) $lines = array();
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
$sql = array();
foreach ( $lines as $id => $v ) {
if ( isset($cols[$id]) && is_object($cols[$id]) ) {
$flds = Lens_ParseArgs($v,',');
// We are trying to change the size of the field, if not allowed, simply ignore the request.
// $flds[1] holds the type, $flds[2] holds the size -postnuke addition
if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4)
&& (isset($flds[0][2]) && is_numeric($flds[0][2]))) {
if ($this->debug) ADOConnection::outp(sprintf("
%s cannot be changed to %s currently
", $flds[0][0], $flds[0][1]));
#echo "
$this->alterCol cannot be changed to $flds currently
";
continue;
}
$sql[] = $alter . $this->alterCol . ' ' . $v;
} else {
$sql[] = $alter . $this->addCol . ' ' . $v;
}
}
return $sql;
}
} // class
?> adodb5/adodb-error.inc.php 100666 0 0 20547 10750035616 10764 DB_ERROR_NOSUCHTABLE,
'/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/i' => DB_ERROR_ALREADY_EXISTS,
'/divide by zero$/i' => DB_ERROR_DIVZERO,
'/pg_atoi: error in .*: can\'t parse /i' => DB_ERROR_INVALID_NUMBER,
'/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/i' => DB_ERROR_NOSUCHFIELD,
'/parser: parse error at or near \"/i' => DB_ERROR_SYNTAX,
'/referential integrity violation/i' => DB_ERROR_CONSTRAINT,
'/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/i'
=> DB_ERROR_ALREADY_EXISTS
);
reset($error_regexps);
while (list($regexp,$code) = each($error_regexps)) {
if (preg_match($regexp, $errormsg)) {
return $code;
}
}
// Fall back to DB_ERROR if there was no mapping.
return DB_ERROR;
}
function adodb_error_odbc()
{
static $MAP = array(
'01004' => DB_ERROR_TRUNCATED,
'07001' => DB_ERROR_MISMATCH,
'21S01' => DB_ERROR_MISMATCH,
'21S02' => DB_ERROR_MISMATCH,
'22003' => DB_ERROR_INVALID_NUMBER,
'22008' => DB_ERROR_INVALID_DATE,
'22012' => DB_ERROR_DIVZERO,
'23000' => DB_ERROR_CONSTRAINT,
'24000' => DB_ERROR_INVALID,
'34000' => DB_ERROR_INVALID,
'37000' => DB_ERROR_SYNTAX,
'42000' => DB_ERROR_SYNTAX,
'IM001' => DB_ERROR_UNSUPPORTED,
'S0000' => DB_ERROR_NOSUCHTABLE,
'S0001' => DB_ERROR_NOT_FOUND,
'S0002' => DB_ERROR_NOSUCHTABLE,
'S0011' => DB_ERROR_ALREADY_EXISTS,
'S0012' => DB_ERROR_NOT_FOUND,
'S0021' => DB_ERROR_ALREADY_EXISTS,
'S0022' => DB_ERROR_NOT_FOUND,
'S1000' => DB_ERROR_NOSUCHTABLE,
'S1009' => DB_ERROR_INVALID,
'S1090' => DB_ERROR_INVALID,
'S1C00' => DB_ERROR_NOT_CAPABLE
);
return $MAP;
}
function adodb_error_ibase()
{
static $MAP = array(
-104 => DB_ERROR_SYNTAX,
-150 => DB_ERROR_ACCESS_VIOLATION,
-151 => DB_ERROR_ACCESS_VIOLATION,
-155 => DB_ERROR_NOSUCHTABLE,
-157 => DB_ERROR_NOSUCHFIELD,
-158 => DB_ERROR_VALUE_COUNT_ON_ROW,
-170 => DB_ERROR_MISMATCH,
-171 => DB_ERROR_MISMATCH,
-172 => DB_ERROR_INVALID,
-204 => DB_ERROR_INVALID,
-205 => DB_ERROR_NOSUCHFIELD,
-206 => DB_ERROR_NOSUCHFIELD,
-208 => DB_ERROR_INVALID,
-219 => DB_ERROR_NOSUCHTABLE,
-297 => DB_ERROR_CONSTRAINT,
-530 => DB_ERROR_CONSTRAINT,
-803 => DB_ERROR_CONSTRAINT,
-551 => DB_ERROR_ACCESS_VIOLATION,
-552 => DB_ERROR_ACCESS_VIOLATION,
-922 => DB_ERROR_NOSUCHDB,
-923 => DB_ERROR_CONNECT_FAILED,
-924 => DB_ERROR_CONNECT_FAILED
);
return $MAP;
}
function adodb_error_ifx()
{
static $MAP = array(
'-201' => DB_ERROR_SYNTAX,
'-206' => DB_ERROR_NOSUCHTABLE,
'-217' => DB_ERROR_NOSUCHFIELD,
'-329' => DB_ERROR_NODBSELECTED,
'-1204' => DB_ERROR_INVALID_DATE,
'-1205' => DB_ERROR_INVALID_DATE,
'-1206' => DB_ERROR_INVALID_DATE,
'-1209' => DB_ERROR_INVALID_DATE,
'-1210' => DB_ERROR_INVALID_DATE,
'-1212' => DB_ERROR_INVALID_DATE
);
return $MAP;
}
function adodb_error_oci8()
{
static $MAP = array(
1 => DB_ERROR_ALREADY_EXISTS,
900 => DB_ERROR_SYNTAX,
904 => DB_ERROR_NOSUCHFIELD,
923 => DB_ERROR_SYNTAX,
942 => DB_ERROR_NOSUCHTABLE,
955 => DB_ERROR_ALREADY_EXISTS,
1476 => DB_ERROR_DIVZERO,
1722 => DB_ERROR_INVALID_NUMBER,
2289 => DB_ERROR_NOSUCHTABLE,
2291 => DB_ERROR_CONSTRAINT,
2449 => DB_ERROR_CONSTRAINT
);
return $MAP;
}
function adodb_error_mssql()
{
static $MAP = array(
208 => DB_ERROR_NOSUCHTABLE,
2601 => DB_ERROR_ALREADY_EXISTS
);
return $MAP;
}
function adodb_error_sqlite()
{
static $MAP = array(
1 => DB_ERROR_SYNTAX
);
return $MAP;
}
function adodb_error_mysql()
{
static $MAP = array(
1004 => DB_ERROR_CANNOT_CREATE,
1005 => DB_ERROR_CANNOT_CREATE,
1006 => DB_ERROR_CANNOT_CREATE,
1007 => DB_ERROR_ALREADY_EXISTS,
1008 => DB_ERROR_CANNOT_DROP,
1045 => DB_ERROR_ACCESS_VIOLATION,
1046 => DB_ERROR_NODBSELECTED,
1049 => DB_ERROR_NOSUCHDB,
1050 => DB_ERROR_ALREADY_EXISTS,
1051 => DB_ERROR_NOSUCHTABLE,
1054 => DB_ERROR_NOSUCHFIELD,
1062 => DB_ERROR_ALREADY_EXISTS,
1064 => DB_ERROR_SYNTAX,
1100 => DB_ERROR_NOT_LOCKED,
1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
1146 => DB_ERROR_NOSUCHTABLE,
1048 => DB_ERROR_CONSTRAINT,
2002 => DB_ERROR_CONNECT_FAILED,
2005 => DB_ERROR_CONNECT_FAILED
);
return $MAP;
}
?> adodb5/adodb-errorhandler.inc.php 100666 0 0 5276 10750035616 12304 $s";
trigger_error($s,ADODB_ERROR_HANDLER_TYPE);
}
?>
adodb5/adodb-errorpear.inc.php 100666 0 0 4344 10750035616 11611 !$s";
}
/**
* Returns last PEAR_Error object. This error might be for an error that
* occured several sql statements ago.
*/
function ADODB_PEAR_Error()
{
global $ADODB_Last_PEAR_Error;
return $ADODB_Last_PEAR_Error;
}
?> adodb5/adodb-exceptions.inc.php 100666 0 0 4250 10750035616 11765 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;
if ($thisConnection) {
$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 (error_reporting() == 0) return; // obey @ protocol
if (is_string($ADODB_EXCEPTION)) $errfn = $ADODB_EXCEPTION;
else $errfn = 'ADODB_EXCEPTION';
throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
}
?> adodb5/adodb-iterator.inc.php 100666 0 0 1277 10750035616 11443 Execute("select * from adoxyz");
foreach($rs as $k => $v) {
echo $k; print_r($v); echo " ";
}
Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2
Moved to adodb.inc.php to improve performance.
*/
?> adodb5/adodb-lib.inc.php 100666 0 0 105101 10750035616 10407 sizeof($array)) $max = sizeof($array);
else $max = $probe;
for ($j=0;$j < $max; $j++) {
$row = $array[$j];
if (!$row) break;
$i = -1;
foreach($row as $v) {
$i += 1;
if (isset($types[$i]) && $types[$i]=='C') continue;
//print " ($i ".$types[$i]. "$v) ";
$v = trim($v);
if (!preg_match('/^[+-]{0,1}[0-9\.]+$/',$v)) {
$types[$i] = 'C'; // once C, always C
continue;
}
if ($j == 0) {
// If empty string, we presume is character
// test for integer for 1st row only
// after that it is up to testing other rows to prove
// that it is not an integer
if (strlen($v) == 0) $types[$i] = 'C';
if (strpos($v,'.') !== false) $types[$i] = 'N';
else $types[$i] = 'I';
continue;
}
if (strpos($v,'.') !== false) $types[$i] = 'N';
}
}
}
function adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
{
$oldX = sizeof(reset($arr));
$oldY = sizeof($arr);
if ($hdr) {
$startx = 1;
$hdr = array('Fields');
for ($y = 0; $y < $oldY; $y++) {
$hdr[] = $arr[$y][0];
}
} else
$startx = 0;
for ($x = $startx; $x < $oldX; $x++) {
if ($fobjs) {
$o = $fobjs[$x];
$newarr[] = array($o->name);
} else
$newarr[] = array();
for ($y = 0; $y < $oldY; $y++) {
$newarr[$x-$startx][] = $arr[$y][$x];
}
}
}
// Force key to upper.
// See also http://www.php.net/manual/en/function.array-change-key-case.php
function _array_change_key_case($an_array)
{
if (is_array($an_array)) {
$new_array = array();
foreach($an_array as $key=>$value)
$new_array[strtoupper($key)] = $value;
return $new_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 ($v === null) {
$v = 'NULL';
$fieldArray[$k] = $v;
} else if ($autoQuote && !is_numeric($v) /*and strncmp($v,"'",1) !== 0 -- sql injection risk*/ and strcasecmp($v,$zthis->null2null)!=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 (isset($fieldArray[$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;
}
} else
return 0;
}
// print "
Error=".$this->ErrorNo().'
';
$first = true;
foreach($fieldArray as $k => $v) {
if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
if ($first) {
$first = false;
$iCols = "$k";
$iVals = "$v";
} else {
$iCols .= ",$k";
$iVals .= ",$v";
}
}
$insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
$rs = $zthis->Execute($insert);
return ($rs) ? 2 : 0;
}
// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
$size=0, $selectAttr='',$compareFields0=true)
{
$hasvalue = false;
if ($multiple or is_array($defstr)) {
if ($size==0) $size=5;
$attr = ' multiple size="'.$size.'"';
if (!strpos($name,'[]')) $name .= '[]';
} else if ($size) $attr = ' size="'.$size.'"';
else $attr ='';
$s = '\n";
}
// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
function _adodb_getmenu_gp(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
$size=0, $selectAttr='',$compareFields0=true)
{
$hasvalue = false;
if ($multiple or is_array($defstr)) {
if ($size==0) $size=5;
$attr = ' multiple size="'.$size.'"';
if (!strpos($name,'[]')) $name .= '[]';
} else if ($size) $attr = ' size="'.$size.'"';
else $attr ='';
$s = '\n";
}
/*
Count the number of records this sql statement will return by using
query rewriting heuristics...
Does not work with UNIONs, except with postgresql and oracle.
Usage:
$conn->Connect(...);
$cnt = _adodb_getcount($conn, $sql);
*/
function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
{
$qryRecs = 0;
if (!empty($zthis->_nestedSQL) || preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) ||
preg_match('/\s+GROUP\s+BY\s+/is',$sql) ||
preg_match('/\s+UNION\s+/is',$sql)) {
$rewritesql = adodb_strip_order_by($sql);
// ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
// but this is only supported by oracle and postgresql...
if ($zthis->dataProvider == 'oci8') {
// Allow Oracle hints to be used for query optimization, Chris Wrye
if (preg_match('#/\\*+.*?\\*\\/#', $sql, $hint)) {
$rewritesql = "SELECT ".$hint[0]." COUNT(*) FROM (".$rewritesql.")";
} else
$rewritesql = "SELECT COUNT(*) FROM (".$rewritesql.")";
} else if (strncmp($zthis->databaseType,'postgres',8) == 0) {
$rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
} else {
$rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
}
} else {
// now replace SELECT ... FROM with SELECT COUNT(*) FROM
$rewritesql = preg_replace(
'/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
// fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
// with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
// also see http://phplens.com/lens/lensforum/msgs.php?id=12752
$rewritesql = adodb_strip_order_by($rewritesql);
}
if (isset($rewritesql) && $rewritesql != $sql) {
if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
if ($secs2cache) {
// we only use half the time of secs2cache because the count can quickly
// become inaccurate if new records are added
$qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
} else {
$qryRecs = $zthis->GetOne($rewritesql,$inputarr);
}
if ($qryRecs !== false) return $qryRecs;
}
//--------------------------------------------
// query rewrite failed - so try slower way...
// strip off unneeded ORDER BY if no UNION
if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
$rstest = $zthis->Execute($rewritesql,$inputarr);
if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
if ($rstest) {
$qryRecs = $rstest->RecordCount();
if ($qryRecs == -1) {
global $ADODB_EXTENSION;
// some databases will return -1 on MoveLast() - change to MoveNext()
if ($ADODB_EXTENSION) {
while(!$rstest->EOF) {
adodb_movenext($rstest);
}
} else {
while(!$rstest->EOF) {
$rstest->MoveNext();
}
}
$qryRecs = $rstest->_currentRow;
}
$rstest->Close();
if ($qryRecs == -1) return 0;
}
return $qryRecs;
}
/*
Code originally from "Cornel G"
This code might not work with SQL that has UNION in it
Also if you are using CachePageExecute(), there is a strong possibility that
data will get out of synch. use CachePageExecute() only with tables that
rarely change.
*/
function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
$inputarr=false, $secs2cache=0)
{
$atfirstpage = false;
$atlastpage = false;
$lastpageno=1;
// If an invalid nrows is supplied,
// we assume a default value of 10 rows per page
if (!isset($nrows) || $nrows <= 0) $nrows = 10;
$qryRecs = false; //count records for no offset
$qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
$lastpageno = (int) ceil($qryRecs / $nrows);
$zthis->_maxRecordCount = $qryRecs;
// Here we check whether $page is the last page or
// whether we are trying to retrieve
// a page number greater than the last page number.
if ($page >= $lastpageno) {
$page = $lastpageno;
$atlastpage = true;
}
// If page number <= 1, then we are at the first page
if (empty($page) || $page <= 1) {
$page = 1;
$atfirstpage = true;
}
// We get the data we want
$offset = $nrows * ($page-1);
if ($secs2cache > 0)
$rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
else
$rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
// Before returning the RecordSet, we set the pagination properties we need
if ($rsreturn) {
$rsreturn->_maxRecordCount = $qryRecs;
$rsreturn->rowsPerPage = $nrows;
$rsreturn->AbsolutePage($page);
$rsreturn->AtFirstPage($atfirstpage);
$rsreturn->AtLastPage($atlastpage);
$rsreturn->LastPageNo($lastpageno);
}
return $rsreturn;
}
// Ivn Oliva version
function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
{
$atfirstpage = false;
$atlastpage = false;
if (!isset($page) || $page <= 1) { // If page number <= 1, then we are at the first page
$page = 1;
$atfirstpage = true;
}
if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page
// Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
// the last page number.
$pagecounter = $page + 1;
$pagecounteroffset = ($pagecounter * $nrows) - $nrows;
if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
if ($rstest) {
while ($rstest && $rstest->EOF && $pagecounter>0) {
$atlastpage = true;
$pagecounter--;
$pagecounteroffset = $nrows * ($pagecounter - 1);
$rstest->Close();
if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
}
if ($rstest) $rstest->Close();
}
if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it
$page = $pagecounter;
if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first
//... page, that is, the recordset has only 1 page.
}
// We get the data we want
$offset = $nrows * ($page-1);
if ($secs2cache > 0) $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
else $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
// Before returning the RecordSet, we set the pagination properties we need
if ($rsreturn) {
$rsreturn->rowsPerPage = $nrows;
$rsreturn->AbsolutePage($page);
$rsreturn->AtFirstPage($atfirstpage);
$rsreturn->AtLastPage($atlastpage);
}
return $rsreturn;
}
function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=2)
{
global $ADODB_QUOTE_FIELDNAMES;
if (!$rs) {
printf(ADODB_BAD_RS,'GetUpdateSQL');
return false;
}
$fieldUpdatedCount = 0;
$arrFields = _array_change_key_case($arrFields);
$hasnumeric = isset($rs->fields[0]);
$setFields = '';
// Loop through all of the fields in the recordset
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
// Get the field from the recordset
$field = $rs->FetchField($i);
// If the recordset field is one
// of the fields passed in then process.
$upperfname = strtoupper($field->name);
if (adodb_key_exists($upperfname,$arrFields,$force)) {
// If the existing field value in the recordset
// is different from the value passed in then
// go ahead and append the field name and new value to
// the update query.
if ($hasnumeric) $val = $rs->fields[$i];
else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name];
else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)];
else $val = '';
if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
// Set the counter for the number of fields that will be updated.
$fieldUpdatedCount++;
// Based on the datatype of the field
// Format the value properly for the database
$type = $rs->MetaType($field->type);
if ($type == 'null') {
$type = 'C';
}
if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES))
$fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
else
$fnameq = $upperfname;
// is_null requires php 4.0.4
//*//
if (is_null($arrFields[$upperfname])
|| (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
|| $arrFields[$upperfname] === $zthis->null2null
)
{
switch ($force) {
//case 0:
// //Ignore empty values. This is allready handled in "adodb_key_exists" function.
//break;
case 1:
//Set null
$setFields .= $field->name . " = null, ";
break;
case 2:
//Set empty
$arrFields[$upperfname] = "";
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
break;
default:
case 3:
//Set the value that was given in array, so you can give both null and empty values
if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
$setFields .= $field->name . " = null, ";
} else {
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,$arrFields, $magicq);
}
break;
}
//*//
} else {
//we do this so each driver can customize the sql for
//DB specific column types.
//Oracle needs BLOB types to be handled with a returning clause
//postgres has special needs as well
$setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
$arrFields, $magicq);
}
}
}
}
// If there were any modified fields then build the rest of the update query.
if ($fieldUpdatedCount > 0 || $forceUpdate) {
// Get the table name from the existing query.
if (!empty($rs->tableName)) $tableName = $rs->tableName;
else {
preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
$tableName = $tableName[1];
}
// Get the full where clause excluding the word "WHERE" from
// the existing query.
preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
$discard = false;
// not a good hack, improvements?
if ($whereClause) {
#var_dump($whereClause);
if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
else if (preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard));
else if (preg_match('/\s(FOR UPDATE.*)/is', $whereClause[1], $discard));
else preg_match('/\s.*(\) WHERE .*)/is', $whereClause[1], $discard); # see http://sourceforge.net/tracker/index.php?func=detail&aid=1379638&group_id=42718&atid=433976
} else
$whereClause = array(false,false);
if ($discard)
$whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
$sql = 'UPDATE '.$tableName.' SET '.substr($setFields, 0, -2);
if (strlen($whereClause[1]) > 0)
$sql .= ' WHERE '.$whereClause[1];
return $sql;
} else {
return false;
}
}
function adodb_key_exists($key, &$arr,$force=2)
{
if ($force<=0) {
// the following is the old behaviour where null or empty fields are ignored
return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
}
if (isset($arr[$key])) return true;
## null check below
if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
return false;
}
/**
* There is a special case of this function for the oci8 driver.
* The proper way to handle an insert w/ a blob in oracle requires
* a returning clause with bind variables and a descriptor blob.
*
*
*/
function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$force=2)
{
static $cacheRS = false;
static $cacheSig = 0;
static $cacheCols;
global $ADODB_QUOTE_FIELDNAMES;
$tableName = '';
$values = '';
$fields = '';
$recordSet = null;
$arrFields = _array_change_key_case($arrFields);
$fieldInsertedCount = 0;
if (is_string($rs)) {
//ok we have a table name
//try and get the column info ourself.
$tableName = $rs;
//we need an object for the recordSet
//because we have to call MetaType.
//php can't do a $rsclass::MetaType()
$rsclass = $zthis->rsPrefix.$zthis->databaseType;
$recordSet = new $rsclass(-1,$zthis->fetchMode);
$recordSet->connection = $zthis;
if (is_string($cacheRS) && $cacheRS == $rs) {
$columns = $cacheCols;
} else {
$columns = $zthis->MetaColumns( $tableName );
$cacheRS = $tableName;
$cacheCols = $columns;
}
} else if (is_subclass_of($rs, 'adorecordset')) {
if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
$columns = $cacheCols;
} else {
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
$columns[] = $rs->FetchField($i);
$cacheRS = $cacheSig;
$cacheCols = $columns;
$rs->insertSig = $cacheSig++;
}
$recordSet = $rs;
} else {
printf(ADODB_BAD_RS,'GetInsertSQL');
return false;
}
// Loop through all of the fields in the recordset
foreach( $columns as $field ) {
$upperfname = strtoupper($field->name);
if (adodb_key_exists($upperfname,$arrFields,$force)) {
$bad = false;
if ((strpos($upperfname,' ') !== false) || ($ADODB_QUOTE_FIELDNAMES))
$fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
else
$fnameq = $upperfname;
$type = $recordSet->MetaType($field->type);
/*/
if (is_null($arrFields[$upperfname])
|| (empty($arrFields[$upperfname]) && strlen($arrFields[$upperfname]) == 0)
|| $arrFields[$upperfname] === $zthis->null2null
)
{
switch ($force) {
case 0: // we must always set null if missing
$bad = true;
break;
case 1:
$values .= "null, ";
break;
case 2:
//Set empty
$arrFields[$upperfname] = "";
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,$arrFields, $magicq);
break;
default:
case 3:
//Set the value that was given in array, so you can give both null and empty values
if (is_null($arrFields[$upperfname]) || $arrFields[$upperfname] === $zthis->null2null) {
$values .= "null, ";
} else {
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq);
}
break;
} // switch
/**/
} else {
//we do this so each driver can customize the sql for
//DB specific column types.
//Oracle needs BLOB types to be handled with a returning clause
//postgres has special needs as well
$values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
$arrFields, $magicq);
}
if ($bad) continue;
// Set the counter for the number of fields that will be inserted.
$fieldInsertedCount++;
// Get the name of the fields to insert
$fields .= $fnameq . ", ";
}
}
// If there were any inserted fields then build the rest of the insert query.
if ($fieldInsertedCount <= 0) return false;
// Get the table name from the existing query.
if (!$tableName) {
if (!empty($rs->tableName)) $tableName = $rs->tableName;
else if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
$tableName = $tableName[1];
else
return false;
}
// Strip off the comma and space on the end of both the fields
// and their values.
$fields = substr($fields, 0, -2);
$values = substr($values, 0, -2);
// Append the fields and their values to the insert query.
return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
}
/**
* This private method is used to help construct
* the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
* It handles the string construction of 1 column -> sql string based on
* the column type. We want to do 'safe' handling of BLOBs
*
* @param string the type of sql we are trying to create
* 'I' or 'U'.
* @param string column data type from the db::MetaType() method
* @param string the column name
* @param array the column value
*
* @return string
*
*/
function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
{
$sql = '';
// Based on the datatype of the field
// Format the value properly for the database
switch($type) {
case 'B':
//in order to handle Blobs correctly, we need
//to do some magic for Oracle
//we need to create a new descriptor to handle
//this properly
if (!empty($zthis->hasReturningInto)) {
if ($action == 'I') {
$sql = 'empty_blob(), ';
} else {
$sql = $fnameq. '=empty_blob(), ';
}
//add the variable to the returning clause array
//so the user can build this later in
//case they want to add more to it
$zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
} else if (empty($arrFields[$fname])){
if ($action == 'I') {
$sql = 'empty_blob(), ';
} else {
$sql = $fnameq. '=empty_blob(), ';
}
} else {
//this is to maintain compatibility
//with older adodb versions.
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
}
break;
case "X":
//we need to do some more magic here for long variables
//to handle these correctly in oracle.
//create a safe bind var name
//to avoid conflicts w/ dupes.
if (!empty($zthis->hasReturningInto)) {
if ($action == 'I') {
$sql = ':xx'.$fname.'xx, ';
} else {
$sql = $fnameq.'=:xx'.$fname.'xx, ';
}
//add the variable to the returning clause array
//so the user can build this later in
//case they want to add more to it
$zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
} else {
//this is to maintain compatibility
//with older adodb versions.
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
}
break;
default:
$sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
break;
}
return $sql;
}
function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
{
if ($recurse) {
switch($zthis->dataProvider) {
case 'postgres':
if ($type == 'L') $type = 'C';
break;
case 'oci8':
return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
}
}
switch($type) {
case "C":
case "X":
case 'B':
$val = $zthis->qstr($arrFields[$fname],$magicq);
break;
case "D":
$val = $zthis->DBDate($arrFields[$fname]);
break;
case "T":
$val = $zthis->DBTimeStamp($arrFields[$fname]);
break;
case "N":
$val = $arrFields[$fname];
if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
break;
case "I":
case "R":
$val = $arrFields[$fname];
if (!is_numeric($val)) $val = (integer) $val;
break;
default:
$val = str_replace(array("'"," ","("),"",$arrFields[$fname]); // basic sql injection defence
if (empty($val)) $val = '0';
break;
}
if ($action == 'I') return $val . ", ";
return $fnameq . "=" . $val . ", ";
}
function _adodb_debug_execute(&$zthis, $sql, $inputarr)
{
$ss = '';
if ($inputarr) {
foreach($inputarr as $kk=>$vv) {
if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
if (is_null($vv)) $ss .= "($kk=>null) ";
else $ss .= "($kk=>'$vv') ";
}
$ss = "[ $ss ]";
}
$sqlTxt = is_array($sql) ? $sql[0] : $sql;
/*str_replace(', ','##1#__^LF',is_array($sql) ? $sql[0] : $sql);
$sqlTxt = str_replace(',',', ',$sqlTxt);
$sqlTxt = str_replace('##1#__^LF', ', ' ,$sqlTxt);
*/
// check if running from browser or command-line
$inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
$dbt = $zthis->databaseType;
if (isset($zthis->dsnType)) $dbt .= '-'.$zthis->dsnType;
if ($inBrowser) {
if ($ss) {
$ss = ''.htmlspecialchars($ss).'';
}
if ($zthis->debug === -1)
ADOConnection::outp( " \n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n \n",false);
else
ADOConnection::outp( "\n($dbt): ".htmlspecialchars($sqlTxt)." $ss\n\n",false);
} else {
ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false);
}
$qID = $zthis->_query($sql,$inputarr);
/*
Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
*/
if ($zthis->databaseType == 'mssql') {
// ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
if($emsg = $zthis->ErrorMsg()) {
if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
}
} else if (!$qID) {
ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
}
if ($zthis->debug === 99) _adodb_backtrace(true,9999,2);
return $qID;
}
# pretty print the debug_backtrace function
function _adodb_backtrace($printOrArr=true,$levels=9999,$skippy=0)
{
if (!function_exists('debug_backtrace')) return '';
$html = (isset($_SERVER['HTTP_USER_AGENT']));
$fmt = ($html) ? " %% line %4d, file: %s" : "%% line %4d, file: %s";
$MAXSTRLEN = 128;
$s = ($html) ? '
' : '';
if (is_array($printOrArr)) $traceArr = $printOrArr;
else $traceArr = debug_backtrace();
array_shift($traceArr);
array_shift($traceArr);
$tabs = sizeof($traceArr)-2;
foreach ($traceArr as $arr) {
if ($skippy) {$skippy -= 1; continue;}
$levels -= 1;
if ($levels < 0) break;
$args = array();
for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' ' : "\t";
$tabs -= 1;
if ($html) $s .= '';
if (isset($arr['class'])) $s .= $arr['class'].'.';
if (isset($arr['args']))
foreach($arr['args'] as $v) {
if (is_null($v)) $args[] = 'null';
else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
else if (is_object($v)) $args[] = 'Object:'.get_class($v);
else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
else {
$v = (string) @$v;
$str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
if (strlen($v) > $MAXSTRLEN) $str .= '...';
$args[] = $str;
}
}
$s .= $arr['function'].'('.implode(', ',$args).')';
$s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
$s .= "\n";
}
if ($html) $s .= '
';
if ($printOrArr) print $s;
return $s;
}
/*
function _adodb_find_from($sql)
{
$sql = str_replace(array("\n","\r"), ' ', $sql);
$charCount = strlen($sql);
$inString = false;
$quote = '';
$parentheseCount = 0;
$prevChars = '';
$nextChars = '';
for($i = 0; $i < $charCount; $i++) {
$char = substr($sql,$i,1);
$prevChars = substr($sql,0,$i);
$nextChars = substr($sql,$i+1);
if((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === false) {
$quote = $char;
$inString = true;
}
elseif((($char == "'" || $char == '"' || $char == '`') && substr($prevChars,-1,1) != '\\') && $inString === true && $quote == $char) {
$quote = "";
$inString = false;
}
elseif($char == "(" && $inString === false)
$parentheseCount++;
elseif($char == ")" && $inString === false && $parentheseCount > 0)
$parentheseCount--;
elseif($parentheseCount <= 0 && $inString === false && $char == " " && strtoupper(substr($prevChars,-5,5)) == " FROM")
return $i;
}
}
*/
?> adodb5/adodb-memcache.lib.inc.php 100666 0 0 6011 10750035616 12110 pconnect($host, $port)) {
$err = 'Can\'t connect to memcache server on: '.$host.':'.$port;
return $false;
}
$rs = $memcache->get($key);
if (!$rs) {
$err = 'Item with such key doesn\'t exists on the memcached server.';
return $false;
}
$tdiff = intval($rs->timeCreated+$timeout - time());
if ($tdiff <= 2) {
switch($tdiff) {
case 2:
if ((rand() & 15) == 0) {
$err = "Timeout 2";
return $false;
}
break;
case 1:
if ((rand() & 3) == 0) {
$err = "Timeout 1";
return $false;
}
break;
default:
$err = "Timeout 0";
return $false;
}
}
return $rs;
}
function putmemcache($key, $rs, $host, $port, $compress, $debug=false)
{
$false = false;
$true = true;
if (!function_exists('memcache_pconnect')) {
if ($debug) ADOConnection::outp(" Memcache module PECL extension not found! \n");
return $false;
}
$memcache = new Memcache;
if (!@$memcache->pconnect($host, $port)) {
if ($debug) ADOConnection::outp(" Can't connect to memcache server on: $host:$port \n");
return $false;
}
$rs->timeCreated = time();
if (!$memcache->set($key, $rs, $compress, 0)) {
if ($debug) ADOConnection::outp(" Failed to save data at the memcached server! \n");
return $false;
}
return $true;
}
function flushmemcache($key=false, $host, $port, $debug=false)
{
if (!function_exists('memcache_pconnect')) {
if ($debug) ADOConnection::outp(" Memcache module PECL extension not found! \n");
return;
}
$memcache = new Memcache;
if (!@$memcache->pconnect($host, $port)) {
if ($debug) ADOConnection::outp(" Can't connect to memcache server on: $host:$port \n");
return;
}
if ($key) {
if (!$memcache->delete($key)) {
if ($debug) ADOConnection::outp("CacheFlush: $key entery doesn't exist on memcached server! \n");
} else {
if ($debug) ADOConnection::outp("CacheFlush: $key entery flushed from memcached server! \n");
}
} else {
if (!$memcache->flush()) {
if ($debug) ADOConnection::outp("CacheFlush: Failure flushing all enteries from memcached server! \n");
} else {
if ($debug) ADOConnection::outp("CacheFlush: All enteries flushed from memcached server! \n");
}
}
return;
}
?>
adodb5/adodb-pager.inc.php 100666 0 0 17664 10750035616 10737 implemented Render_PageLinks().
Please note, this class is entirely unsupported,
and no free support requests except for bug reports
will be entertained by the author.
*/
class ADODB_Pager {
var $id; // unique id for pager (defaults to 'adodb')
var $db; // ADODB connection object
var $sql; // sql used
var $rs; // recordset generated
var $curr_page; // current page number before Render() called, calculated in constructor
var $rows; // number of rows per page
var $linksPerPage=10; // number of links per page in navigation bar
var $showPageLinks;
var $gridAttributes = 'width=100% border=1 bgcolor=white';
// Localize text strings here
var $first = '|<';
var $prev = '<<';
var $next = '>>';
var $last = '>|';
var $moreLinks = '...';
var $startLinks = '...';
var $gridHeader = false;
var $htmlSpecialChars = true;
var $page = 'Page';
var $linkSelectedColor = 'red';
var $cache = 0; #secs to cache with CachePageExecute()
//----------------------------------------------
// constructor
//
// $db adodb connection object
// $sql sql statement
// $id optional id to identify which pager,
// if you have multiple on 1 page.
// $id should be only be [a-z0-9]*
//
function ADODB_Pager(&$db,$sql,$id = 'adodb', $showPageLinks = false)
{
global $PHP_SELF;
$curr_page = $id.'_curr_page';
if (empty($PHP_SELF)) $PHP_SELF = htmlspecialchars($_SERVER['PHP_SELF']); // htmlspecialchars() to prevent XSS attacks
$this->sql = $sql;
$this->id = $id;
$this->db = $db;
$this->showPageLinks = $showPageLinks;
$next_page = $id.'_next_page';
if (isset($_GET[$next_page])) {
$_SESSION[$curr_page] = (integer) $_GET[$next_page];
}
if (empty($_SESSION[$curr_page])) $_SESSION[$curr_page] = 1; ## at first page
$this->curr_page = $_SESSION[$curr_page];
}
//---------------------------
// Display link to first page
function Render_First($anchor=true)
{
global $PHP_SELF;
if ($anchor) {
?>
first;?>
first ";
}
}
//--------------------------
// Display link to next page
function render_next($anchor=true)
{
global $PHP_SELF;
if ($anchor) {
?>
next;?>
next ";
}
}
//------------------
// Link to last page
//
// for better performance with large recordsets, you can set
// $this->db->pageExecuteCountRows = false, which disables
// last page counting.
function render_last($anchor=true)
{
global $PHP_SELF;
if (!$this->db->pageExecuteCountRows) return;
if ($anchor) {
?>
last;?>
last ";
}
}
//---------------------------------------------------
// original code by "Pablo Costa"
function render_pagelinks()
{
global $PHP_SELF;
$pages = $this->rs->LastPageNo();
$linksperpage = $this->linksPerPage ? $this->linksPerPage : $pages;
for($i=1; $i <= $pages; $i+=$linksperpage)
{
if($this->rs->AbsolutePage() >= $i)
{
$start = $i;
}
}
$numbers = '';
$end = $start+$linksperpage-1;
$link = $this->id . "_next_page";
if($end > $pages) $end = $pages;
if ($this->startLinks && $start > 1) {
$pos = $start - 1;
$numbers .= "$this->startLinks ";
}
for($i=$start; $i <= $end; $i++) {
if ($this->rs->AbsolutePage() == $i)
$numbers .= "linkSelectedColor>$i ";
else
$numbers .= "$i ";
}
if ($this->moreLinks && $end < $pages)
$numbers .= "$this->moreLinks ";
print $numbers . ' ';
}
// Link to previous page
function render_prev($anchor=true)
{
global $PHP_SELF;
if ($anchor) {
?>
prev;?>
prev ";
}
}
//--------------------------------------------------------
// Simply rendering of grid. You should override this for
// better control over the format of the grid
//
// We use output buffering to keep code clean and readable.
function RenderGrid()
{
global $gSQLBlockRows; // used by rs2html to indicate how many rows to display
include_once(ADODB_DIR.'/tohtml.inc.php');
ob_start();
$gSQLBlockRows = $this->rows;
rs2html($this->rs,$this->gridAttributes,$this->gridHeader,$this->htmlSpecialChars);
$s = ob_get_contents();
ob_end_clean();
return $s;
}
//-------------------------------------------------------
// Navigation bar
//
// we use output buffering to keep the code easy to read.
function RenderNav()
{
ob_start();
if (!$this->rs->AtFirstPage()) {
$this->Render_First();
$this->Render_Prev();
} else {
$this->Render_First(false);
$this->Render_Prev(false);
}
if ($this->showPageLinks){
$this->Render_PageLinks();
}
if (!$this->rs->AtLastPage()) {
$this->Render_Next();
$this->Render_Last();
} else {
$this->Render_Next(false);
$this->Render_Last(false);
}
$s = ob_get_contents();
ob_end_clean();
return $s;
}
//-------------------
// This is the footer
function RenderPageCount()
{
if (!$this->db->pageExecuteCountRows) return '';
$lastPage = $this->rs->LastPageNo();
if ($lastPage == -1) $lastPage = 1; // check for empty rs.
if ($this->curr_page > $lastPage) $this->curr_page = 1;
return "$this->page ".$this->curr_page."/".$lastPage."";
}
//-----------------------------------
// Call this class to draw everything.
function Render($rows=10)
{
global $ADODB_COUNTRECS;
$this->rows = $rows;
if ($this->db->dataProvider == 'informix') $this->db->cursorType = IFX_SCROLL;
$savec = $ADODB_COUNTRECS;
if ($this->db->pageExecuteCountRows) $ADODB_COUNTRECS = true;
if ($this->cache)
$rs = $this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page);
else
$rs = $this->db->PageExecute($this->sql,$rows,$this->curr_page);
$ADODB_COUNTRECS = $savec;
$this->rs = $rs;
if (!$rs) {
print "
Query failed: $this->sql
";
return;
}
if (!$rs->EOF && (!$rs->AtFirstPage() || !$rs->AtLastPage()))
$header = $this->RenderNav();
else
$header = " ";
$grid = $this->RenderGrid();
$footer = $this->RenderPageCount();
$this->RenderLayout($header,$grid,$footer);
$rs->Close();
$this->rs = false;
}
//------------------------------------------------------
// override this to control overall layout and formating
function RenderLayout($header,$grid,$footer,$attributes='border=1 bgcolor=beige')
{
echo "
",
$header,
"
",
$grid,
"
",
$footer,
"
";
}
}
?> adodb5/adodb-pear.inc.php 100666 0 0 22526 10750035616 10561 |
* and Tomas V.V.Cox . Portions (c)1997-2002 The PHP Group.
*/
/*
We support:
DB_Common
---------
query - returns PEAR_Error on error
limitQuery - return PEAR_Error on error
prepare - does not return PEAR_Error on error
execute - does not return PEAR_Error on error
setFetchMode - supports ASSOC and ORDERED
errorNative
quote
nextID
disconnect
getOne
getAssoc
getRow
getCol
getAll
DB_Result
---------
numRows - returns -1 if not supported
numCols
fetchInto - does not support passing of fetchmode
fetchRows - does not support passing of fetchmode
free
*/
define('ADODB_PEAR',dirname(__FILE__));
include_once "PEAR.php";
include_once ADODB_PEAR."/adodb-errorpear.inc.php";
include_once ADODB_PEAR."/adodb.inc.php";
if (!defined('DB_OK')) {
define("DB_OK", 1);
define("DB_ERROR",-1);
// autoExecute constants
define('DB_AUTOQUERY_INSERT', 1);
define('DB_AUTOQUERY_UPDATE', 2);
/**
* This is a special constant that tells DB the user hasn't specified
* any particular get mode, so the default should be used.
*/
define('DB_FETCHMODE_DEFAULT', 0);
/**
* Column data indexed by numbers, ordered from 0 and up
*/
define('DB_FETCHMODE_ORDERED', 1);
/**
* Column data indexed by column names
*/
define('DB_FETCHMODE_ASSOC', 2);
/* for compatibility */
define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
/**
* these are constants for the tableInfo-function
* they are bitwised or'ed. so if there are more constants to be defined
* in the future, adjust DB_TABLEINFO_FULL accordingly
*/
define('DB_TABLEINFO_ORDER', 1);
define('DB_TABLEINFO_ORDERTABLE', 2);
define('DB_TABLEINFO_FULL', 3);
}
/**
* The main "DB" class is simply a container class with some static
* methods for creating DB objects as well as some utility functions
* common to all parts of DB.
*
*/
class DB
{
/**
* Create a new DB object for the specified database type
*
* @param $type string database type, for example "mysql"
*
* @return object a newly created DB object, or a DB error code on
* error
*/
function factory($type)
{
include_once(ADODB_DIR."/drivers/adodb-$type.inc.php");
$obj = NewADOConnection($type);
if (!is_object($obj)) $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
return $obj;
}
/**
* Create a new DB object and connect to the specified database
*
* @param $dsn mixed "data source name", see the DB::parseDSN
* method for a description of the dsn format. Can also be
* specified as an array of the format returned by DB::parseDSN.
*
* @param $options mixed if boolean (or scalar), tells whether
* this connection should be persistent (for backends that support
* this). This parameter can also be an array of options, see
* DB_common::setOption for more information on connection
* options.
*
* @return object a newly created DB connection object, or a DB
* error object on error
*
* @see DB::parseDSN
* @see DB::isError
*/
function connect($dsn, $options = false)
{
if (is_array($dsn)) {
$dsninfo = $dsn;
} else {
$dsninfo = DB::parseDSN($dsn);
}
switch ($dsninfo["phptype"]) {
case 'pgsql': $type = 'postgres7'; break;
case 'ifx': $type = 'informix9'; break;
default: $type = $dsninfo["phptype"]; break;
}
if (is_array($options) && isset($options["debug"]) &&
$options["debug"] >= 2) {
// expose php errors with sufficient debug level
@include_once("adodb-$type.inc.php");
} else {
@include_once("adodb-$type.inc.php");
}
@$obj = NewADOConnection($type);
if (!is_object($obj)) {
$obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
return $obj;
}
if (is_array($options)) {
foreach($options as $k => $v) {
switch(strtolower($k)) {
case 'persist':
case 'persistent': $persist = $v; break;
#ibase
case 'dialect': $obj->dialect = $v; break;
case 'charset': $obj->charset = $v; break;
case 'buffers': $obj->buffers = $v; break;
#ado
case 'charpage': $obj->charPage = $v; break;
#mysql
case 'clientflags': $obj->clientFlags = $v; break;
}
}
} else {
$persist = false;
}
if (isset($dsninfo['socket'])) $dsninfo['hostspec'] .= ':'.$dsninfo['socket'];
else if (isset($dsninfo['port'])) $dsninfo['hostspec'] .= ':'.$dsninfo['port'];
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) $obj = ADODB_PEAR_Error();
return $obj;
}
/**
* Return the DB API version
*
* @return int the DB API version number
*/
function apiVersion()
{
return 2;
}
/**
* Tell whether a result code from a DB method is an error
*
* @param $value int result code
*
* @return bool whether $value is an error
*/
function isError($value)
{
if (!is_object($value)) return false;
$class = get_class($value);
return $class == 'pear_error' || is_subclass_of($value, 'pear_error') ||
$class == 'db_error' || is_subclass_of($value, 'db_error');
}
/**
* Tell whether a result code from a DB method is a warning.
* Warnings differ from errors in that they are generated by DB,
* and are not fatal.
*
* @param $value mixed result value
*
* @return bool whether $value is a warning
*/
function isWarning($value)
{
return false;
/*
return is_object($value) &&
(get_class( $value ) == "db_warning" ||
is_subclass_of($value, "db_warning"));*/
}
/**
* Parse a data source name
*
* @param $dsn string Data Source Name to be parsed
*
* @return array an associative array with the following keys:
*
* phptype: Database backend used in PHP (mysql, odbc etc.)
* dbsyntax: Database used with regards to SQL syntax etc.
* protocol: Communication protocol to use (tcp, unix etc.)
* hostspec: Host specification (hostname[:port])
* database: Database to use on the DBMS server
* username: User name for login
* password: Password for login
*
* The format of the supplied DSN is in its fullest form:
*
* phptype(dbsyntax)://username:password@protocol+hostspec/database
*
* Most variations are allowed:
*
* phptype://username:password@protocol+hostspec:110//usr/db_file.db
* phptype://username:password@hostspec/database_name
* phptype://username:password@hostspec
* phptype://username@hostspec
* phptype://hostspec/database
* phptype://hostspec
* phptype(dbsyntax)
* phptype
*
* @author Tomas V.V.Cox
*/
function parseDSN($dsn)
{
if (is_array($dsn)) {
return $dsn;
}
$parsed = array(
'phptype' => false,
'dbsyntax' => false,
'protocol' => false,
'hostspec' => false,
'database' => false,
'username' => false,
'password' => false
);
// Find phptype and dbsyntax
if (($pos = strpos($dsn, '://')) !== false) {
$str = substr($dsn, 0, $pos);
$dsn = substr($dsn, $pos + 3);
} else {
$str = $dsn;
$dsn = NULL;
}
// Get phptype and dbsyntax
// $str => phptype(dbsyntax)
if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
$parsed['phptype'] = $arr[1];
$parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
} else {
$parsed['phptype'] = $str;
$parsed['dbsyntax'] = $str;
}
if (empty($dsn)) {
return $parsed;
}
// Get (if found): username and password
// $dsn => username:password@protocol+hostspec/database
if (($at = strpos($dsn,'@')) !== false) {
$str = substr($dsn, 0, $at);
$dsn = substr($dsn, $at + 1);
if (($pos = strpos($str, ':')) !== false) {
$parsed['username'] = urldecode(substr($str, 0, $pos));
$parsed['password'] = urldecode(substr($str, $pos + 1));
} else {
$parsed['username'] = urldecode($str);
}
}
// Find protocol and hostspec
// $dsn => protocol+hostspec/database
if (($pos=strpos($dsn, '/')) !== false) {
$str = substr($dsn, 0, $pos);
$dsn = substr($dsn, $pos + 1);
} else {
$str = $dsn;
$dsn = NULL;
}
// Get protocol + hostspec
// $str => protocol+hostspec
if (($pos=strpos($str, '+')) !== false) {
$parsed['protocol'] = substr($str, 0, $pos);
$parsed['hostspec'] = urldecode(substr($str, $pos + 1));
} else {
$parsed['hostspec'] = urldecode($str);
}
// Get dabase if any
// $dsn => database
if (!empty($dsn)) {
$parsed['database'] = $dsn;
}
return $parsed;
}
/**
* Load a PHP database extension if it is not loaded already.
*
* @access public
*
* @param $name the base name of the extension (without the .so or
* .dll suffix)
*
* @return bool true if the extension was already or successfully
* loaded, false if it could not be loaded
*/
function assertExtension($name)
{
if (!extension_loaded($name)) {
$dlext = (strncmp(PHP_OS,'WIN',3) === 0) ? '.dll' : '.so';
@dl($name . $dlext);
}
if (!extension_loaded($name)) {
return false;
}
return true;
}
}
?> adodb5/adodb-perf.inc.php 100666 0 0 76004 10750035616 10566 = minimum number of secs to run
// returns in K the memory of current process, or 0 if not known
function adodb_getmem()
{
if (function_exists('memory_get_usage'))
return (integer) ((memory_get_usage()+512)/1024);
$pid = getmypid();
if ( strncmp(strtoupper(PHP_OS),'WIN',3)==0) {
$output = array();
exec('tasklist /FI "PID eq ' . $pid. '" /FO LIST', $output);
return substr($output[5], strpos($output[5], ':') + 1);
}
/* Hopefully UNIX */
exec("ps --pid $pid --no-headers -o%mem,size", $output);
if (sizeof($output) == 0) return 0;
$memarr = explode(' ',$output[0]);
if (sizeof($memarr)>=2) return (integer) $memarr[1];
return 0;
}
// avoids localization problems where , is used instead of .
function adodb_round($n,$prec)
{
return number_format($n, $prec, '.', '');
}
/* return microtime value as a float */
function adodb_microtime()
{
$t = microtime();
$t = explode(' ',$t);
return (float)$t[1]+ (float)$t[0];
}
/* sql code timing */
function adodb_log_sql(&$connx,$sql,$inputarr)
{
$perf_table = adodb_perf::table();
$connx->fnExecute = false;
$t0 = microtime();
$rs = $connx->Execute($sql,$inputarr);
$t1 = microtime();
if (!empty($connx->_logsql) && (empty($connx->_logsqlErrors) || !$rs)) {
global $ADODB_LOG_CONN;
if (!empty($ADODB_LOG_CONN)) {
$conn = $ADODB_LOG_CONN;
if ($conn->databaseType != $connx->databaseType)
$prefix = '/*dbx='.$connx->databaseType .'*/ ';
else
$prefix = '';
} else {
$conn = $connx;
$prefix = '';
}
$conn->_logsql = false; // disable logsql error simulation
$dbT = $conn->databaseType;
$a0 = split(' ',$t0);
$a0 = (float)$a0[1]+(float)$a0[0];
$a1 = split(' ',$t1);
$a1 = (float)$a1[1]+(float)$a1[0];
$time = $a1 - $a0;
if (!$rs) {
$errM = $connx->ErrorMsg();
$errN = $connx->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($_SERVER['HTTP_HOST'])) {
$tracer .= ' '.$_SERVER['HTTP_HOST'];
if (isset($_SERVER['PHP_SELF'])) $tracer .= $_SERVER['PHP_SELF'];
} else
if (isset($_SERVER['PHP_SELF'])) $tracer .= ' '.$_SERVER['PHP_SELF'];
//$tracer .= (string) adodb_backtrace(false);
$tracer = (string) substr($tracer,0,500);
if (is_array($inputarr)) {
if (is_array(reset($inputarr))) $params = 'Array sizeof='.sizeof($inputarr);
else {
// Quote string parameters so we can see them in the
// performance stats. This helps spot disabled indexes.
$xar_params = $inputarr;
foreach ($xar_params as $xar_param_key => $xar_param) {
if (gettype($xar_param) == 'string')
$xar_params[$xar_param_key] = '"' . $xar_param . '"';
}
$params = implode(', ', $xar_params);
if (strlen($params) >= 3000) $params = substr($params, 0, 3000);
}
} else {
$params = '';
}
if (is_array($sql)) $sql = $sql[0];
if ($prefix) $sql = $prefix.$sql;
$arr = array('b'=>strlen($sql).'.'.crc32($sql),
'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6));
//var_dump($arr);
$saved = $conn->debug;
$conn->debug = 0;
$d = $conn->sysTimeStamp;
if (empty($d)) $d = date("'Y-m-d H:i:s'");
if ($conn->dataProvider == 'oci8' && $dbT != 'oci8po') {
$isql = "insert into $perf_table values($d,:b,:c,:d,:e,:f)";
} else if ($dbT == 'odbc_mssql' || $dbT == 'informix' || strncmp($dbT,'odbtp',4)==0) {
$timer = $arr['f'];
if ($dbT == 'informix') $sql2 = substr($sql2,0,230);
$sql1 = $conn->qstr($arr['b']);
$sql2 = $conn->qstr($arr['c']);
$params = $conn->qstr($arr['d']);
$tracer = $conn->qstr($arr['e']);
$isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values($d,$sql1,$sql2,$params,$tracer,$timer)";
if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql);
$arr = false;
} else {
if ($dbT == 'db2') $arr['f'] = (float) $arr['f'];
$isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)";
}
global $ADODB_PERF_MIN;
if ($errN != 0 || $time >= $ADODB_PERF_MIN) {
$ok = $conn->Execute($isql,$arr);
} else
$ok = true;
$conn->debug = $saved;
if ($ok) {
$conn->_logsql = true;
} else {
$err2 = $conn->ErrorMsg();
$conn->_logsql = true; // enable logsql error simulation
$perf = NewPerfMonitor($conn);
if ($perf) {
if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr);
} else {
$ok = $conn->Execute("create table $perf_table (
created varchar(50),
sql0 varchar(250),
sql1 varchar(4000),
params varchar(3000),
tracer varchar(500),
timer decimal(16,6))");
}
if (!$ok) {
ADOConnection::outp( "
LOGSQL Insert Failed: $isql $err2
");
$conn->_logsql = false;
}
}
$connx->_errorMsg = $errM;
$connx->_errorCode = $errN;
}
$connx->fnExecute = 'adodb_log_sql';
return $rs;
}
/*
The settings data structure is an associative array that database parameter per element.
Each database parameter element in the array is itself an array consisting of:
0: category code, used to group related db parameters
1: either
a. sql string to retrieve value, eg. "select value from v\$parameter where name='db_block_size'",
b. array holding sql string and field to look for, e.g. array('show variables','table_cache'),
c. a string prefixed by =, then a PHP method of the class is invoked,
e.g. to invoke $this->GetIndexValue(), set this array element to '=GetIndexValue',
2: description of the database parameter
*/
class adodb_perf {
var $conn;
var $color = '#F0F0F0';
var $table = '
';
var $titles = '
Parameter
Value
Description
';
var $warnRatio = 90;
var $tablesSQL = false;
var $cliFormat = "%32s => %s \r\n";
var $sql1 = 'sql1'; // used for casting sql1 to text for mssql
var $explain = true;
var $helpurl = "".$this->Explain($_GET['sql'],$partial)."\n";
}
if (isset($_GET['sql'])) return;
$sql1 = $this->sql1;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
//$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 $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
order by 1 desc",$numsql);
if (isset($savem)) $this->conn->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
$this->conn->fnExecute = $saveE;
if (!$rs) return "
$this->helpurl. ".$this->conn->ErrorMsg()."
";
$s = "
Suspicious SQL
The following SQL have high average execution times
Avg Time
Count
SQL
Max
Min
\n";
$max = $this->maxLength;
while (!$rs->EOF) {
$sql = $rs->fields[1];
$raw = urlencode($sql);
if (strlen($raw)>$max-100) {
$sql2 = substr($sql,0,$max-500);
$raw = urlencode($sql2).'&part='.crc32($sql);
}
$prefix = "";
$suffix = "";
if ($this->explain == false || strlen($prefix)>$max) {
$suffix = ' ... String too long for GET parameter: '.strlen($prefix).'';
$prefix = '';
}
$s .= "
".adodb_round($rs->fields[0],6)."
".$rs->fields[2]."
".$prefix.htmlspecialchars($sql).$suffix."".
"
".$rs->fields[3]."
".$rs->fields[4]."
";
$rs->MoveNext();
}
return $s."
";
}
function CheckMemory()
{
return '';
}
function SuspiciousSQL($numsql=10)
{
return adodb_perf::_SuspiciousSQL($numsql);
}
function ExpensiveSQL($numsql=10)
{
return adodb_perf::_ExpensiveSQL($numsql);
}
/*
This reports the percentage of load on the instance due to the most
expensive few SQL statements. Tuning these statements can often
make huge improvements in overall system performance.
*/
function _ExpensiveSQL($numsql = 10)
{
global $ADODB_FETCH_MODE;
$perf_table = adodb_perf::table();
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
if (isset($_GET['expe']) && isset($_GET['sql'])) {
$partial = !empty($_GET['part']);
echo "".$this->Explain($_GET['sql'],$partial)."\n";
}
if (isset($_GET['sql'])) return;
$sql1 = $this->sql1;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
$rs = $this->conn->SelectLimit(
"select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
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
having count(*)>1
order by 1 desc",$numsql);
if (isset($savem)) $this->conn->SetFetchMode($savem);
$this->conn->fnExecute = $saveE;
$ADODB_FETCH_MODE = $save;
if (!$rs) return "
$this->helpurl. ".$this->conn->ErrorMsg()."
";
$s = "
Expensive SQL
Tuning the following SQL could reduce the server load substantially
*
* @param string table name of the table to optimize
* @param int mode optimization-mode
* ADODB_OPT_HIGH for full optimization
* ADODB_OPT_LOW for CPU-less optimization
* Default is LOW ADODB_OPT_LOW
* @author Markus Staab
* @return Returns true on success and false on error
*/
function OptimizeTables()
{
$args = func_get_args();
$numArgs = func_num_args();
if ( $numArgs == 0) return false;
$mode = ADODB_OPT_LOW;
$lastArg = $args[ $numArgs - 1];
if ( !is_string($lastArg)) {
$mode = $lastArg;
unset( $args[ $numArgs - 1]);
}
foreach( $args as $table) {
$this->optimizeTable( $table, $mode);
}
}
/**
* Reorganise the table-indices/statistics/.. depending on the given mode.
* Default Implementation throws an error.
*
* @param string table name of the table to optimize
* @param int mode optimization-mode
* ADODB_OPT_HIGH for full optimization
* ADODB_OPT_LOW for CPU-less optimization
* Default is LOW ADODB_OPT_LOW
* @author Markus Staab
* @return Returns true on success and false on error
*/
function OptimizeTable( $table, $mode = ADODB_OPT_LOW)
{
ADOConnection::outp( sprintf( "
%s: '%s' not implemented for driver '%s'
", __CLASS__, __FUNCTION__, $this->conn->databaseType));
return false;
}
/**
* Reorganise current database.
* Default implementation loops over all MetaTables() and
* optimize each using optmizeTable()
*
* @author Markus Staab
* @return Returns true on success and false on error
*/
function optimizeDatabase()
{
$conn = $this->conn;
if ( !$conn) return false;
$tables = $conn->MetaTables( 'TABLES');
if ( !$tables ) return false;
foreach( $tables as $table) {
if ( !$this->optimizeTable( $table)) {
return false;
}
}
return true;
}
// end hack
}
?> adodb5/adodb-php4.inc.php 100666 0 0 501 10750035616 10432