mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-28 19:03:14 +01:00
imported version 4.51 of ADOdb
This commit is contained in:
parent
3e3075e913
commit
0d70830fc3
304
phpgwapi/inc/adodb/adodb-csvlib.inc.php
Normal file
304
phpgwapi/inc/adodb/adodb-csvlib.inc.php
Normal file
@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
global $ADODB_INCLUDED_CSV;
|
||||
$ADODB_INCLUDED_CSV = 1;
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for CSV serialization. This is used by the csv/proxy driver and is the
|
||||
CacheExecute() serialization format.
|
||||
|
||||
==== NOTE ====
|
||||
Format documented at http://php.weblogs.com/ADODB_CSV
|
||||
==============
|
||||
*/
|
||||
|
||||
/**
|
||||
* convert a recordset into special format
|
||||
*
|
||||
* @param rs the recordset
|
||||
*
|
||||
* @return the CSV formated data
|
||||
*/
|
||||
function _rs2serialize(&$rs,$conn=false,$sql='')
|
||||
{
|
||||
$max = ($rs) ? $rs->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;
|
||||
}
|
||||
|
||||
$rs =& new ADORecordSet_array();
|
||||
$rs->InitArrayFields($rows,$flds);
|
||||
return $line.serialize($rs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$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->fields = array();
|
||||
$rs->timeCreated = $meta[1];
|
||||
$rs =& new ADORecordSet($val=true);
|
||||
$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--!<p>';
|
||||
}
|
||||
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 ADORecordSet_array();
|
||||
$rs->timeCreated = $ttl;
|
||||
$rs->InitArrayFields($arr,$flds);
|
||||
return $rs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save a file $filename and its $contents (normally for caching) with file locking
|
||||
*/
|
||||
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!
|
||||
$tmpname = $filename.uniqid($mtime).getmypid();
|
||||
if (!($fd = fopen($tmpname,'a'))) return false;
|
||||
$ok = ftruncate($fd,0);
|
||||
if (!fwrite($fd,$contents)) $ok = false;
|
||||
fclose($fd);
|
||||
chmod($tmpname,0644);
|
||||
// the tricky moment
|
||||
@unlink($filename);
|
||||
if (!@rename($tmpname,$filename)) {
|
||||
unlink($tmpname);
|
||||
$ok = false;
|
||||
}
|
||||
if (!$ok) {
|
||||
if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
if (!($fd = fopen($filename, 'a'))) return false;
|
||||
if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
|
||||
$ok = fwrite( $fd, $contents );
|
||||
fclose($fd);
|
||||
chmod($filename,0644);
|
||||
}else {
|
||||
fclose($fd);
|
||||
if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename<br>\n");
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
?>
|
674
phpgwapi/inc/adodb/adodb-datadict.inc.php
Normal file
674
phpgwapi/inc/adodb/adodb-datadict.inc.php
Normal file
@ -0,0 +1,674 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
DOCUMENTATION:
|
||||
|
||||
See adodb/tests/test-datadict.php for docs and examples.
|
||||
*/
|
||||
|
||||
/*
|
||||
Test script for parser
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
function Lens_ParseTest()
|
||||
{
|
||||
$str = "`zcol ACOL` NUMBER(32,2) DEFAULT 'The \"cow\" (and Jim''s dog) jumps over the moon' PRIMARY, INTI INT AUTO DEFAULT 0";
|
||||
print "<p>$str</p>";
|
||||
$a= Lens_ParseArgs($str);
|
||||
print "<pre>";
|
||||
print_r($a);
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
if (!function_exists('ctype_alnum')) {
|
||||
function ctype_alnum($text) {
|
||||
return preg_match('/^[a-z0-9]*$/i', $text);
|
||||
}
|
||||
}
|
||||
|
||||
//Lens_ParseTest();
|
||||
|
||||
/**
|
||||
Parse arguments, treat "text" (text) and 'text' as quotation marks.
|
||||
To escape, use "" or '' or ))
|
||||
|
||||
Will read in "abc def" sans quotes, as: abc def
|
||||
Same with 'abc def'.
|
||||
However if `abc def`, then will read in as `abc def`
|
||||
|
||||
@param endstmtchar Character that indicates end of statement
|
||||
@param tokenchars Include the following characters in tokens apart from A-Z and 0-9
|
||||
@returns 2 dimensional array containing parsed tokens.
|
||||
*/
|
||||
function Lens_ParseArgs($args,$endstmtchar=',',$tokenchars='_.-')
|
||||
{
|
||||
$pos = 0;
|
||||
$intoken = false;
|
||||
$stmtno = 0;
|
||||
$endquote = false;
|
||||
$tokens = array();
|
||||
$tokens[$stmtno] = array();
|
||||
$max = strlen($args);
|
||||
$quoted = false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
|
||||
class ADODB_DataDict {
|
||||
var $connection;
|
||||
var $debug = false;
|
||||
var $dropTable = 'DROP TABLE %s';
|
||||
var $dropIndex = 'DROP INDEX %s';
|
||||
var $addCol = ' ADD';
|
||||
var $alterCol = ' ALTER COLUMN';
|
||||
var $dropCol = ' DROP COLUMN';
|
||||
var $nameRegex = '\w';
|
||||
var $schema = false;
|
||||
var $serverInfo = array();
|
||||
var $autoIncrement = false;
|
||||
var $dataProvider;
|
||||
var $blobSize = 100; /// any varchar/char field this size or greater is treated as a blob
|
||||
/// in other words, we use a text area for editting.
|
||||
|
||||
function GetCommentSQL($table,$col)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function SetCommentSQL($table,$col,$cmt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function &MetaTables()
|
||||
{
|
||||
return $this->connection->MetaTables();
|
||||
}
|
||||
|
||||
function &MetaColumns($tab, $upper=true, $schema=false)
|
||||
{
|
||||
return $this->connection->MetaColumns($this->TableName($tab), $upper, $schema);
|
||||
}
|
||||
|
||||
function &MetaPrimaryKeys($tab,$owner=false,$intkey=false)
|
||||
{
|
||||
return $this->connection->MetaPrimaryKeys($this->TableName($tab), $owner, $intkey);
|
||||
}
|
||||
|
||||
function &MetaIndexes($table, $primary = false, $owner = false)
|
||||
{
|
||||
return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
|
||||
}
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
return ADORecordSet::MetaType($t,$len,$fieldobj);
|
||||
}
|
||||
|
||||
function NameQuote($name = NULL)
|
||||
{
|
||||
if (!is_string($name)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$name = trim($name);
|
||||
|
||||
if ( !is_object($this->connection) ) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
$quote = $this->connection->nameQuote;
|
||||
|
||||
// if name is of the form `name`, quote it
|
||||
if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
|
||||
return $quote . $matches[1] . $quote;
|
||||
}
|
||||
|
||||
// if name contains special characters, quote it
|
||||
if ( !preg_match('/^[' . $this->nameRegex . ']+$/', $name) ) {
|
||||
return $quote . $name . $quote;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
function TableName($name)
|
||||
{
|
||||
if ( $this->schema ) {
|
||||
return $this->NameQuote($this->schema) .'.'. $this->NameQuote($name);
|
||||
}
|
||||
return $this->NameQuote($name);
|
||||
}
|
||||
|
||||
// Executes the sql array returned by GetTableSQL and GetIndexSQL
|
||||
function ExecuteSQLArray($sql, $continueOnError = true)
|
||||
{
|
||||
$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) {
|
||||
$flds[$key] = $this->NameQuote($fld);
|
||||
}
|
||||
|
||||
return $this->_IndexSQL($this->NameQuote($idxname), $this->TableName($tabname), $flds, $this->_Options($idxoptions));
|
||||
}
|
||||
|
||||
function DropIndexSQL ($idxname, $tabname = NULL)
|
||||
{
|
||||
return array(sprintf($this->dropIndex, $this->NameQuote($idxname), $this->TableName($tabname)));
|
||||
}
|
||||
|
||||
function SetSchema($schema)
|
||||
{
|
||||
$this->schema = $schema;
|
||||
}
|
||||
|
||||
function AddColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$sql = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' ';
|
||||
foreach($lines as $v) {
|
||||
$sql[] = $alter . $v;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$sql = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' ';
|
||||
foreach($lines as $v) {
|
||||
$sql[] = $alter . $v;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
$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)));
|
||||
}
|
||||
|
||||
/*
|
||||
Generate the SQL to create table. Returns an array of sql strings.
|
||||
*/
|
||||
function CreateTableSQL($tabname, $flds, $tableoptions=false)
|
||||
{
|
||||
if (!$tableoptions) $tableoptions = array();
|
||||
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
|
||||
$taboptions = $this->_Options($tableoptions);
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$sql = $this->_TableSQL($tabname,$lines,$pkey,$taboptions);
|
||||
|
||||
$tsql = $this->_Triggers($tabname,$taboptions);
|
||||
foreach($tsql as $s) $sql[] = $s;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _GenFields($flds)
|
||||
{
|
||||
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 'CONSTRAINT':
|
||||
case 'DEFAULT':
|
||||
$hasparam = $token;
|
||||
break;
|
||||
default:
|
||||
if ($hasparam) $f1[$hasparam] = $token;
|
||||
else $f1[] = $token;
|
||||
$hasparam = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$flds[] = $f1;
|
||||
|
||||
}
|
||||
}
|
||||
$this->autoIncrement = false;
|
||||
$lines = array();
|
||||
$pkey = 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;
|
||||
|
||||
//-----------------
|
||||
// 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':
|
||||
case 'PRIMARY': $fprimary = $v; $fnotnull = 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;
|
||||
} //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;
|
||||
|
||||
//--------------------
|
||||
// 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 (strlen($fdefault) && !$fnoquote)
|
||||
if ($ty == 'C' or $ty == 'X' or
|
||||
( substr($fdefault,0,1) != "'" && !is_numeric($fdefault)))
|
||||
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);
|
||||
|
||||
$fname = str_pad($fname,16);
|
||||
$lines[$fid] = $fname.' '.$ftype.$suffix;
|
||||
|
||||
if ($fautoinc) $this->autoIncrement = true;
|
||||
} // foreach $flds
|
||||
|
||||
return array($lines,$pkey);
|
||||
}
|
||||
/*
|
||||
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 ]" <florian.buzin@easywe.de>
|
||||
|
||||
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)
|
||||
{
|
||||
// check table exists
|
||||
$cols = &$this->MetaColumns($tablename);
|
||||
if ( empty($cols)) {
|
||||
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
|
||||
}
|
||||
|
||||
// already exists, alter table instead
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$alter = 'ALTER TABLE ' . $this->TableName($tablename);
|
||||
$sql = array();
|
||||
|
||||
foreach ( $lines as $id => $v ) {
|
||||
if ( isset($cols[$id]) && is_object($cols[$id]) ) {
|
||||
$sql[] = $alter . $this->alterCol . ' ' . $v;
|
||||
} else {
|
||||
$sql[] = $alter . $this->addCol . ' ' . $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
} // class
|
||||
?>
|
79
phpgwapi/inc/adodb/adodb-errorhandler.inc.php
Normal file
79
phpgwapi/inc/adodb/adodb-errorhandler.inc.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* @version V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
* Released under both BSD license and Lesser GPL library license.
|
||||
* Whenever there is any discrepancy between the two licenses,
|
||||
* the BSD license will take precedence.
|
||||
*
|
||||
* Set tabs to 4 for best viewing.
|
||||
*
|
||||
* Latest version is available at http://php.weblogs.com
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
// added Claudio Bustos clbustos#entelchile.net
|
||||
if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR);
|
||||
|
||||
define('ADODB_ERROR_HANDLER','ADODB_Error_Handler');
|
||||
|
||||
/**
|
||||
* Default Error Handler. This will be called with the following params
|
||||
*
|
||||
* @param $dbms the RDBMS you are connecting to
|
||||
* @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
|
||||
* @param $thisConn $current connection object - can be false if no connection object created
|
||||
*/
|
||||
function ADODB_Error_Handler($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection)
|
||||
{
|
||||
if (error_reporting() == 0) return; // obey @ protocol
|
||||
switch($fn) {
|
||||
case 'EXECUTE':
|
||||
$sql = $p1;
|
||||
$inputparams = $p2;
|
||||
|
||||
$s = "$dbms error: [$errno: $errmsg] in $fn(\"$sql\")\n";
|
||||
break;
|
||||
|
||||
case 'PCONNECT':
|
||||
case 'CONNECT':
|
||||
$host = $p1;
|
||||
$database = $p2;
|
||||
|
||||
$s = "$dbms error: [$errno: $errmsg] in $fn($host, '****', '****', $database)\n";
|
||||
break;
|
||||
default:
|
||||
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n";
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Log connection error somewhere
|
||||
* 0 message is sent to PHP's system logger, using the Operating System's system
|
||||
* logging mechanism or a file, depending on what the error_log configuration
|
||||
* directive is set to.
|
||||
* 1 message is sent by email to the address in the destination parameter.
|
||||
* This is the only message type where the fourth parameter, extra_headers is used.
|
||||
* This message type uses the same internal function as mail() does.
|
||||
* 2 message is sent through the PHP debugging connection.
|
||||
* This option is only available if remote debugging has been enabled.
|
||||
* In this case, the destination parameter specifies the host name or IP address
|
||||
* and optionally, port number, of the socket receiving the debug information.
|
||||
* 3 message is appended to the file destination
|
||||
*/
|
||||
if (defined('ADODB_ERROR_LOG_TYPE')) {
|
||||
$t = date('Y-m-d H:i:s');
|
||||
if (defined('ADODB_ERROR_LOG_DEST'))
|
||||
error_log("($t) $s", ADODB_ERROR_LOG_TYPE, ADODB_ERROR_LOG_DEST);
|
||||
else
|
||||
error_log("($t) $s", ADODB_ERROR_LOG_TYPE);
|
||||
}
|
||||
|
||||
|
||||
//print "<p>$s</p>";
|
||||
trigger_error($s,ADODB_ERROR_HANDLER_TYPE);
|
||||
}
|
||||
?>
|
79
phpgwapi/inc/adodb/adodb-exceptions.inc.php
Normal file
79
phpgwapi/inc/adodb/adodb-exceptions.inc.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @version V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
* Released under both BSD license and Lesser GPL library license.
|
||||
* Whenever there is any discrepancy between the two licenses,
|
||||
* the BSD license will take precedence.
|
||||
*
|
||||
* Set tabs to 4 for best viewing.
|
||||
*
|
||||
* Latest version is available at http://php.weblogs.com
|
||||
*
|
||||
* Exception-handling code using PHP5 exceptions (try-catch-throw).
|
||||
*/
|
||||
|
||||
|
||||
if (!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE',E_USER_ERROR);
|
||||
define('ADODB_ERROR_HANDLER','adodb_throw');
|
||||
|
||||
class ADODB_Exception extends Exception {
|
||||
var $dbms;
|
||||
var $fn;
|
||||
var $sql = '';
|
||||
var $params = '';
|
||||
var $host = '';
|
||||
var $database = '';
|
||||
|
||||
function __construct($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
|
||||
{
|
||||
switch($fn) {
|
||||
case 'EXECUTE':
|
||||
$this->sql = $p1;
|
||||
$this->params = $p2;
|
||||
$s = "$dbms error: [$errno: $errmsg] in $fn(\"$p1\")\n";
|
||||
break;
|
||||
|
||||
case 'PCONNECT':
|
||||
case 'CONNECT':
|
||||
$user = $thisConnection->user;
|
||||
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, '$user', '****', $p2)\n";
|
||||
break;
|
||||
default:
|
||||
$s = "$dbms error: [$errno: $errmsg] in $fn($p1, $p2)\n";
|
||||
break;
|
||||
}
|
||||
|
||||
$this->dbms = $dbms;
|
||||
$this->host = $thisConnection->host;
|
||||
$this->database = $thisConnection->database;
|
||||
$this->fn = $fn;
|
||||
$this->msg = $errmsg;
|
||||
|
||||
if (!is_numeric($errno)) $errno = -1;
|
||||
parent::__construct($s,$errno);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Error Handler. This will be called with the following params
|
||||
*
|
||||
* @param $dbms the RDBMS you are connecting to
|
||||
* @param $fn the name of the calling function (in uppercase)
|
||||
* @param $errno the native error number from the database
|
||||
* @param $errmsg the native error msg from the database
|
||||
* @param $p1 $fn specific parameter - see below
|
||||
* @param $P2 $fn specific parameter - see below
|
||||
*/
|
||||
|
||||
function adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
|
||||
{
|
||||
global $ADODB_EXCEPTION;
|
||||
|
||||
if (is_string($ADODB_EXCEPTION)) $errfn = $ADODB_EXCEPTION;
|
||||
else $errfn = 'ADODB_EXCEPTION';
|
||||
throw new $errfn($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection);
|
||||
}
|
||||
|
||||
|
||||
?>
|
83
phpgwapi/inc/adodb/adodb-iterator.inc.php
Normal file
83
phpgwapi/inc/adodb/adodb-iterator.inc.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4.
|
||||
|
||||
Declares the ADODB Base Class for PHP5 "ADODB_BASE_RS", and supports iteration with
|
||||
the ADODB_Iterator class.
|
||||
|
||||
$rs = $db->Execute("select * from adoxyz");
|
||||
foreach($rs as $k => $v) {
|
||||
echo $k; print_r($v); echo "<br>";
|
||||
}
|
||||
|
||||
|
||||
Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2
|
||||
*/
|
||||
|
||||
|
||||
class ADODB_Iterator implements Iterator {
|
||||
|
||||
private $rs;
|
||||
|
||||
function __construct($rs)
|
||||
{
|
||||
$this->rs = $rs;
|
||||
}
|
||||
function rewind()
|
||||
{
|
||||
$this->rs->MoveFirst();
|
||||
}
|
||||
|
||||
function valid()
|
||||
{
|
||||
return !$this->rs->EOF;
|
||||
}
|
||||
|
||||
function key()
|
||||
{
|
||||
return $this->rs->_currentRow;
|
||||
}
|
||||
|
||||
function current()
|
||||
{
|
||||
return $this->rs->fields;
|
||||
}
|
||||
|
||||
function next()
|
||||
{
|
||||
$this->rs->MoveNext();
|
||||
}
|
||||
|
||||
function __call($func, $params)
|
||||
{
|
||||
return call_user_func_array(array($this->rs, $func), $params);
|
||||
}
|
||||
|
||||
|
||||
function hasMore()
|
||||
{
|
||||
return !$this->rs->EOF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ADODB_BASE_RS implements IteratorAggregate {
|
||||
function getIterator() {
|
||||
return new ADODB_Iterator($this);
|
||||
}
|
||||
|
||||
function __toString()
|
||||
{
|
||||
include_once(ADODB_DIR.'/toexport.inc.php');
|
||||
return _adodb_export($this,',',',',false,true);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
805
phpgwapi/inc/adodb/adodb-lib.inc.php
Normal file
805
phpgwapi/inc/adodb/adodb-lib.inc.php
Normal file
@ -0,0 +1,805 @@
|
||||
<?php
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
global $ADODB_INCLUDED_LIB;
|
||||
$ADODB_INCLUDED_LIB = 1;
|
||||
|
||||
/*
|
||||
@version V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim\@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Less commonly used functions are placed here to reduce size of adodb.inc.php.
|
||||
*/
|
||||
|
||||
|
||||
// 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)) {
|
||||
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 ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
|
||||
$v = $zthis->qstr($v);
|
||||
$fieldArray[$k] = $v;
|
||||
}
|
||||
if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
|
||||
|
||||
if ($first) {
|
||||
$first = false;
|
||||
$uSet = "$k=$v";
|
||||
} else
|
||||
$uSet .= ",$k=$v";
|
||||
}
|
||||
|
||||
$where = false;
|
||||
foreach ($keyCol as $v) {
|
||||
if ($where) $where .= " and $v=$fieldArray[$v]";
|
||||
else $where = "$v=$fieldArray[$v]";
|
||||
}
|
||||
|
||||
if ($uSet && $where) {
|
||||
$update = "UPDATE $table SET $uSet WHERE $where";
|
||||
|
||||
$rs = $zthis->_Execute($update);
|
||||
if ($rs) {
|
||||
if ($zthis->poorAffectedRows) {
|
||||
/*
|
||||
The Select count(*) wipes out any errors that the update would have returned.
|
||||
http://phplens.com/lens/lensforum/msgs.php?id=5696
|
||||
*/
|
||||
if ($zthis->ErrorNo()<>0) return 0;
|
||||
|
||||
# affected_rows == 0 if update field values identical to old values
|
||||
# for mysql - which is silly.
|
||||
|
||||
$cnt = $zthis->GetOne("select count(*) from $table where $where");
|
||||
if ($cnt > 0) return 1; // record already exists
|
||||
} else {
|
||||
|
||||
if (($zthis->Affected_Rows()>0)) return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// print "<p>Error=".$this->ErrorNo().'<p>';
|
||||
$first = true;
|
||||
foreach($fieldArray as $k => $v) {
|
||||
if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
|
||||
|
||||
if ($first) {
|
||||
$first = false;
|
||||
$iCols = "$k";
|
||||
$iVals = "$v";
|
||||
} else {
|
||||
$iCols .= ",$k";
|
||||
$iVals .= ",$v";
|
||||
}
|
||||
}
|
||||
$insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
|
||||
$rs = $zthis->_Execute($insert);
|
||||
return ($rs) ? 2 : 0;
|
||||
}
|
||||
|
||||
// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
|
||||
function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
|
||||
$size=0, $selectAttr='',$compareFields0=true)
|
||||
{
|
||||
$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 = "<select name=\"$name\"$attr $selectAttr>";
|
||||
if ($blank1stItem)
|
||||
if (is_string($blank1stItem)) {
|
||||
$barr = explode(':',$blank1stItem);
|
||||
if (sizeof($barr) == 1) $barr[] = '';
|
||||
$s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
|
||||
} else $s .= "\n<option></option>";
|
||||
|
||||
if ($zthis->FieldCount() > 1) $hasvalue=true;
|
||||
else $compareFields0 = true;
|
||||
|
||||
$value = '';
|
||||
while(!$zthis->EOF) {
|
||||
$zval = rtrim(reset($zthis->fields));
|
||||
if (sizeof($zthis->fields) > 1) {
|
||||
if (isset($zthis->fields[1]))
|
||||
$zval2 = rtrim($zthis->fields[1]);
|
||||
else
|
||||
$zval2 = rtrim(next($zthis->fields));
|
||||
}
|
||||
$selected = ($compareFields0) ? $zval : $zval2;
|
||||
|
||||
if ($blank1stItem && $zval=="") {
|
||||
$zthis->MoveNext();
|
||||
continue;
|
||||
}
|
||||
if ($hasvalue)
|
||||
$value = " value='".htmlspecialchars($zval2)."'";
|
||||
|
||||
if (is_array($defstr)) {
|
||||
|
||||
if (in_array($selected,$defstr))
|
||||
$s .= "<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
|
||||
else
|
||||
$s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
|
||||
}
|
||||
else {
|
||||
if (strcasecmp($selected,$defstr)==0)
|
||||
$s .= "<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
|
||||
else
|
||||
$s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
|
||||
}
|
||||
$zthis->MoveNext();
|
||||
} // while
|
||||
|
||||
return $s ."\n</select>\n";
|
||||
}
|
||||
|
||||
/*
|
||||
Count the number of records this sql statement will return by using
|
||||
query rewriting techniques...
|
||||
|
||||
Does not work with UNIONs.
|
||||
*/
|
||||
function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
|
||||
{
|
||||
$qryRecs = 0;
|
||||
|
||||
if (preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || preg_match('/\s+GROUP\s+BY\s+/is',$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') {
|
||||
|
||||
$rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
|
||||
$rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
|
||||
|
||||
} else if ( $zthis->databaseType == 'postgres' || $zthis->databaseType == 'postgres7') {
|
||||
|
||||
$info = $zthis->ServerInfo();
|
||||
if (substr($info['version'],0,3) >= 7.1) { // good till version 999
|
||||
$rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
|
||||
$rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
|
||||
}
|
||||
}
|
||||
} 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!
|
||||
$rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql);
|
||||
}
|
||||
|
||||
if (isset($rewritesql) && $rewritesql != $sql) {
|
||||
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);
|
||||
|
||||
$rstest = &$zthis->_Execute($rewritesql,$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" <conyg@fx.ro>
|
||||
|
||||
This code will 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;
|
||||
}
|
||||
|
||||
// Iván 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,$forcenulls=false)
|
||||
{
|
||||
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,$forcenulls)) {
|
||||
|
||||
// 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);
|
||||
|
||||
// is_null requires php 4.0.4
|
||||
if (($forcenulls && is_null($arrFields[$upperfname])) ||
|
||||
$arrFields[$upperfname] === 'null') {
|
||||
$setFields .= $field->name . " = null, ";
|
||||
} else {
|
||||
if ($type == 'null') {
|
||||
$type = 'C';
|
||||
}
|
||||
|
||||
if (strpos($upperfname,' ') !== false)
|
||||
$fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
|
||||
else
|
||||
$fnameq = $upperfname;
|
||||
|
||||
//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.
|
||||
preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
|
||||
|
||||
// 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) {
|
||||
if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
|
||||
else preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard);
|
||||
} else
|
||||
$whereClause = array(false,false);
|
||||
|
||||
if ($discard)
|
||||
$whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
|
||||
|
||||
$sql = 'UPDATE '.$tableName[1].' 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,$forcenulls=false)
|
||||
{
|
||||
if (!$forcenulls) {
|
||||
// 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,$forcenulls=false)
|
||||
{
|
||||
$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;
|
||||
|
||||
$columns = $zthis->MetaColumns( $tableName );
|
||||
} else if (is_subclass_of($rs, 'adorecordset')) {
|
||||
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
|
||||
$columns[] = $rs->FetchField($i);
|
||||
$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,$forcenulls)) {
|
||||
|
||||
// Set the counter for the number of fields that will be inserted.
|
||||
$fieldInsertedCount++;
|
||||
|
||||
if (strpos($upperfname,' ') !== false)
|
||||
$fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
|
||||
else
|
||||
$fnameq = $upperfname;
|
||||
|
||||
|
||||
// Get the name of the fields to insert
|
||||
$fields .= $fnameq . ", ";
|
||||
|
||||
$type = $recordSet->MetaType($field->type);
|
||||
|
||||
if (($forcenulls && is_null($arrFields[$upperfname])) ||
|
||||
$arrFields[$upperfname] === 'null') {
|
||||
$values .= "null, ";
|
||||
} 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 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 (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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$sql = '';
|
||||
|
||||
switch($type) {
|
||||
case "C":
|
||||
case "X":
|
||||
case 'B':
|
||||
if ($action == 'I') {
|
||||
$sql = $zthis->qstr($arrFields[$fname],$magicq) . ", ";
|
||||
} else {
|
||||
$sql .= $fnameq . "=" . $zthis->qstr($arrFields[$fname],$magicq) . ", ";
|
||||
}
|
||||
break;
|
||||
|
||||
case "D":
|
||||
if ($action == 'I') {
|
||||
$sql = $zthis->DBDate($arrFields[$fname]) . ", ";
|
||||
} else {
|
||||
$sql .= $fnameq . "=" . $zthis->DBDate($arrFields[$fname]) . ", ";
|
||||
}
|
||||
break;
|
||||
|
||||
case "T":
|
||||
if ($action == 'I') {
|
||||
$sql = $zthis->DBTimeStamp($arrFields[$fname]) . ", ";
|
||||
} else {
|
||||
$sql .= $fnameq . "=" . $zthis->DBTimeStamp($arrFields[$fname]) . ", ";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$val = $arrFields[$fname];
|
||||
if (empty($val)) $val = '0';
|
||||
|
||||
|
||||
if ($action == 'I') {
|
||||
$sql .= $val . ", ";
|
||||
} else {
|
||||
$sql .= $fnameq . "=" . $val . ", ";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function _adodb_debug_execute(&$zthis, $sql, $inputarr)
|
||||
{
|
||||
global $HTTP_SERVER_VARS;
|
||||
|
||||
$ss = '';
|
||||
if ($inputarr) {
|
||||
foreach($inputarr as $kk=>$vv) {
|
||||
if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
|
||||
$ss .= "($kk=>'$vv') ";
|
||||
}
|
||||
$ss = "[ $ss ]";
|
||||
}
|
||||
$sqlTxt = str_replace(',',', ',is_array($sql) ? $sql[0] : $sql);
|
||||
|
||||
// check if running from browser or command-line
|
||||
$inBrowser = isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']);
|
||||
|
||||
if ($inBrowser) {
|
||||
$ss = htmlspecialchars($ss);
|
||||
if ($zthis->debug === -1)
|
||||
ADOConnection::outp( "<br>\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." <code>$ss</code>\n<br>\n",false);
|
||||
else
|
||||
ADOConnection::outp( "<hr>\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." <code>$ss</code>\n<hr>\n",false);
|
||||
} else {
|
||||
ADOConnection::outp("-----\n($zthis->databaseType): ".$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());
|
||||
}
|
||||
|
||||
return $qID;
|
||||
}
|
||||
|
||||
|
||||
function _adodb_backtrace($printOrArr=true,$levels=9999)
|
||||
{
|
||||
if (PHPVERSION() < 4.3) return '';
|
||||
|
||||
$html = (isset($_SERVER['HTTP_USER_AGENT']));
|
||||
$fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
|
||||
|
||||
$MAXSTRLEN = 64;
|
||||
|
||||
$s = ($html) ? '<pre align=left>' : '';
|
||||
|
||||
if (is_array($printOrArr)) $traceArr = $printOrArr;
|
||||
else $traceArr = debug_backtrace();
|
||||
array_shift($traceArr);
|
||||
array_shift($traceArr);
|
||||
$tabs = sizeof($traceArr)-2;
|
||||
|
||||
foreach ($traceArr as $arr) {
|
||||
$levels -= 1;
|
||||
if ($levels < 0) break;
|
||||
|
||||
$args = array();
|
||||
for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' ' : "\t";
|
||||
$tabs -= 1;
|
||||
if ($html) $s .= '<font face="Courier New,Courier">';
|
||||
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 .= '</pre>';
|
||||
if ($printOrArr) print $s;
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
?>
|
287
phpgwapi/inc/adodb/adodb-pager.inc.php
Normal file
287
phpgwapi/inc/adodb/adodb-pager.inc.php
Normal file
@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
This class provides recordset pagination with
|
||||
First/Prev/Next/Last links.
|
||||
|
||||
Feel free to modify this class for your own use as
|
||||
it is very basic. To learn how to use it, see the
|
||||
example in adodb/tests/testpaging.php.
|
||||
|
||||
"Pablo Costa" <pablo@cbsp.com.br> 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 = '<code>|<</code>';
|
||||
var $prev = '<code><<</code>';
|
||||
var $next = '<code>>></code>';
|
||||
var $last = '<code>>|</code>';
|
||||
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 $HTTP_SERVER_VARS,$PHP_SELF,$HTTP_SESSION_VARS,$HTTP_GET_VARS;
|
||||
|
||||
$curr_page = $id.'_curr_page';
|
||||
if (empty($PHP_SELF)) $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
|
||||
|
||||
$this->sql = $sql;
|
||||
$this->id = $id;
|
||||
$this->db = $db;
|
||||
$this->showPageLinks = $showPageLinks;
|
||||
|
||||
$next_page = $id.'_next_page';
|
||||
|
||||
if (isset($HTTP_GET_VARS[$next_page])) {
|
||||
$HTTP_SESSION_VARS[$curr_page] = $HTTP_GET_VARS[$next_page];
|
||||
}
|
||||
if (empty($HTTP_SESSION_VARS[$curr_page])) $HTTP_SESSION_VARS[$curr_page] = 1; ## at first page
|
||||
|
||||
$this->curr_page = $HTTP_SESSION_VARS[$curr_page];
|
||||
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
// Display link to first page
|
||||
function Render_First($anchor=true)
|
||||
{
|
||||
global $PHP_SELF;
|
||||
if ($anchor) {
|
||||
?>
|
||||
<a href="<?php echo $PHP_SELF,'?',$this->id;?>_next_page=1"><?php echo $this->first;?></a>
|
||||
<?php
|
||||
} else {
|
||||
print "$this->first ";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------
|
||||
// Display link to next page
|
||||
function render_next($anchor=true)
|
||||
{
|
||||
global $PHP_SELF;
|
||||
|
||||
if ($anchor) {
|
||||
?>
|
||||
<a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->AbsolutePage() + 1 ?>"><?php echo $this->next;?></a>
|
||||
<?php
|
||||
} else {
|
||||
print "$this->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) {
|
||||
?>
|
||||
<a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->LastPageNo() ?>"><?php echo $this->last;?></a>
|
||||
<?php
|
||||
} else {
|
||||
print "$this->last ";
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
// original code by "Pablo Costa" <pablo@cbsp.com.br>
|
||||
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 .= "<a href=$PHP_SELF?$link=$pos>$this->startLinks</a> ";
|
||||
}
|
||||
|
||||
for($i=$start; $i <= $end; $i++) {
|
||||
if ($this->rs->AbsolutePage() == $i)
|
||||
$numbers .= "<font color=$this->linkSelectedColor><b>$i</b></font> ";
|
||||
else
|
||||
$numbers .= "<a href=$PHP_SELF?$link=$i>$i</a> ";
|
||||
|
||||
}
|
||||
if ($this->moreLinks && $end < $pages)
|
||||
$numbers .= "<a href=$PHP_SELF?$link=$i>$this->moreLinks</a> ";
|
||||
print $numbers . ' ';
|
||||
}
|
||||
// Link to previous page
|
||||
function render_prev($anchor=true)
|
||||
{
|
||||
global $PHP_SELF;
|
||||
if ($anchor) {
|
||||
?>
|
||||
<a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->AbsolutePage() - 1 ?>"><?php echo $this->prev;?></a>
|
||||
<?php
|
||||
} else {
|
||||
print "$this->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 "<font size=-1>$this->page ".$this->curr_page."/".$lastPage."</font>";
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
// Call this class to draw everything.
|
||||
function Render($rows=10)
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
|
||||
$this->rows = $rows;
|
||||
|
||||
$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 "<h3>Query failed: $this->sql</h3>";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$rs->EOF && (!$rs->AtFirstPage() || !$rs->AtLastPage()))
|
||||
$header = $this->RenderNav();
|
||||
else
|
||||
$header = " ";
|
||||
|
||||
$grid = $this->RenderGrid();
|
||||
$footer = $this->RenderPageCount();
|
||||
$rs->Close();
|
||||
$this->rs = false;
|
||||
|
||||
$this->RenderLayout($header,$grid,$footer);
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// override this to control overall layout and formating
|
||||
function RenderLayout($header,$grid,$footer,$attributes='border=1 bgcolor=beige')
|
||||
{
|
||||
echo "<table ".$attributes."><tr><td>",
|
||||
$header,
|
||||
"</td></tr><tr><td>",
|
||||
$grid,
|
||||
"</td></tr><tr><td>",
|
||||
$footer,
|
||||
"</td></tr></table>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
909
phpgwapi/inc/adodb/adodb-perf.inc.php
Normal file
909
phpgwapi/inc/adodb/adodb-perf.inc.php
Normal file
@ -0,0 +1,909 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for basic performance monitoring and tuning.
|
||||
|
||||
My apologies if you see code mixed with presentation. The presentation suits
|
||||
my needs. If you want to separate code from presentation, be my guest. Patches
|
||||
are welcome.
|
||||
|
||||
*/
|
||||
|
||||
if (!defined(ADODB_DIR)) include_once(dirname(__FILE__).'/adodb.inc.php');
|
||||
include_once(ADODB_DIR.'/tohtml.inc.php');
|
||||
|
||||
|
||||
// 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(&$conn,$sql,$inputarr)
|
||||
{
|
||||
global $HTTP_SERVER_VARS;
|
||||
|
||||
$perf_table = adodb_perf::table();
|
||||
$conn->fnExecute = false;
|
||||
$t0 = microtime();
|
||||
$rs =& $conn->Execute($sql,$inputarr);
|
||||
$t1 = microtime();
|
||||
|
||||
if (!empty($conn->_logsql)) {
|
||||
$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 = $conn->ErrorMsg();
|
||||
$errN = $conn->ErrorNo();
|
||||
$conn->lastInsID = 0;
|
||||
$tracer = substr('ERROR: '.htmlspecialchars($errM),0,250);
|
||||
} else {
|
||||
$tracer = '';
|
||||
$errM = '';
|
||||
$errN = 0;
|
||||
$dbg = $conn->debug;
|
||||
$conn->debug = false;
|
||||
if (!is_object($rs) || $rs->dataProvider == 'empty')
|
||||
$conn->_affected = $conn->affected_rows(true);
|
||||
$conn->lastInsID = @$conn->Insert_ID();
|
||||
$conn->debug = $dbg;
|
||||
}
|
||||
if (isset($HTTP_SERVER_VARS['HTTP_HOST'])) {
|
||||
$tracer .= '<br>'.$HTTP_SERVER_VARS['HTTP_HOST'];
|
||||
if (isset($HTTP_SERVER_VARS['PHP_SELF'])) $tracer .= $HTTP_SERVER_VARS['PHP_SELF'];
|
||||
} else
|
||||
if (isset($HTTP_SERVER_VARS['PHP_SELF'])) $tracer .= '<br>'.$HTTP_SERVER_VARS['PHP_SELF'];
|
||||
//$tracer .= (string) adodb_backtrace(false);
|
||||
|
||||
$tracer = substr($tracer,0,500);
|
||||
|
||||
if (is_array($inputarr)) {
|
||||
if (is_array(reset($inputarr))) $params = 'Array sizeof='.sizeof($inputarr);
|
||||
else {
|
||||
$params = '';
|
||||
$params = implode(', ',$inputarr);
|
||||
if (strlen($params) >= 3000) $params = substr($params, 0, 3000);
|
||||
}
|
||||
} else {
|
||||
$params = '';
|
||||
}
|
||||
|
||||
if (is_array($sql)) $sql = $sql[0];
|
||||
$arr = array('b'=>trim(substr($sql,0,230)),
|
||||
'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6));
|
||||
//var_dump($arr);
|
||||
$saved = $conn->debug;
|
||||
$conn->debug = 0;
|
||||
|
||||
if ($conn->dataProvider == 'oci8' && $dbT != 'oci8po') {
|
||||
$isql = "insert into $perf_table values($conn->sysTimeStamp,:b,:c,:d,:e,:f)";
|
||||
} else if ($dbT == 'odbc_mssql' || $dbT == 'informix') {
|
||||
$timer = $arr['f'];
|
||||
if ($dbT == 'informix') $sql2 = substr($sql2,0,230);
|
||||
|
||||
$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($conn->sysTimeStamp,$sql1,$sql2,$params,$tracer,$timer)";
|
||||
if ($dbT == 'informix') $isql = str_replace(chr(10),' ',$isql);
|
||||
$arr = false;
|
||||
} else {
|
||||
$isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $conn->sysTimeStamp,?,?,?,?,?)";
|
||||
}
|
||||
$ok = $conn->Execute($isql,$arr);
|
||||
$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( "<b>LOGSQL Insert Failed</b>: $isql<br>$err2</br>");
|
||||
$conn->_logsql = false;
|
||||
}
|
||||
}
|
||||
$conn->_errorMsg = $errM;
|
||||
$conn->_errorCode = $errN;
|
||||
}
|
||||
$conn->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 = '<table border=1 bgcolor=white>';
|
||||
var $titles = '<tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Description</b></td></tr>';
|
||||
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 = "<a href=http://phplens.com/adodb/reference.functions.fnexecute.and.fncacheexecute.properties.html#logsql>LogSQL help</a>";
|
||||
var $createTableSQL = false;
|
||||
var $maxLength = 2000;
|
||||
|
||||
// Sets the tablename to be used
|
||||
function table($newtable = false)
|
||||
{
|
||||
static $_table;
|
||||
|
||||
if (!empty($newtable)) $_table = $newtable;
|
||||
if (empty($_table)) $_table = 'adodb_logsql';
|
||||
return $_table;
|
||||
}
|
||||
|
||||
// returns array with info to calculate CPU Load
|
||||
function _CPULoad()
|
||||
{
|
||||
/*
|
||||
|
||||
cpu 524152 2662 2515228 336057010
|
||||
cpu0 264339 1408 1257951 168025827
|
||||
cpu1 259813 1254 1257277 168031181
|
||||
page 622307 25475680
|
||||
swap 24 1891
|
||||
intr 890153570 868093576 6 0 4 4 0 6 1 2 0 0 0 124 0 8098760 2 13961053 0 0 0 0 0 0 0 0 0 0 0 0 0 16 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
disk_io: (3,0):(3144904,54369,610378,3090535,50936192) (3,1):(3630212,54097,633016,3576115,50951320)
|
||||
ctxt 66155838
|
||||
btime 1062315585
|
||||
processes 69293
|
||||
|
||||
*/
|
||||
// Algorithm is taken from
|
||||
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/example__obtaining_raw_performance_data.asp
|
||||
if (strncmp(PHP_OS,'WIN',3)==0) {
|
||||
@$c = new COM("WinMgmts:{impersonationLevel=impersonate}!Win32_PerfRawData_PerfOS_Processor.Name='_Total'");
|
||||
if (!$c) return false;
|
||||
|
||||
$info[0] = $c->PercentProcessorTime;
|
||||
$info[1] = 0;
|
||||
$info[2] = 0;
|
||||
$info[3] = $c->TimeStamp_Sys100NS;
|
||||
//print_r($info);
|
||||
return $info;
|
||||
}
|
||||
|
||||
// Algorithm - Steve Blinch (BlitzAffe Online, http://www.blitzaffe.com)
|
||||
$statfile = '/proc/stat';
|
||||
if (!file_exists($statfile)) return false;
|
||||
|
||||
$fd = fopen($statfile,"r");
|
||||
if (!$fd) return false;
|
||||
|
||||
$statinfo = explode("\n",fgets($fd, 1024));
|
||||
fclose($fd);
|
||||
foreach($statinfo as $line) {
|
||||
$info = explode(" ",$line);
|
||||
if($info[0]=="cpu") {
|
||||
array_shift($info); // pop off "cpu"
|
||||
if(!$info[0]) array_shift($info); // pop off blank space (if any)
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/* NOT IMPLEMENTED */
|
||||
function MemInfo()
|
||||
{
|
||||
/*
|
||||
|
||||
total: used: free: shared: buffers: cached:
|
||||
Mem: 1055289344 917299200 137990144 0 165437440 599773184
|
||||
Swap: 2146775040 11055104 2135719936
|
||||
MemTotal: 1030556 kB
|
||||
MemFree: 134756 kB
|
||||
MemShared: 0 kB
|
||||
Buffers: 161560 kB
|
||||
Cached: 581384 kB
|
||||
SwapCached: 4332 kB
|
||||
Active: 494468 kB
|
||||
Inact_dirty: 322856 kB
|
||||
Inact_clean: 24256 kB
|
||||
Inact_target: 168316 kB
|
||||
HighTotal: 131064 kB
|
||||
HighFree: 1024 kB
|
||||
LowTotal: 899492 kB
|
||||
LowFree: 133732 kB
|
||||
SwapTotal: 2096460 kB
|
||||
SwapFree: 2085664 kB
|
||||
Committed_AS: 348732 kB
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Remember that this is client load, not db server load!
|
||||
*/
|
||||
var $_lastLoad;
|
||||
function CPULoad()
|
||||
{
|
||||
$info = $this->_CPULoad();
|
||||
if (!$info) return false;
|
||||
|
||||
if (empty($this->_lastLoad)) {
|
||||
sleep(1);
|
||||
$this->_lastLoad = $info;
|
||||
$info = $this->_CPULoad();
|
||||
}
|
||||
|
||||
$last = $this->_lastLoad;
|
||||
$this->_lastLoad = $info;
|
||||
|
||||
$d_user = $info[0] - $last[0];
|
||||
$d_nice = $info[1] - $last[1];
|
||||
$d_system = $info[2] - $last[2];
|
||||
$d_idle = $info[3] - $last[3];
|
||||
|
||||
//printf("Delta - User: %f Nice: %f System: %f Idle: %f<br>",$d_user,$d_nice,$d_system,$d_idle);
|
||||
|
||||
if (strncmp(PHP_OS,'WIN',3)==0) {
|
||||
if ($d_idle < 1) $d_idle = 1;
|
||||
return 100*(1-$d_user/$d_idle);
|
||||
}else {
|
||||
$total=$d_user+$d_nice+$d_system+$d_idle;
|
||||
if ($total<1) $total=1;
|
||||
return 100*($d_user+$d_nice+$d_system)/$total;
|
||||
}
|
||||
}
|
||||
|
||||
function Tracer($sql)
|
||||
{
|
||||
$perf_table = adodb_perf::table();
|
||||
$saveE = $this->conn->fnExecute;
|
||||
$this->conn->fnExecute = false;
|
||||
|
||||
$sqlq = $this->conn->qstr($sql);
|
||||
$arr = $this->conn->GetArray(
|
||||
"select count(*),tracer
|
||||
from $perf_table where sql1=$sqlq
|
||||
group by tracer
|
||||
order by 1 desc");
|
||||
$s = '';
|
||||
if ($arr) {
|
||||
$s .= '<h3>Scripts Affected</h3>';
|
||||
foreach($arr as $k) {
|
||||
$s .= sprintf("%4d",$k[0]).' '.strip_tags($k[1]).'<br>';
|
||||
}
|
||||
}
|
||||
$this->conn->fnExecute = $saveE;
|
||||
return $s;
|
||||
}
|
||||
|
||||
/*
|
||||
Explain Plan for $sql.
|
||||
If only a snippet of the $sql is passed in, then $partial will hold the crc32 of the
|
||||
actual sql.
|
||||
*/
|
||||
function Explain($sql,$partial=false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function InvalidSQL($numsql = 10)
|
||||
{
|
||||
global $HTTP_GET_VARS;
|
||||
|
||||
if (isset($HTTP_GET_VARS['sql'])) return;
|
||||
$s = '<h3>Invalid SQL</h3>';
|
||||
$saveE = $this->conn->fnExecute;
|
||||
$this->conn->fnExecute = false;
|
||||
$perf_table = adodb_perf::table();
|
||||
$rs =& $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
|
||||
$this->conn->fnExecute = $saveE;
|
||||
if ($rs) {
|
||||
$s .= rs2html($rs,false,false,false,false);
|
||||
} else
|
||||
return "<p>$this->helpurl. ".$this->conn->ErrorMsg()."</p>";
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This script identifies the longest running SQL
|
||||
*/
|
||||
function _SuspiciousSQL($numsql = 10)
|
||||
{
|
||||
global $ADODB_FETCH_MODE,$HTTP_GET_VARS;
|
||||
|
||||
$perf_table = adodb_perf::table();
|
||||
$saveE = $this->conn->fnExecute;
|
||||
$this->conn->fnExecute = false;
|
||||
|
||||
if (isset($HTTP_GET_VARS['exps']) && isset($HTTP_GET_VARS['sql'])) {
|
||||
$partial = !empty($HTTP_GET_VARS['part']);
|
||||
echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
|
||||
}
|
||||
|
||||
if (isset($HTTP_GET_VARS['sql'])) return;
|
||||
$sql1 = $this->sql1;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
//$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);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
$this->conn->fnExecute = $saveE;
|
||||
|
||||
if (!$rs) return "<p>$this->helpurl. ".$this->conn->ErrorMsg()."</p>";
|
||||
$s = "<h3>Suspicious SQL</h3>
|
||||
<font size=1>The following SQL have high average execution times</font><br>
|
||||
<table border=1 bgcolor=white><tr><td><b>Avg Time</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
|
||||
$max = $this->maxLength;
|
||||
while (!$rs->EOF) {
|
||||
$sql = $rs->fields[1];
|
||||
$raw = urlencode($sql);
|
||||
if (strlen($raw)>$max-100) {
|
||||
$sql2 = substr($sql,0,$max-500);
|
||||
$raw = urlencode($sql2).'&part='.crc32($sql);
|
||||
}
|
||||
$prefix = "<a target=sql".rand()." href=\"?hidem=1&exps=1&sql=".$raw."&x#explain\">";
|
||||
$suffix = "</a>";
|
||||
if ($this->explain == false || strlen($prefix)>$max) {
|
||||
$suffix = ' ... <i>String too long for GET parameter: '.strlen($prefix).'</i>';
|
||||
$prefix = '';
|
||||
}
|
||||
$s .= "<tr><td>".adodb_round($rs->fields[0],6)."<td align=right>".$rs->fields[2]."<td><font size=-1>".$prefix.htmlspecialchars($sql).$suffix."</font>".
|
||||
"<td>".$rs->fields[3]."<td>".$rs->fields[4]."</tr>";
|
||||
$rs->MoveNext();
|
||||
}
|
||||
return $s."</table>";
|
||||
|
||||
}
|
||||
|
||||
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 $HTTP_GET_VARS,$ADODB_FETCH_MODE;
|
||||
|
||||
$perf_table = adodb_perf::table();
|
||||
$saveE = $this->conn->fnExecute;
|
||||
$this->conn->fnExecute = false;
|
||||
|
||||
if (isset($HTTP_GET_VARS['expe']) && isset($HTTP_GET_VARS['sql'])) {
|
||||
$partial = !empty($HTTP_GET_VARS['part']);
|
||||
echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
|
||||
}
|
||||
|
||||
if (isset($HTTP_GET_VARS['sql'])) return;
|
||||
|
||||
$sql1 = $this->sql1;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$rs =& $this->conn->SelectLimit(
|
||||
"select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
|
||||
from $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);
|
||||
|
||||
$this->conn->fnExecute = $saveE;
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if (!$rs) return "<p>$this->helpurl. ".$this->conn->ErrorMsg()."</p>";
|
||||
$s = "<h3>Expensive SQL</h3>
|
||||
<font size=1>Tuning the following SQL will reduce the server load substantially</font><br>
|
||||
<table border=1 bgcolor=white><tr><td><b>Load</b><td><b>Count</b><td><b>SQL</b><td><b>Max</b><td><b>Min</b></tr>\n";
|
||||
$max = $this->maxLength;
|
||||
while (!$rs->EOF) {
|
||||
$sql = $rs->fields[1];
|
||||
$raw = urlencode($sql);
|
||||
if (strlen($raw)>$max-100) {
|
||||
$sql2 = substr($sql,0,$max-500);
|
||||
$raw = urlencode($sql2).'&part='.crc32($sql);
|
||||
}
|
||||
$prefix = "<a target=sqle".rand()." href=\"?hidem=1&expe=1&sql=".$raw."&x#explain\">";
|
||||
$suffix = "</a>";
|
||||
if($this->explain == false || strlen($prefix>$max)) {
|
||||
$prefix = '';
|
||||
$suffix = '';
|
||||
}
|
||||
$s .= "<tr><td>".adodb_round($rs->fields[0],6)."<td align=right>".$rs->fields[2]."<td><font size=-1>".$prefix.htmlspecialchars($sql).$suffix."</font>".
|
||||
"<td>".$rs->fields[3]."<td>".$rs->fields[4]."</tr>";
|
||||
$rs->MoveNext();
|
||||
}
|
||||
return $s."</table>";
|
||||
}
|
||||
|
||||
/*
|
||||
Raw function to return parameter value from $settings.
|
||||
*/
|
||||
function DBParameter($param)
|
||||
{
|
||||
if (empty($this->settings[$param])) return false;
|
||||
$sql = $this->settings[$param][1];
|
||||
return $this->_DBParameter($sql);
|
||||
}
|
||||
|
||||
/*
|
||||
Raw function returning array of poll paramters
|
||||
*/
|
||||
function &PollParameters()
|
||||
{
|
||||
$arr[0] = (float)$this->DBParameter('data cache hit ratio');
|
||||
$arr[1] = (float)$this->DBParameter('data reads');
|
||||
$arr[2] = (float)$this->DBParameter('data writes');
|
||||
$arr[3] = (integer) $this->DBParameter('current connections');
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/*
|
||||
Low-level Get Database Parameter
|
||||
*/
|
||||
function _DBParameter($sql)
|
||||
{
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
if (is_array($sql)) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$sql1 = $sql[0];
|
||||
$key = $sql[1];
|
||||
if (sizeof($sql)>2) $pos = $sql[2];
|
||||
else $pos = 1;
|
||||
if (sizeof($sql)>3) $coef = $sql[3];
|
||||
else $coef = false;
|
||||
$ret = false;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$rs = $this->conn->Execute($sql1);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs) {
|
||||
while (!$rs->EOF) {
|
||||
$keyf = reset($rs->fields);
|
||||
if (trim($keyf) == $key) {
|
||||
$ret = $rs->fields[$pos];
|
||||
if ($coef) $ret *= $coef;
|
||||
break;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
}
|
||||
$this->conn->LogSQL($savelog);
|
||||
return $ret;
|
||||
} else {
|
||||
if (strncmp($sql,'=',1) == 0) {
|
||||
$fn = substr($sql,1);
|
||||
return $this->$fn();
|
||||
}
|
||||
$sql = str_replace('$DATABASE',$this->conn->database,$sql);
|
||||
$ret = $this->conn->GetOne($sql);
|
||||
$this->conn->LogSQL($savelog);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Warn if cache ratio falls below threshold. Displayed in "Description" column.
|
||||
*/
|
||||
function WarnCacheRatio($val)
|
||||
{
|
||||
if ($val < $this->warnRatio)
|
||||
return '<font color=red><b>Cache ratio should be at least '.$this->warnRatio.'%</b></font>';
|
||||
else return '';
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
// HIGH LEVEL UI FUNCTIONS
|
||||
/***********************************************************************************************/
|
||||
|
||||
|
||||
function UI($pollsecs=5)
|
||||
{
|
||||
global $HTTP_GET_VARS,$HTTP_SERVER_VARS,$HTTP_POST_VARS;
|
||||
|
||||
$perf_table = adodb_perf::table();
|
||||
$conn = $this->conn;
|
||||
|
||||
$app = $conn->host;
|
||||
if ($conn->host && $conn->database) $app .= ', db=';
|
||||
$app .= $conn->database;
|
||||
|
||||
if ($app) $app .= ', ';
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
$info = $conn->ServerInfo();
|
||||
if (isset($HTTP_GET_VARS['clearsql'])) {
|
||||
$this->conn->Execute("delete from $perf_table");
|
||||
}
|
||||
$this->conn->LogSQL($savelog);
|
||||
|
||||
// magic quotes
|
||||
|
||||
if (isset($HTTP_GET_VARS['sql']) && get_magic_quotes_gpc()) {
|
||||
$_GET['sql'] = $HTTP_GET_VARS['sql'] = str_replace(array("\\'",'\"'),array("'",'"'),$HTTP_GET_VARS['sql']);
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['ADODB_PERF_SQL'])) $nsql = $_SESSION['ADODB_PERF_SQL'] = 10;
|
||||
else $nsql = $_SESSION['ADODB_PERF_SQL'];
|
||||
|
||||
$app .= $info['description'];
|
||||
|
||||
|
||||
if (isset($HTTP_GET_VARS['do'])) $do = $HTTP_GET_VARS['do'];
|
||||
else if (isset($HTTP_POST_VARS['do'])) $do = $HTTP_POST_VARS['do'];
|
||||
else if (isset($HTTP_GET_VARS['sql'])) $do = 'viewsql';
|
||||
else $do = 'stats';
|
||||
|
||||
if (isset($HTTP_GET_VARS['nsql'])) {
|
||||
if ($HTTP_GET_VARS['nsql'] > 0) $nsql = $_SESSION['ADODB_PERF_SQL'] = (integer) $HTTP_GET_VARS['nsql'];
|
||||
}
|
||||
echo "<title>ADOdb Performance Monitor on $app</title><body bgcolor=white>";
|
||||
if ($do == 'viewsql') $form = "<td><form># SQL:<input type=hidden value=viewsql name=do> <input type=text size=4 name=nsql value=$nsql><input type=submit value=Go></td></form>";
|
||||
else $form = "<td> </td>";
|
||||
|
||||
$allowsql = !defined('ADODB_PERF_NO_RUN_SQL');
|
||||
|
||||
if (empty($HTTP_GET_VARS['hidem']))
|
||||
echo "<table border=1 width=100% bgcolor=lightyellow><tr><td colspan=2>
|
||||
<b><a href=http://adodb.sourceforge.net/?perf=1>ADOdb</a> Performance Monitor</b> <font size=1>for $app</font></tr><tr><td>
|
||||
<a href=?do=stats><b>Performance Stats</b></a> <a href=?do=viewsql><b>View SQL</b></a>
|
||||
<a href=?do=tables><b>View Tables</b></a> <a href=?do=poll><b>Poll Stats</b></a>",
|
||||
$allowsql ? ' <a href=?do=dosql><b>Run SQL</b></a>' : '',
|
||||
"$form",
|
||||
"</tr></table>";
|
||||
|
||||
|
||||
switch ($do) {
|
||||
default:
|
||||
case 'stats':
|
||||
echo $this->HealthCheck();
|
||||
//$this->conn->debug=1;
|
||||
echo $this->CheckMemory();
|
||||
break;
|
||||
case 'poll':
|
||||
echo "<iframe width=720 height=80%
|
||||
src=\"{$HTTP_SERVER_VARS['PHP_SELF']}?do=poll2&hidem=1\"></iframe>";
|
||||
break;
|
||||
case 'poll2':
|
||||
echo "<pre>";
|
||||
$this->Poll($pollsecs);
|
||||
break;
|
||||
|
||||
case 'dosql':
|
||||
if (!$allowsql) break;
|
||||
|
||||
$this->DoSQLForm();
|
||||
break;
|
||||
case 'viewsql':
|
||||
if (empty($HTTP_GET_VARS['hidem']))
|
||||
echo " <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
|
||||
echo($this->SuspiciousSQL($nsql));
|
||||
echo($this->ExpensiveSQL($nsql));
|
||||
echo($this->InvalidSQL($nsql));
|
||||
break;
|
||||
case 'tables':
|
||||
echo $this->Tables(); break;
|
||||
}
|
||||
global $ADODB_vers;
|
||||
echo "<p><div align=center><font size=1>$ADODB_vers Sponsored by <a href=http://phplens.com/>phpLens</a></font></div>";
|
||||
}
|
||||
|
||||
/*
|
||||
Runs in infinite loop, returning real-time statistics
|
||||
*/
|
||||
function Poll($secs=5)
|
||||
{
|
||||
$this->conn->fnExecute = false;
|
||||
//$this->conn->debug=1;
|
||||
if ($secs <= 1) $secs = 1;
|
||||
echo "Accumulating statistics, every $secs seconds...\n";flush();
|
||||
$arro =& $this->PollParameters();
|
||||
$cnt = 0;
|
||||
set_time_limit(0);
|
||||
sleep($secs);
|
||||
while (1) {
|
||||
$arr =& $this->PollParameters();
|
||||
|
||||
$hits = sprintf('%2.2f',$arr[0]);
|
||||
$reads = sprintf('%12.4f',($arr[1]-$arro[1])/$secs);
|
||||
$writes = sprintf('%12.4f',($arr[2]-$arro[2])/$secs);
|
||||
$sess = sprintf('%5d',$arr[3]);
|
||||
|
||||
$load = $this->CPULoad();
|
||||
if ($load !== false) {
|
||||
$oslabel = 'WS-CPU%';
|
||||
$osval = sprintf(" %2.1f ",(float) $load);
|
||||
}else {
|
||||
$oslabel = '';
|
||||
$osval = '';
|
||||
}
|
||||
if ($cnt % 10 == 0) echo " Time ".$oslabel." Hit% Sess Reads/s Writes/s\n";
|
||||
$cnt += 1;
|
||||
echo date('H:i:s').' '.$osval."$hits $sess $reads $writes\n";
|
||||
flush();
|
||||
|
||||
sleep($secs);
|
||||
$arro = $arr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Returns basic health check in a command line interface
|
||||
*/
|
||||
function HealthCheckCLI()
|
||||
{
|
||||
return $this->HealthCheck(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns basic health check as HTML
|
||||
*/
|
||||
function HealthCheck($cli=false)
|
||||
{
|
||||
$saveE = $this->conn->fnExecute;
|
||||
$this->conn->fnExecute = false;
|
||||
if ($cli) $html = '';
|
||||
else $html = $this->table.'<tr><td colspan=3><h3>'.$this->conn->databaseType.'</h3></td></tr>'.$this->titles;
|
||||
|
||||
$oldc = false;
|
||||
$bgc = '';
|
||||
foreach($this->settings as $name => $arr) {
|
||||
if ($arr === false) break;
|
||||
|
||||
if (!is_string($name)) {
|
||||
if ($cli) $html .= " -- $arr -- \n";
|
||||
else $html .= "<tr bgcolor=$this->color><td colspan=3><i>$arr</i> </td></tr>";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_array($arr)) break;
|
||||
$category = $arr[0];
|
||||
$how = $arr[1];
|
||||
if (sizeof($arr)>2) $desc = $arr[2];
|
||||
else $desc = ' ';
|
||||
|
||||
|
||||
if ($category == 'HIDE') continue;
|
||||
|
||||
$val = $this->_DBParameter($how);
|
||||
|
||||
if ($desc && strncmp($desc,"=",1) === 0) {
|
||||
$fn = substr($desc,1);
|
||||
$desc = $this->$fn($val);
|
||||
}
|
||||
|
||||
if ($val === false) {
|
||||
$m = $this->conn->ErrorMsg();
|
||||
$val = "Error: $m";
|
||||
} else {
|
||||
if (is_numeric($val) && $val >= 256*1024) {
|
||||
if ($val % (1024*1024) == 0) {
|
||||
$val /= (1024*1024);
|
||||
$val .= 'M';
|
||||
} else if ($val % 1024 == 0) {
|
||||
$val /= 1024;
|
||||
$val .= 'K';
|
||||
}
|
||||
//$val = htmlspecialchars($val);
|
||||
}
|
||||
}
|
||||
if ($category != $oldc) {
|
||||
$oldc = $category;
|
||||
//$bgc = ($bgc == ' bgcolor='.$this->color) ? ' bgcolor=white' : ' bgcolor='.$this->color;
|
||||
}
|
||||
if (strlen($desc)==0) $desc = ' ';
|
||||
if (strlen($val)==0) $val = ' ';
|
||||
if ($cli) {
|
||||
$html .= str_replace(' ','',sprintf($this->cliFormat,strip_tags($name),strip_tags($val),strip_tags($desc)));
|
||||
|
||||
}else {
|
||||
$html .= "<tr$bgc><td>".$name.'</td><td>'.$val.'</td><td>'.$desc."</td></tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$cli) $html .= "</table>\n";
|
||||
$this->conn->fnExecute = $saveE;
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
function Tables($orderby='1')
|
||||
{
|
||||
if (!$this->tablesSQL) return false;
|
||||
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
$rs = $this->conn->Execute($this->tablesSQL.' order by '.$orderby);
|
||||
$this->conn->LogSQL($savelog);
|
||||
$html = rs2html($rs,false,false,false,false);
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
function CreateLogTable()
|
||||
{
|
||||
if (!$this->createTableSQL) return false;
|
||||
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
$ok = $this->conn->Execute($this->createTableSQL);
|
||||
$this->conn->LogSQL($savelog);
|
||||
return ($ok) ? true : false;
|
||||
}
|
||||
|
||||
function DoSQLForm()
|
||||
{
|
||||
global $HTTP_SERVER_VARS,$HTTP_GET_VARS,$HTTP_POST_VARS,$HTTP_SESSION_VARS;
|
||||
|
||||
$HTTP_VARS = array_merge($HTTP_GET_VARS,$HTTP_POST_VARS);
|
||||
|
||||
$PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
|
||||
$sql = isset($HTTP_VARS['sql']) ? $HTTP_VARS['sql'] : '';
|
||||
|
||||
if (isset($HTTP_SESSION_VARS['phplens_sqlrows'])) $rows = $HTTP_SESSION_VARS['phplens_sqlrows'];
|
||||
else $rows = 3;
|
||||
|
||||
if (isset($HTTP_VARS['SMALLER'])) {
|
||||
$rows /= 2;
|
||||
if ($rows < 3) $rows = 3;
|
||||
$HTTP_SESSION_VARS['phplens_sqlrows'] = $rows;
|
||||
}
|
||||
if (isset($HTTP_VARS['BIGGER'])) {
|
||||
$rows *= 2;
|
||||
$HTTP_SESSION_VARS['phplens_sqlrows'] = $rows;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<form method="POST" action="<?php echo $PHP_SELF ?>">
|
||||
<table><tr>
|
||||
<td> Form size: <input type="submit" value=" < " name="SMALLER"><input type="submit" value=" > > " name="BIGGER">
|
||||
</td>
|
||||
<td align=right>
|
||||
<input type="submit" value=" Run SQL Below " name="RUN"><input type=hidden name=do value=dosql>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td colspan=2><textarea rows=<?php print $rows; ?> name="sql" cols="80"><?php print htmlspecialchars($sql) ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
if (!isset($HTTP_VARS['sql'])) return;
|
||||
|
||||
$sql = $this->undomq(trim($sql));
|
||||
if (substr($sql,strlen($sql)-1) === ';') {
|
||||
$print = true;
|
||||
$sqla = $this->SplitSQL($sql);
|
||||
} else {
|
||||
$print = false;
|
||||
$sqla = array($sql);
|
||||
}
|
||||
foreach($sqla as $sqls) {
|
||||
|
||||
if (!$sqls) continue;
|
||||
|
||||
if ($print) {
|
||||
print "<p>".htmlspecialchars($sqls)."</p>";
|
||||
flush();
|
||||
}
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
$rs = $this->conn->Execute($sqls);
|
||||
$this->conn->LogSQL($savelog);
|
||||
if ($rs && is_object($rs) && !$rs->EOF) {
|
||||
rs2html($rs);
|
||||
while ($rs->NextRecordSet()) {
|
||||
print "<table width=98% bgcolor=#C0C0FF><tr><td> </td></tr></table>";
|
||||
rs2html($rs);
|
||||
}
|
||||
} else {
|
||||
$e1 = (integer) $this->conn->ErrorNo();
|
||||
$e2 = $this->conn->ErrorMsg();
|
||||
if (($e1) || ($e2)) {
|
||||
if (empty($e1)) $e1 = '-1'; // postgresql fix
|
||||
print ' '.$e1.': '.$e2;
|
||||
} else {
|
||||
print "<p>No Recordset returned<br></p>";
|
||||
}
|
||||
}
|
||||
} // foreach
|
||||
}
|
||||
|
||||
function SplitSQL($sql)
|
||||
{
|
||||
$arr = explode(';',$sql);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function undomq(&$m)
|
||||
{
|
||||
if (get_magic_quotes_gpc()) {
|
||||
// undo the damage
|
||||
$m = str_replace('\\\\','\\',$m);
|
||||
$m = str_replace('\"','"',$m);
|
||||
$m = str_replace('\\\'','\'',$m);
|
||||
}
|
||||
return $m;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
16
phpgwapi/inc/adodb/adodb-php4.inc.php
Normal file
16
phpgwapi/inc/adodb/adodb-php4.inc.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4.
|
||||
*/
|
||||
|
||||
|
||||
class ADODB_BASE_RS {
|
||||
}
|
||||
|
||||
?>
|
967
phpgwapi/inc/adodb/adodb-time.inc.php
Normal file
967
phpgwapi/inc/adodb/adodb-time.inc.php
Normal file
@ -0,0 +1,967 @@
|
||||
<?php
|
||||
/**
|
||||
ADOdb Date Library, part of the ADOdb abstraction library
|
||||
Download: http://php.weblogs.com/adodb_date_time_library
|
||||
|
||||
PHP native date functions use integer timestamps for computations.
|
||||
Because of this, dates are restricted to the years 1901-2038 on Unix
|
||||
and 1970-2038 on Windows due to integer overflow for dates beyond
|
||||
those years. This library overcomes these limitations by replacing the
|
||||
native function's signed integers (normally 32-bits) with PHP floating
|
||||
point numbers (normally 64-bits).
|
||||
|
||||
Dates from 100 A.D. to 3000 A.D. and later
|
||||
have been tested. The minimum is 100 A.D. as <100 will invoke the
|
||||
2 => 4 digit year conversion. The maximum is billions of years in the
|
||||
future, but this is a theoretical limit as the computation of that year
|
||||
would take too long with the current implementation of adodb_mktime().
|
||||
|
||||
This library replaces native functions as follows:
|
||||
|
||||
<pre>
|
||||
getdate() with adodb_getdate()
|
||||
date() with adodb_date()
|
||||
gmdate() with adodb_gmdate()
|
||||
mktime() with adodb_mktime()
|
||||
gmmktime() with adodb_gmmktime()
|
||||
</pre>
|
||||
|
||||
The parameters are identical, except that adodb_date() accepts a subset
|
||||
of date()'s field formats. Mktime() will convert from local time to GMT,
|
||||
and date() will convert from GMT to local time, but daylight savings is
|
||||
not handled currently.
|
||||
|
||||
This library is independant of the rest of ADOdb, and can be used
|
||||
as standalone code.
|
||||
|
||||
PERFORMANCE
|
||||
|
||||
For high speed, this library uses the native date functions where
|
||||
possible, and only switches to PHP code when the dates fall outside
|
||||
the 32-bit signed integer range.
|
||||
|
||||
GREGORIAN CORRECTION
|
||||
|
||||
Pope Gregory shortened October of A.D. 1582 by ten days. Thursday,
|
||||
October 4, 1582 (Julian) was followed immediately by Friday, October 15,
|
||||
1582 (Gregorian).
|
||||
|
||||
Since 0.06, we handle this correctly, so:
|
||||
|
||||
adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)
|
||||
== 24 * 3600 (1 day)
|
||||
|
||||
=============================================================================
|
||||
|
||||
COPYRIGHT
|
||||
|
||||
(c) 2003 John Lim and released under BSD-style license except for code by jackbbs,
|
||||
which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year
|
||||
and originally found at http://www.php.net/manual/en/function.mktime.php
|
||||
|
||||
=============================================================================
|
||||
|
||||
BUG REPORTS
|
||||
|
||||
These should be posted to the ADOdb forums at
|
||||
|
||||
http://phplens.com/lens/lensforum/topics.php?id=4
|
||||
|
||||
=============================================================================
|
||||
|
||||
FUNCTION DESCRIPTIONS
|
||||
|
||||
|
||||
FUNCTION adodb_getdate($date=false)
|
||||
|
||||
Returns an array containing date information, as getdate(), but supports
|
||||
dates greater than 1901 to 2038.
|
||||
|
||||
|
||||
FUNCTION adodb_date($fmt, $timestamp = false)
|
||||
|
||||
Convert a timestamp to a formatted local date. If $timestamp is not defined, the
|
||||
current timestamp is used. Unlike the function date(), it supports dates
|
||||
outside the 1901 to 2038 range.
|
||||
|
||||
The format fields that adodb_date supports:
|
||||
|
||||
<pre>
|
||||
a - "am" or "pm"
|
||||
A - "AM" or "PM"
|
||||
d - day of the month, 2 digits with leading zeros; i.e. "01" to "31"
|
||||
D - day of the week, textual, 3 letters; e.g. "Fri"
|
||||
F - month, textual, long; e.g. "January"
|
||||
g - hour, 12-hour format without leading zeros; i.e. "1" to "12"
|
||||
G - hour, 24-hour format without leading zeros; i.e. "0" to "23"
|
||||
h - hour, 12-hour format; i.e. "01" to "12"
|
||||
H - hour, 24-hour format; i.e. "00" to "23"
|
||||
i - minutes; i.e. "00" to "59"
|
||||
j - day of the month without leading zeros; i.e. "1" to "31"
|
||||
l (lowercase 'L') - day of the week, textual, long; e.g. "Friday"
|
||||
L - boolean for whether it is a leap year; i.e. "0" or "1"
|
||||
m - month; i.e. "01" to "12"
|
||||
M - month, textual, 3 letters; e.g. "Jan"
|
||||
n - month without leading zeros; i.e. "1" to "12"
|
||||
O - Difference to Greenwich time in hours; e.g. "+0200"
|
||||
Q - Quarter, as in 1, 2, 3, 4
|
||||
r - RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200"
|
||||
s - seconds; i.e. "00" to "59"
|
||||
S - English ordinal suffix for the day of the month, 2 characters;
|
||||
i.e. "st", "nd", "rd" or "th"
|
||||
t - number of days in the given month; i.e. "28" to "31"
|
||||
T - Timezone setting of this machine; e.g. "EST" or "MDT"
|
||||
U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
|
||||
w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday)
|
||||
Y - year, 4 digits; e.g. "1999"
|
||||
y - year, 2 digits; e.g. "99"
|
||||
z - day of the year; i.e. "0" to "365"
|
||||
Z - timezone offset in seconds (i.e. "-43200" to "43200").
|
||||
The offset for timezones west of UTC is always negative,
|
||||
and for those east of UTC is always positive.
|
||||
</pre>
|
||||
|
||||
Unsupported:
|
||||
<pre>
|
||||
B - Swatch Internet time
|
||||
I (capital i) - "1" if Daylight Savings Time, "0" otherwise.
|
||||
W - ISO-8601 week number of year, weeks starting on Monday
|
||||
|
||||
</pre>
|
||||
|
||||
FUNCTION adodb_date2($fmt, $isoDateString = false)
|
||||
Same as adodb_date, but 2nd parameter accepts iso date, eg.
|
||||
|
||||
adodb_date2('d-M-Y H:i','2003-12-25 13:01:34');
|
||||
|
||||
FUNCTION adodb_gmdate($fmt, $timestamp = false)
|
||||
|
||||
Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the
|
||||
current timestamp is used. Unlike the function date(), it supports dates
|
||||
outside the 1901 to 2038 range.
|
||||
|
||||
|
||||
FUNCTION adodb_mktime($hr, $min, $sec [, $month, $day, $year])
|
||||
|
||||
Converts a local date to a unix timestamp. Unlike the function mktime(), it supports
|
||||
dates outside the 1901 to 2038 range. Differs from mktime() in that all parameters
|
||||
are currently compulsory.
|
||||
|
||||
FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year])
|
||||
|
||||
Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports
|
||||
dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters
|
||||
are currently compulsory.
|
||||
|
||||
=============================================================================
|
||||
|
||||
NOTES
|
||||
|
||||
Useful url for generating test timestamps:
|
||||
http://www.4webhelp.net/us/timestamp.php
|
||||
|
||||
Possible future optimizations include
|
||||
|
||||
a. Using an algorithm similar to Plauger's in "The Standard C Library"
|
||||
(page 428, xttotm.c _Ttotm() function). Plauger's algorithm will not
|
||||
work outside 32-bit signed range, so i decided not to implement it.
|
||||
|
||||
b. Iterate over a block of years (say 12) when searching for the
|
||||
correct year.
|
||||
|
||||
c. Implement daylight savings, which looks awfully complicated, see
|
||||
http://webexhibits.org/daylightsaving/
|
||||
|
||||
|
||||
CHANGELOG
|
||||
- 18 July 2004 0.15
|
||||
All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. This
|
||||
brings it more in line with mktime (still not identical).
|
||||
|
||||
- 23 June 2004 0.14
|
||||
|
||||
Allow you to define your own daylights savings function, adodb_daylight_sv.
|
||||
If the function is defined (somewhere in an include), then you can correct for daylights savings.
|
||||
|
||||
In this example, we apply daylights savings in June or July, adding one hour. This is extremely
|
||||
unrealistic as it does not take into account time-zone, geographic location, current year.
|
||||
|
||||
function adodb_daylight_sv(&$arr, $is_gmt)
|
||||
{
|
||||
if ($is_gmt) return;
|
||||
$m = $arr['mon'];
|
||||
if ($m == 6 || $m == 7) $arr['hours'] += 1;
|
||||
}
|
||||
|
||||
This is only called by adodb_date() and not by adodb_mktime().
|
||||
|
||||
The format of $arr is
|
||||
Array (
|
||||
[seconds] => 0
|
||||
[minutes] => 0
|
||||
[hours] => 0
|
||||
[mday] => 1 # day of month, eg 1st day of the month
|
||||
[mon] => 2 # month (eg. Feb)
|
||||
[year] => 2102
|
||||
[yday] => 31 # days in current year
|
||||
[leap] => # true if leap year
|
||||
[ndays] => 28 # no of days in current month
|
||||
)
|
||||
|
||||
|
||||
- 28 Apr 2004 0.13
|
||||
Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov.
|
||||
|
||||
- 20 Mar 2004 0.12
|
||||
Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32.
|
||||
|
||||
- 26 Oct 2003 0.11
|
||||
Because of daylight savings problems (some systems apply daylight savings to
|
||||
January!!!), changed adodb_get_gmt_diff() to ignore daylight savings.
|
||||
|
||||
- 9 Aug 2003 0.10
|
||||
Fixed bug with dates after 2038.
|
||||
See http://phplens.com/lens/lensforum/msgs.php?id=6980
|
||||
|
||||
- 1 July 2003 0.09
|
||||
Added support for Q (Quarter).
|
||||
Added adodb_date2(), which accepts ISO date in 2nd param
|
||||
|
||||
- 3 March 2003 0.08
|
||||
Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS
|
||||
if you want PHP to handle negative timestamps between 1901 to 1969.
|
||||
|
||||
- 27 Feb 2003 0.07
|
||||
All negative numbers handled by adodb now because of RH 7.3+ problems.
|
||||
See http://bugs.php.net/bug.php?id=20048&edit=2
|
||||
|
||||
- 4 Feb 2003 0.06
|
||||
Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates
|
||||
are now correctly handled.
|
||||
|
||||
- 29 Jan 2003 0.05
|
||||
|
||||
Leap year checking differs under Julian calendar (pre 1582). Also
|
||||
leap year code optimized by checking for most common case first.
|
||||
|
||||
We also handle month overflow correctly in mktime (eg month set to 13).
|
||||
|
||||
Day overflow for less than one month's days is supported.
|
||||
|
||||
- 28 Jan 2003 0.04
|
||||
|
||||
Gregorian correction handled. In PHP5, we might throw an error if
|
||||
mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10.
|
||||
Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582.
|
||||
|
||||
- 27 Jan 2003 0.03
|
||||
|
||||
Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION.
|
||||
Fixed calculation of days since start of year for <1970.
|
||||
|
||||
- 27 Jan 2003 0.02
|
||||
|
||||
Changed _adodb_getdate() to inline leap year checking for better performance.
|
||||
Fixed problem with time-zones west of GMT +0000.
|
||||
|
||||
- 24 Jan 2003 0.01
|
||||
|
||||
First implementation.
|
||||
*/
|
||||
|
||||
|
||||
/* Initialization */
|
||||
|
||||
/*
|
||||
Version Number
|
||||
*/
|
||||
define('ADODB_DATE_VERSION',0.15);
|
||||
|
||||
/*
|
||||
We check for Windows as only +ve ints are accepted as dates on Windows.
|
||||
|
||||
Apparently this problem happens also with Linux, RH 7.3 and later!
|
||||
|
||||
glibc-2.2.5-34 and greater has been changed to return -1 for dates <
|
||||
1970. This used to work. The problem exists with RedHat 7.3 and 8.0
|
||||
echo (mktime(0, 0, 0, 1, 1, 1960)); // prints -1
|
||||
|
||||
References:
|
||||
http://bugs.php.net/bug.php?id=20048&edit=2
|
||||
http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html
|
||||
*/
|
||||
|
||||
if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1);
|
||||
|
||||
function adodb_date_test_date($y1,$m)
|
||||
{
|
||||
//print " $y1/$m ";
|
||||
$t = adodb_mktime(0,0,0,$m,13,$y1);
|
||||
if ("$y1-$m-13 00:00:00" != adodb_date('Y-n-d H:i:s',$t)) {
|
||||
print "<b>$y1 error</b><br>";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
Test Suite
|
||||
*/
|
||||
function adodb_date_test()
|
||||
{
|
||||
|
||||
error_reporting(E_ALL);
|
||||
print "<h4>Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION. "</h4>";
|
||||
@set_time_limit(0);
|
||||
$fail = false;
|
||||
|
||||
// This flag disables calling of PHP native functions, so we can properly test the code
|
||||
if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
|
||||
|
||||
$t = adodb_mktime(0,0,0);
|
||||
if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>';
|
||||
|
||||
$t = adodb_mktime(0,0,0,6,1,2102);
|
||||
if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
|
||||
|
||||
$t = adodb_mktime(0,0,0,2,1,2102);
|
||||
if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
|
||||
|
||||
|
||||
print "<p>Testing gregorian <=> julian conversion<p>";
|
||||
$t = adodb_mktime(0,0,0,10,11,1492);
|
||||
//http://www.holidayorigins.com/html/columbus_day.html - Friday check
|
||||
if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing<br>';
|
||||
|
||||
$t = adodb_mktime(0,0,0,2,29,1500);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years<br>';
|
||||
|
||||
$t = adodb_mktime(0,0,0,2,29,1700);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years<br>';
|
||||
|
||||
print adodb_mktime(0,0,0,10,4,1582).' ';
|
||||
print adodb_mktime(0,0,0,10,15,1582);
|
||||
$diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582));
|
||||
if ($diff != 3600*24) print " <b>Error in gregorian correction = ".($diff/3600/24)." days </b><br>";
|
||||
|
||||
print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : '<b>Error</b>')."<br>";
|
||||
print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : '<b>Error</b>')."<br>";
|
||||
|
||||
print "<p>Testing overflow<p>";
|
||||
|
||||
$t = adodb_mktime(0,0,0,3,33,1965);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1 <br>';
|
||||
$t = adodb_mktime(0,0,0,4,33,1971);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2 <br>';
|
||||
$t = adodb_mktime(0,0,0,1,60,1965);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).' <br>';
|
||||
$t = adodb_mktime(0,0,0,12,32,1965);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).' <br>';
|
||||
$t = adodb_mktime(0,0,0,12,63,1965);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).' <br>';
|
||||
$t = adodb_mktime(0,0,0,13,3,1965);
|
||||
if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1 <br>';
|
||||
|
||||
print "Testing 2-digit => 4-digit year conversion<p>";
|
||||
if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000<br>";
|
||||
if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010<br>";
|
||||
if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020<br>";
|
||||
if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030<br>";
|
||||
if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940<br>";
|
||||
if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950<br>";
|
||||
if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990<br>";
|
||||
|
||||
// Test string formating
|
||||
print "<p>Testing date formating</p>";
|
||||
$fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C822 r s t U w y Y z Z 2003';
|
||||
$s1 = date($fmt,0);
|
||||
$s2 = adodb_date($fmt,0);
|
||||
if ($s1 != $s2) {
|
||||
print " date() 0 failed<br>$s1<br>$s2<br>";
|
||||
}
|
||||
flush();
|
||||
for ($i=100; --$i > 0; ) {
|
||||
|
||||
$ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000);
|
||||
$s1 = date($fmt,$ts);
|
||||
$s2 = adodb_date($fmt,$ts);
|
||||
//print "$s1 <br>$s2 <p>";
|
||||
$pos = strcmp($s1,$s2);
|
||||
|
||||
if (($s1) != ($s2)) {
|
||||
for ($j=0,$k=strlen($s1); $j < $k; $j++) {
|
||||
if ($s1[$j] != $s2[$j]) {
|
||||
print substr($s1,$j).' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
print "<b>Error date(): $ts<br><pre>
|
||||
\"$s1\" (date len=".strlen($s1).")
|
||||
\"$s2\" (adodb_date len=".strlen($s2).")</b></pre><br>";
|
||||
$fail = true;
|
||||
}
|
||||
|
||||
$a1 = getdate($ts);
|
||||
$a2 = adodb_getdate($ts);
|
||||
$rez = array_diff($a1,$a2);
|
||||
if (sizeof($rez)>0) {
|
||||
print "<b>Error getdate() $ts</b><br>";
|
||||
print_r($a1);
|
||||
print "<br>";
|
||||
print_r($a2);
|
||||
print "<p>";
|
||||
$fail = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Test generation of dates outside 1901-2038
|
||||
print "<p>Testing random dates between 100 and 4000</p>";
|
||||
adodb_date_test_date(100,1);
|
||||
for ($i=100; --$i >= 0;) {
|
||||
$y1 = 100+rand(0,1970-100);
|
||||
$m = rand(1,12);
|
||||
adodb_date_test_date($y1,$m);
|
||||
|
||||
$y1 = 3000-rand(0,3000-1970);
|
||||
adodb_date_test_date($y1,$m);
|
||||
}
|
||||
print '<p>';
|
||||
$start = 1960+rand(0,10);
|
||||
$yrs = 12;
|
||||
$i = 365.25*86400*($start-1970);
|
||||
$offset = 36000+rand(10000,60000);
|
||||
$max = 365*$yrs*86400;
|
||||
$lastyear = 0;
|
||||
|
||||
// we generate a timestamp, convert it to a date, and convert it back to a timestamp
|
||||
// and check if the roundtrip broke the original timestamp value.
|
||||
print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: ";
|
||||
$cnt = 0;
|
||||
for ($max += $i; $i < $max; $i += $offset) {
|
||||
$ret = adodb_date('m,d,Y,H,i,s',$i);
|
||||
$arr = explode(',',$ret);
|
||||
if ($lastyear != $arr[2]) {
|
||||
$lastyear = $arr[2];
|
||||
print " $lastyear ";
|
||||
flush();
|
||||
}
|
||||
$newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]);
|
||||
if ($i != $newi) {
|
||||
print "Error at $i, adodb_mktime returned $newi ($ret)";
|
||||
$fail = true;
|
||||
break;
|
||||
}
|
||||
$cnt += 1;
|
||||
}
|
||||
echo "Tested $cnt dates<br>";
|
||||
if (!$fail) print "<p>Passed !</p>";
|
||||
else print "<p><b>Failed</b> :-(</p>";
|
||||
}
|
||||
|
||||
/**
|
||||
Returns day of week, 0 = Sunday,... 6=Saturday.
|
||||
Algorithm from PEAR::Date_Calc
|
||||
*/
|
||||
function adodb_dow($year, $month, $day)
|
||||
{
|
||||
/*
|
||||
Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
|
||||
proclaimed that from that time onwards 3 days would be dropped from the calendar
|
||||
every 400 years.
|
||||
|
||||
Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian).
|
||||
*/
|
||||
if ($year <= 1582) {
|
||||
if ($year < 1582 ||
|
||||
($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3;
|
||||
else
|
||||
$greg_correction = 0;
|
||||
} else
|
||||
$greg_correction = 0;
|
||||
|
||||
if($month > 2)
|
||||
$month -= 2;
|
||||
else {
|
||||
$month += 10;
|
||||
$year--;
|
||||
}
|
||||
|
||||
$day = ( floor((13 * $month - 1) / 5) +
|
||||
$day + ($year % 100) +
|
||||
floor(($year % 100) / 4) +
|
||||
floor(($year / 100) / 4) - 2 *
|
||||
floor($year / 100) + 77);
|
||||
|
||||
return (($day - 7 * floor($day / 7))) + $greg_correction;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Checks for leap year, returns true if it is. No 2-digit year check. Also
|
||||
handles julian calendar correctly.
|
||||
*/
|
||||
function _adodb_is_leap_year($year)
|
||||
{
|
||||
if ($year % 4 != 0) return false;
|
||||
|
||||
if ($year % 400 == 0) {
|
||||
return true;
|
||||
// if gregorian calendar (>1582), century not-divisible by 400 is not leap
|
||||
} else if ($year > 1582 && $year % 100 == 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
checks for leap year, returns true if it is. Has 2-digit year check
|
||||
*/
|
||||
function adodb_is_leap_year($year)
|
||||
{
|
||||
return _adodb_is_leap_year(adodb_year_digit_check($year));
|
||||
}
|
||||
|
||||
/**
|
||||
Fix 2-digit years. Works for any century.
|
||||
Assumes that if 2-digit is more than 30 years in future, then previous century.
|
||||
*/
|
||||
function adodb_year_digit_check($y)
|
||||
{
|
||||
if ($y < 100) {
|
||||
|
||||
$yr = (integer) date("Y");
|
||||
$century = (integer) ($yr /100);
|
||||
|
||||
if ($yr%100 > 50) {
|
||||
$c1 = $century + 1;
|
||||
$c0 = $century;
|
||||
} else {
|
||||
$c1 = $century;
|
||||
$c0 = $century - 1;
|
||||
}
|
||||
$c1 *= 100;
|
||||
// if 2-digit year is less than 30 years in future, set it to this century
|
||||
// otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
|
||||
if (($y + $c1) < $yr+30) $y = $y + $c1;
|
||||
else $y = $y + $c0*100;
|
||||
}
|
||||
return $y;
|
||||
}
|
||||
|
||||
/**
|
||||
get local time zone offset from GMT
|
||||
*/
|
||||
function adodb_get_gmt_diff()
|
||||
{
|
||||
static $TZ;
|
||||
if (isset($TZ)) return $TZ;
|
||||
|
||||
$TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0);
|
||||
return $TZ;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns an array with date info.
|
||||
*/
|
||||
function adodb_getdate($d=false,$fast=false)
|
||||
{
|
||||
if ($d === false) return getdate();
|
||||
if (!defined('ADODB_TEST_DATES')) {
|
||||
if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
|
||||
if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
|
||||
return @getdate($d);
|
||||
}
|
||||
}
|
||||
return _adodb_getdate($d);
|
||||
}
|
||||
|
||||
/**
|
||||
Low-level function that returns the getdate() array. We have a special
|
||||
$fast flag, which if set to true, will return fewer array values,
|
||||
and is much faster as it does not calculate dow, etc.
|
||||
*/
|
||||
function _adodb_getdate($origd=false,$fast=false,$is_gmt=false)
|
||||
{
|
||||
$d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff());
|
||||
|
||||
$_day_power = 86400;
|
||||
$_hour_power = 3600;
|
||||
$_min_power = 60;
|
||||
|
||||
if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction
|
||||
|
||||
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
|
||||
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
|
||||
|
||||
$d366 = $_day_power * 366;
|
||||
$d365 = $_day_power * 365;
|
||||
|
||||
if ($d < 0) {
|
||||
$origd = $d;
|
||||
// The valid range of a 32bit signed timestamp is typically from
|
||||
// Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
|
||||
for ($a = 1970 ; --$a >= 0;) {
|
||||
$lastd = $d;
|
||||
|
||||
if ($leaf = _adodb_is_leap_year($a)) $d += $d366;
|
||||
else $d += $d365;
|
||||
|
||||
if ($d >= 0) {
|
||||
$year = $a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd;
|
||||
|
||||
$d = $lastd;
|
||||
$mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
|
||||
for ($a = 13 ; --$a > 0;) {
|
||||
$lastd = $d;
|
||||
$d += $mtab[$a] * $_day_power;
|
||||
if ($d >= 0) {
|
||||
$month = $a;
|
||||
$ndays = $mtab[$a];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$d = $lastd;
|
||||
$day = $ndays + ceil(($d+1) / ($_day_power));
|
||||
|
||||
$d += ($ndays - $day+1)* $_day_power;
|
||||
$hour = floor($d/$_hour_power);
|
||||
|
||||
} else {
|
||||
for ($a = 1970 ;; $a++) {
|
||||
$lastd = $d;
|
||||
|
||||
if ($leaf = _adodb_is_leap_year($a)) $d -= $d366;
|
||||
else $d -= $d365;
|
||||
if ($d < 0) {
|
||||
$year = $a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$secsInYear = $lastd;
|
||||
$d = $lastd;
|
||||
$mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal;
|
||||
for ($a = 1 ; $a <= 12; $a++) {
|
||||
$lastd = $d;
|
||||
$d -= $mtab[$a] * $_day_power;
|
||||
if ($d < 0) {
|
||||
$month = $a;
|
||||
$ndays = $mtab[$a];
|
||||
break;
|
||||
}
|
||||
}
|
||||
$d = $lastd;
|
||||
$day = ceil(($d+1) / $_day_power);
|
||||
$d = $d - ($day-1) * $_day_power;
|
||||
$hour = floor($d /$_hour_power);
|
||||
}
|
||||
|
||||
$d -= $hour * $_hour_power;
|
||||
$min = floor($d/$_min_power);
|
||||
$secs = $d - $min * $_min_power;
|
||||
if ($fast) {
|
||||
return array(
|
||||
'seconds' => $secs,
|
||||
'minutes' => $min,
|
||||
'hours' => $hour,
|
||||
'mday' => $day,
|
||||
'mon' => $month,
|
||||
'year' => $year,
|
||||
'yday' => floor($secsInYear/$_day_power),
|
||||
'leap' => $leaf,
|
||||
'ndays' => $ndays
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$dow = adodb_dow($year,$month,$day);
|
||||
|
||||
return array(
|
||||
'seconds' => $secs,
|
||||
'minutes' => $min,
|
||||
'hours' => $hour,
|
||||
'mday' => $day,
|
||||
'wday' => $dow,
|
||||
'mon' => $month,
|
||||
'year' => $year,
|
||||
'yday' => floor($secsInYear/$_day_power),
|
||||
'weekday' => gmdate('l',$_day_power*(3+$dow)),
|
||||
'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
|
||||
0 => $origd
|
||||
);
|
||||
}
|
||||
|
||||
function adodb_gmdate($fmt,$d=false)
|
||||
{
|
||||
return adodb_date($fmt,$d,true);
|
||||
}
|
||||
|
||||
// accepts unix timestamp and iso date format in $d
|
||||
function adodb_date2($fmt, $d=false, $is_gmt=false)
|
||||
{
|
||||
if ($d !== false) {
|
||||
if (!preg_match(
|
||||
"|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
|
||||
($d), $rr)) return adodb_date($fmt,false,$is_gmt);
|
||||
|
||||
if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt);
|
||||
|
||||
// h-m-s-MM-DD-YY
|
||||
if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
|
||||
else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
|
||||
}
|
||||
|
||||
return adodb_date($fmt,$d,$is_gmt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Return formatted date based on timestamp $d
|
||||
*/
|
||||
function adodb_date($fmt,$d=false,$is_gmt=false)
|
||||
{
|
||||
static $daylight;
|
||||
|
||||
if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
|
||||
if (!defined('ADODB_TEST_DATES')) {
|
||||
if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
|
||||
if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer
|
||||
return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d);
|
||||
|
||||
}
|
||||
}
|
||||
$_day_power = 86400;
|
||||
|
||||
$arr = _adodb_getdate($d,true,$is_gmt);
|
||||
if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
|
||||
if ($daylight) adodb_daylight_sv($arr, $is_gmt);
|
||||
|
||||
$year = $arr['year'];
|
||||
$month = $arr['mon'];
|
||||
$day = $arr['mday'];
|
||||
$hour = $arr['hours'];
|
||||
$min = $arr['minutes'];
|
||||
$secs = $arr['seconds'];
|
||||
|
||||
$max = strlen($fmt);
|
||||
$dates = '';
|
||||
|
||||
/*
|
||||
at this point, we have the following integer vars to manipulate:
|
||||
$year, $month, $day, $hour, $min, $secs
|
||||
*/
|
||||
for ($i=0; $i < $max; $i++) {
|
||||
switch($fmt[$i]) {
|
||||
case 'T': $dates .= date('T');break;
|
||||
// YEAR
|
||||
case 'L': $dates .= $arr['leap'] ? '1' : '0'; break;
|
||||
case 'r': // Thu, 21 Dec 2000 16:01:07 +0200
|
||||
|
||||
$dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', '
|
||||
. ($day<10?' '.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
|
||||
|
||||
if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour;
|
||||
|
||||
if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min;
|
||||
|
||||
if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs;
|
||||
|
||||
$gmt = adodb_get_gmt_diff();
|
||||
$dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
|
||||
|
||||
case 'Y': $dates .= $year; break;
|
||||
case 'y': $dates .= substr($year,strlen($year)-2,2); break;
|
||||
// MONTH
|
||||
case 'm': if ($month<10) $dates .= '0'.$month; else $dates .= $month; break;
|
||||
case 'Q': $dates .= ($month+3)>>2; break;
|
||||
case 'n': $dates .= $month; break;
|
||||
case 'M': $dates .= date('M',mktime(0,0,0,$month,2,1971)); break;
|
||||
case 'F': $dates .= date('F',mktime(0,0,0,$month,2,1971)); break;
|
||||
// DAY
|
||||
case 't': $dates .= $arr['ndays']; break;
|
||||
case 'z': $dates .= $arr['yday']; break;
|
||||
case 'w': $dates .= adodb_dow($year,$month,$day); break;
|
||||
case 'l': $dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day))); break;
|
||||
case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break;
|
||||
case 'j': $dates .= $day; break;
|
||||
case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break;
|
||||
case 'S':
|
||||
$d10 = $day % 10;
|
||||
if ($d10 == 1) $dates .= 'st';
|
||||
else if ($d10 == 2) $dates .= 'nd';
|
||||
else if ($d10 == 3) $dates .= 'rd';
|
||||
else $dates .= 'th';
|
||||
break;
|
||||
|
||||
// HOUR
|
||||
case 'Z':
|
||||
$dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break;
|
||||
case 'O':
|
||||
$gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff();
|
||||
$dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break;
|
||||
|
||||
case 'H':
|
||||
if ($hour < 10) $dates .= '0'.$hour;
|
||||
else $dates .= $hour;
|
||||
break;
|
||||
case 'h':
|
||||
if ($hour > 12) $hh = $hour - 12;
|
||||
else {
|
||||
if ($hour == 0) $hh = '12';
|
||||
else $hh = $hour;
|
||||
}
|
||||
|
||||
if ($hh < 10) $dates .= '0'.$hh;
|
||||
else $dates .= $hh;
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
$dates .= $hour;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if ($hour > 12) $hh = $hour - 12;
|
||||
else {
|
||||
if ($hour == 0) $hh = '12';
|
||||
else $hh = $hour;
|
||||
}
|
||||
$dates .= $hh;
|
||||
break;
|
||||
// MINUTES
|
||||
case 'i': if ($min < 10) $dates .= '0'.$min; else $dates .= $min; break;
|
||||
// SECONDS
|
||||
case 'U': $dates .= $d; break;
|
||||
case 's': if ($secs < 10) $dates .= '0'.$secs; else $dates .= $secs; break;
|
||||
// AM/PM
|
||||
// Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
|
||||
case 'a':
|
||||
if ($hour>=12) $dates .= 'pm';
|
||||
else $dates .= 'am';
|
||||
break;
|
||||
case 'A':
|
||||
if ($hour>=12) $dates .= 'PM';
|
||||
else $dates .= 'AM';
|
||||
break;
|
||||
default:
|
||||
$dates .= $fmt[$i]; break;
|
||||
// ESCAPE
|
||||
case "\\":
|
||||
$i++;
|
||||
if ($i < $max) $dates .= $fmt[$i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a timestamp given a GMT/UTC time.
|
||||
Note that $is_dst is not implemented and is ignored.
|
||||
*/
|
||||
function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
|
||||
{
|
||||
return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
|
||||
}
|
||||
|
||||
/**
|
||||
Return a timestamp given a local time. Originally by jackbbs.
|
||||
Note that $is_dst is not implemented and is ignored.
|
||||
|
||||
Not a very fast algorithm - O(n) operation. Could be optimized to O(1).
|
||||
*/
|
||||
function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false)
|
||||
{
|
||||
if (!defined('ADODB_TEST_DATES')) {
|
||||
// for windows, we don't check 1970 because with timezone differences,
|
||||
// 1 Jan 1970 could generate negative timestamp, which is illegal
|
||||
if (1971 < $year && $year < 2038
|
||||
|| $mon === false
|
||||
|| !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
|
||||
)
|
||||
return $is_gmt?
|
||||
@gmmktime($hr,$min,$sec,$mon,$day,$year):
|
||||
@mktime($hr,$min,$sec,$mon,$day,$year);
|
||||
}
|
||||
|
||||
$gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff();
|
||||
|
||||
$hr = intval($hr);
|
||||
$min = intval($min);
|
||||
$sec = intval($sec);
|
||||
$mon = intval($mon);
|
||||
$day = intval($day);
|
||||
$year = intval($year);
|
||||
|
||||
|
||||
$year = adodb_year_digit_check($year);
|
||||
|
||||
if ($mon > 12) {
|
||||
$y = floor($mon / 12);
|
||||
$year += $y;
|
||||
$mon -= $y*12;
|
||||
}
|
||||
|
||||
$_day_power = 86400;
|
||||
$_hour_power = 3600;
|
||||
$_min_power = 60;
|
||||
|
||||
$_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31);
|
||||
$_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31);
|
||||
|
||||
$_total_date = 0;
|
||||
if ($year >= 1970) {
|
||||
for ($a = 1970 ; $a <= $year; $a++) {
|
||||
$leaf = _adodb_is_leap_year($a);
|
||||
if ($leaf == true) {
|
||||
$loop_table = $_month_table_leaf;
|
||||
$_add_date = 366;
|
||||
} else {
|
||||
$loop_table = $_month_table_normal;
|
||||
$_add_date = 365;
|
||||
}
|
||||
if ($a < $year) {
|
||||
$_total_date += $_add_date;
|
||||
} else {
|
||||
for($b=1;$b<$mon;$b++) {
|
||||
$_total_date += $loop_table[$b];
|
||||
}
|
||||
}
|
||||
}
|
||||
$_total_date +=$day-1;
|
||||
$ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different;
|
||||
|
||||
} else {
|
||||
for ($a = 1969 ; $a >= $year; $a--) {
|
||||
$leaf = _adodb_is_leap_year($a);
|
||||
if ($leaf == true) {
|
||||
$loop_table = $_month_table_leaf;
|
||||
$_add_date = 366;
|
||||
} else {
|
||||
$loop_table = $_month_table_normal;
|
||||
$_add_date = 365;
|
||||
}
|
||||
if ($a > $year) { $_total_date += $_add_date;
|
||||
} else {
|
||||
for($b=12;$b>$mon;$b--) {
|
||||
$_total_date += $loop_table[$b];
|
||||
}
|
||||
}
|
||||
}
|
||||
$_total_date += $loop_table[$mon] - $day;
|
||||
|
||||
$_day_time = $hr * $_hour_power + $min * $_min_power + $sec;
|
||||
$_day_time = $_day_power - $_day_time;
|
||||
$ret = -( $_total_date * $_day_power + $_day_time - $gmt_different);
|
||||
if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction
|
||||
else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582.
|
||||
}
|
||||
//print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
?>
|
2194
phpgwapi/inc/adodb/adodb-xmlschema.inc.php
Normal file
2194
phpgwapi/inc/adodb/adodb-xmlschema.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
3660
phpgwapi/inc/adodb/adodb.inc.php
Normal file
3660
phpgwapi/inc/adodb/adodb.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
95
phpgwapi/inc/adodb/datadict/datadict-access.inc.php
Normal file
95
phpgwapi/inc/adodb/datadict/datadict-access.inc.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_access extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'access';
|
||||
var $seqField = false;
|
||||
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'TEXT';
|
||||
case 'XL':
|
||||
case 'X': return 'MEMO';
|
||||
|
||||
case 'C2': return 'TEXT'; // up to 32K
|
||||
case 'X2': return 'MEMO';
|
||||
|
||||
case 'B': return 'BINARY';
|
||||
|
||||
case 'D': return 'DATETIME';
|
||||
case 'T': return 'DATETIME';
|
||||
|
||||
case 'L': return 'BYTE';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'BYTE';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INTEGER';
|
||||
case 'I8': return 'INTEGER';
|
||||
|
||||
case 'F': return 'DOUBLE';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
if ($fautoinc) {
|
||||
$ftype = 'COUNTER';
|
||||
return '';
|
||||
}
|
||||
if (substr($ftype,0,7) == 'DECIMAL') $ftype = 'DECIMAL';
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) {
|
||||
//$suffix .= " DEFAULT $fdefault";
|
||||
if ($this->debug) ADOConnection::outp("Warning: Access does not supported DEFAULT values (field $fname)");
|
||||
}
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
function CreateDatabase($dbname,$options=false)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function SetSchema($schema)
|
||||
{
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
76
phpgwapi/inc/adodb/datadict/datadict-db2.inc.php
Normal file
76
phpgwapi/inc/adodb/datadict/datadict-db2.inc.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_db2 extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'db2';
|
||||
var $seqField = false;
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL': return 'CLOB';
|
||||
case 'X': return 'VARCHAR(3600)';
|
||||
|
||||
case 'C2': return 'VARCHAR'; // up to 32K
|
||||
case 'X2': return 'VARCHAR(3600)'; // up to 32000, but default page size too small
|
||||
|
||||
case 'B': return 'BLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'TIMESTAMP';
|
||||
|
||||
case 'L': return 'SMALLINT';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INTEGER';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'DOUBLE';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
$suffix = '';
|
||||
if ($fautoinc) return ' GENERATED ALWAYS AS IDENTITY'; # as identity start with
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
151
phpgwapi/inc/adodb/datadict/datadict-firebird.inc.php
Normal file
151
phpgwapi/inc/adodb/datadict/datadict-firebird.inc.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
class ADODB2_firebird15 extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'firebird15';
|
||||
var $seqField = false;
|
||||
var $seqPrefix = 'gen_';
|
||||
var $blobSize = 40000;
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(4000)';
|
||||
|
||||
case 'C2': return 'VARCHAR'; // up to 32K
|
||||
case 'X2': return 'VARCHAR(4000)';
|
||||
|
||||
case 'B': return 'BLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'TIMESTAMP';
|
||||
|
||||
case 'L': return 'SMALLINT';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INTEGER';
|
||||
case 'I8': return 'INTEGER';
|
||||
|
||||
case 'F': return 'DOUBLE PRECISION';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function NameQuote($name = NULL)
|
||||
{
|
||||
if (!is_string($name)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$name = trim($name);
|
||||
|
||||
if ( !is_object($this->connection) ) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
$quote = $this->connection->nameQuote;
|
||||
|
||||
// if name is of the form `name`, quote it
|
||||
if ( preg_match('/^`(.+)`$/', $name, $matches) ) {
|
||||
return $quote . $matches[1] . $quote;
|
||||
}
|
||||
|
||||
// if name contains special characters, quote it
|
||||
if ( !preg_match('/^[' . $this->nameRegex . ']+$/', $name) ) {
|
||||
return $quote . $name . $quote;
|
||||
}
|
||||
|
||||
return $quote . $name . $quote;
|
||||
}
|
||||
|
||||
function CreateDatabase($dbname, $options=false)
|
||||
{
|
||||
$options = $this->_Options($options);
|
||||
$sql = array();
|
||||
|
||||
$sql[] = "DECLARE EXTERNAL FUNCTION LOWER CSTRING(80) RETURNS CSTRING(80) FREE_IT ENTRY_POINT 'IB_UDF_lower' MODULE_NAME 'ib_udf'";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _DropAutoIncrement($t)
|
||||
{
|
||||
if (strpos($t,'.') !== false) {
|
||||
$tarr = explode('.',$t);
|
||||
return 'DROP GENERATOR '.$tarr[0].'."gen_'.$tarr[1].'"';
|
||||
}
|
||||
return 'DROP GENERATOR "GEN_'.$t;
|
||||
}
|
||||
|
||||
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
|
||||
{
|
||||
$suffix = '';
|
||||
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if ($fautoinc) $this->seqField = $fname;
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE or replace TRIGGER jaddress_insert
|
||||
before insert on jaddress
|
||||
for each row
|
||||
begin
|
||||
IF ( NEW."seqField" IS NULL OR NEW."seqField" = 0 ) THEN
|
||||
NEW."seqField" = GEN_ID("GEN_tabname", 1);
|
||||
end;
|
||||
*/
|
||||
function _Triggers($tabname,$tableoptions)
|
||||
{
|
||||
if (!$this->seqField) return array();
|
||||
|
||||
$tab1 = preg_replace( '/"/', '', $tabname );
|
||||
if ($this->schema) {
|
||||
$t = strpos($tab1,'.');
|
||||
if ($t !== false) $tab = substr($tab1,$t+1);
|
||||
else $tab = $tab1;
|
||||
$seqField = $this->seqField;
|
||||
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
|
||||
$trigname = $this->schema.'.trig_'.$this->seqPrefix.$tab;
|
||||
} else {
|
||||
$seqField = $this->seqField;
|
||||
$seqname = $this->seqPrefix.$tab1;
|
||||
$trigname = 'trig_'.$seqname;
|
||||
}
|
||||
if (isset($tableoptions['REPLACE']))
|
||||
{ $sql[] = "DROP GENERATOR \"$seqname\"";
|
||||
$sql[] = "CREATE GENERATOR \"$seqname\"";
|
||||
$sql[] = "ALTER TRIGGER \"$trigname\" BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END";
|
||||
}
|
||||
else
|
||||
{ $sql[] = "CREATE GENERATOR \"$seqname\"";
|
||||
$sql[] = "CREATE TRIGGER \"$trigname\" FOR $tabname BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END";
|
||||
}
|
||||
|
||||
$this->seqField = false;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
125
phpgwapi/inc/adodb/datadict/datadict-generic.inc.php
Normal file
125
phpgwapi/inc/adodb/datadict/datadict-generic.inc.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_generic extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'generic';
|
||||
var $seqField = false;
|
||||
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(250)';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'VARCHAR(250)';
|
||||
|
||||
case 'B': return 'VARCHAR';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATE';
|
||||
|
||||
case 'L': return 'DECIMAL(1)';
|
||||
case 'I': return 'DECIMAL(10)';
|
||||
case 'I1': return 'DECIMAL(3)';
|
||||
case 'I2': return 'DECIMAL(5)';
|
||||
case 'I4': return 'DECIMAL(10)';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'DECIMAL(32,8)';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
//db2
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'X': return 'VARCHAR';
|
||||
|
||||
case 'C2': return 'VARCHAR'; // up to 32K
|
||||
case 'X2': return 'VARCHAR';
|
||||
|
||||
case 'B': return 'BLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'TIMESTAMP';
|
||||
|
||||
case 'L': return 'SMALLINT';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INTEGER';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'DOUBLE';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
// ifx
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';// 255
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'NVARCHAR';
|
||||
case 'X2': return 'TEXT';
|
||||
|
||||
case 'B': return 'BLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATETIME';
|
||||
|
||||
case 'L': return 'SMALLINT';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INTEGER';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'FLOAT';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
*/
|
||||
?>
|
67
phpgwapi/inc/adodb/datadict/datadict-ibase.inc.php
Normal file
67
phpgwapi/inc/adodb/datadict/datadict-ibase.inc.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_ibase extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'ibase';
|
||||
var $seqField = false;
|
||||
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'VARCHAR(4000)';
|
||||
|
||||
case 'C2': return 'VARCHAR'; // up to 32K
|
||||
case 'X2': return 'VARCHAR(4000)';
|
||||
|
||||
case 'B': return 'BLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'TIMESTAMP';
|
||||
|
||||
case 'L': return 'SMALLINT';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INTEGER';
|
||||
case 'I8': return 'INTEGER';
|
||||
|
||||
case 'F': return 'DOUBLE PRECISION';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
80
phpgwapi/inc/adodb/datadict/datadict-informix.inc.php
Normal file
80
phpgwapi/inc/adodb/datadict/datadict-informix.inc.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_informix extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'informix';
|
||||
var $seqField = false;
|
||||
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';// 255
|
||||
case 'XL':
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'NVARCHAR';
|
||||
case 'X2': return 'TEXT';
|
||||
|
||||
case 'B': return 'BLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATETIME';
|
||||
|
||||
case 'L': return 'SMALLINT';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INTEGER';
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
|
||||
case 'F': return 'FLOAT';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("DropColumnSQL not supported");
|
||||
return array();
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
if ($fautoinc) {
|
||||
$ftype = 'SERIAL';
|
||||
return '';
|
||||
}
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
250
phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php
Normal file
250
phpgwapi/inc/adodb/datadict/datadict-mssql.inc.php
Normal file
@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_mssql extends ADODB_DataDict {
|
||||
var $databaseType = 'mssql';
|
||||
|
||||
var $dropIndex = 'DROP INDEX %2$s.%1$s';
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
$len = -1; // mysql max_length is not accurate
|
||||
switch (strtoupper($t)) {
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER': return 'I';
|
||||
case 'BIT':
|
||||
case 'TINYINT': return 'I1';
|
||||
case 'SMALLINT': return 'I2';
|
||||
case 'BIGINT': return 'I8';
|
||||
|
||||
case 'REAL':
|
||||
case 'FLOAT': return 'F';
|
||||
default: return parent::MetaType($t,$len,$fieldobj);
|
||||
}
|
||||
}
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch(strtoupper($meta)) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'NVARCHAR';
|
||||
case 'X2': return 'NTEXT';
|
||||
|
||||
case 'B': return 'IMAGE';
|
||||
|
||||
case 'D': return 'DATETIME';
|
||||
case 'T': return 'DATETIME';
|
||||
case 'L': return 'BIT';
|
||||
|
||||
case 'I': return 'INT';
|
||||
case 'I1': return 'TINYINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INT';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'REAL';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function AddColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$f = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$s = "ALTER TABLE $tabname $this->addCol";
|
||||
foreach($lines as $v) {
|
||||
$f[] = "\n $v";
|
||||
}
|
||||
$s .= implode(',',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/*
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$sql = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
foreach($lines as $v) {
|
||||
$sql[] = "ALTER TABLE $tabname $this->alterCol $v";
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
*/
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
if (!is_array($flds))
|
||||
$flds = explode(',',$flds);
|
||||
$f = array();
|
||||
$s = 'ALTER TABLE ' . $tabname;
|
||||
foreach($flds as $v) {
|
||||
$f[] = "\n$this->dropCol $v";
|
||||
}
|
||||
$s .= implode(',',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fautoinc) $suffix .= ' IDENTITY(1,1)';
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
else if ($suffix == '') $suffix .= ' NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE TABLE
|
||||
[ database_name.[ owner ] . | owner. ] table_name
|
||||
( { < column_definition >
|
||||
| column_name AS computed_column_expression
|
||||
| < table_constraint > ::= [ CONSTRAINT constraint_name ] }
|
||||
|
||||
| [ { PRIMARY KEY | UNIQUE } [ ,...n ]
|
||||
)
|
||||
|
||||
[ ON { filegroup | DEFAULT } ]
|
||||
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
|
||||
|
||||
< column_definition > ::= { column_name data_type }
|
||||
[ COLLATE < collation_name > ]
|
||||
[ [ DEFAULT constant_expression ]
|
||||
| [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
|
||||
]
|
||||
[ ROWGUIDCOL]
|
||||
[ < column_constraint > ] [ ...n ]
|
||||
|
||||
< column_constraint > ::= [ CONSTRAINT constraint_name ]
|
||||
{ [ NULL | NOT NULL ]
|
||||
| [ { PRIMARY KEY | UNIQUE }
|
||||
[ CLUSTERED | NONCLUSTERED ]
|
||||
[ WITH FILLFACTOR = fillfactor ]
|
||||
[ON {filegroup | DEFAULT} ] ]
|
||||
]
|
||||
| [ [ FOREIGN KEY ]
|
||||
REFERENCES ref_table [ ( ref_column ) ]
|
||||
[ ON DELETE { CASCADE | NO ACTION } ]
|
||||
[ ON UPDATE { CASCADE | NO ACTION } ]
|
||||
[ NOT FOR REPLICATION ]
|
||||
]
|
||||
| CHECK [ NOT FOR REPLICATION ]
|
||||
( logical_expression )
|
||||
}
|
||||
|
||||
< table_constraint > ::= [ CONSTRAINT constraint_name ]
|
||||
{ [ { PRIMARY KEY | UNIQUE }
|
||||
[ CLUSTERED | NONCLUSTERED ]
|
||||
{ ( column [ ASC | DESC ] [ ,...n ] ) }
|
||||
[ WITH FILLFACTOR = fillfactor ]
|
||||
[ ON { filegroup | DEFAULT } ]
|
||||
]
|
||||
| FOREIGN KEY
|
||||
[ ( column [ ,...n ] ) ]
|
||||
REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
|
||||
[ ON DELETE { CASCADE | NO ACTION } ]
|
||||
[ ON UPDATE { CASCADE | NO ACTION } ]
|
||||
[ NOT FOR REPLICATION ]
|
||||
| CHECK [ NOT FOR REPLICATION ]
|
||||
( search_conditions )
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
|
||||
ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
|
||||
[ WITH < index_option > [ ,...n] ]
|
||||
[ ON filegroup ]
|
||||
< index_option > :: =
|
||||
{ PAD_INDEX |
|
||||
FILLFACTOR = fillfactor |
|
||||
IGNORE_DUP_KEY |
|
||||
DROP_EXISTING |
|
||||
STATISTICS_NORECOMPUTE |
|
||||
SORT_IN_TEMPDB
|
||||
}
|
||||
*/
|
||||
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
|
||||
$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
|
||||
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
|
||||
$sql[] = $s;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
function _GetSize($ftype, $ty, $fsize, $fprec)
|
||||
{
|
||||
switch ($ftype) {
|
||||
case 'INT':
|
||||
case 'SMALLINT':
|
||||
case 'TINYINT':
|
||||
case 'BIGINT':
|
||||
return $ftype;
|
||||
}
|
||||
if (strlen($fsize) && $ty != 'X' && $ty != 'B' && strpos($ftype,'(') === false) {
|
||||
$ftype .= "(".$fsize;
|
||||
if (strlen($fprec)) $ftype .= ",".$fprec;
|
||||
$ftype .= ')';
|
||||
}
|
||||
return $ftype;
|
||||
}
|
||||
}
|
||||
?>
|
179
phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php
Normal file
179
phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_mysql extends ADODB_DataDict {
|
||||
var $databaseType = 'mysql';
|
||||
var $alterCol = ' MODIFY COLUMN';
|
||||
var $alterTableAddIndex = true;
|
||||
var $dropTable = 'DROP TABLE IF EXISTS %s'; // requires mysql 3.22 or later
|
||||
|
||||
var $dropIndex = 'DROP INDEX %s ON %s';
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
$len = -1; // mysql max_length is not accurate
|
||||
switch (strtoupper($t)) {
|
||||
case 'STRING':
|
||||
case 'CHAR':
|
||||
case 'VARCHAR':
|
||||
case 'TINYBLOB':
|
||||
case 'TINYTEXT':
|
||||
case 'ENUM':
|
||||
case 'SET':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
case 'LONGTEXT':
|
||||
case 'MEDIUMTEXT':
|
||||
return 'X';
|
||||
|
||||
// php_mysql extension always returns 'blob' even if 'text'
|
||||
// so we have to check whether binary...
|
||||
case 'IMAGE':
|
||||
case 'LONGBLOB':
|
||||
case 'BLOB':
|
||||
case 'MEDIUMBLOB':
|
||||
return !empty($fieldobj->binary) ? 'B' : 'X';
|
||||
|
||||
case 'YEAR':
|
||||
case 'DATE': return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP': return 'T';
|
||||
|
||||
case 'FLOAT':
|
||||
case 'DOUBLE':
|
||||
return 'F';
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER': return (!empty($fieldobj->primary_key)) ? 'R' : 'I';
|
||||
case 'TINYINT': return (!empty($fieldobj->primary_key)) ? 'R' : 'I1';
|
||||
case 'SMALLINT': return (!empty($fieldobj->primary_key)) ? 'R' : 'I2';
|
||||
case 'MEDIUMINT': return (!empty($fieldobj->primary_key)) ? 'R' : 'I4';
|
||||
case 'BIGINT': return (!empty($fieldobj->primary_key)) ? 'R' : 'I8';
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch(strtoupper($meta)) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'LONGTEXT';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'LONGTEXT';
|
||||
|
||||
case 'B': return 'LONGBLOB';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'DATETIME';
|
||||
case 'L': return 'TINYINT';
|
||||
|
||||
case 'R':
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'TINYINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'MEDIUMINT';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'DOUBLE';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
|
||||
{
|
||||
$suffix = '';
|
||||
if ($funsigned) $suffix .= ' UNSIGNED';
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fautoinc) $suffix .= ' AUTO_INCREMENT';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
|
||||
[table_options] [select_statement]
|
||||
create_definition:
|
||||
col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
|
||||
[PRIMARY KEY] [reference_definition]
|
||||
or PRIMARY KEY (index_col_name,...)
|
||||
or KEY [index_name] (index_col_name,...)
|
||||
or INDEX [index_name] (index_col_name,...)
|
||||
or UNIQUE [INDEX] [index_name] (index_col_name,...)
|
||||
or FULLTEXT [INDEX] [index_name] (index_col_name,...)
|
||||
or [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...)
|
||||
[reference_definition]
|
||||
or CHECK (expr)
|
||||
*/
|
||||
|
||||
/*
|
||||
CREATE [UNIQUE|FULLTEXT] INDEX index_name
|
||||
ON tbl_name (col_name[(length)],... )
|
||||
*/
|
||||
|
||||
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
if ($this->alterTableAddIndex) $sql[] = "ALTER TABLE $tabname DROP INDEX $idxname";
|
||||
else $sql[] = sprintf($this->dropIndex, $idxname, $tabname);
|
||||
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if (isset($idxoptions['FULLTEXT'])) {
|
||||
$unique = ' FULLTEXT';
|
||||
} elseif (isset($idxoptions['UNIQUE'])) {
|
||||
$unique = ' UNIQUE';
|
||||
} else {
|
||||
$unique = '';
|
||||
}
|
||||
|
||||
if ( is_array($flds) ) $flds = implode(', ',$flds);
|
||||
|
||||
if ($this->alterTableAddIndex) $s = "ALTER TABLE $tabname ADD $unique INDEX $idxname ";
|
||||
else $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname;
|
||||
|
||||
$s .= ' (' . $flds . ')';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
$sql[] = $s;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
?>
|
277
phpgwapi/inc/adodb/datadict/datadict-oci8.inc.php
Normal file
277
phpgwapi/inc/adodb/datadict/datadict-oci8.inc.php
Normal file
@ -0,0 +1,277 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_oci8 extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'oci8';
|
||||
var $seqField = false;
|
||||
var $seqPrefix = 'SEQ_';
|
||||
var $dropTable = "DROP TABLE %s CASCADE CONSTRAINTS";
|
||||
var $trigPrefix = 'TRIG_';
|
||||
|
||||
function MetaType($t,$len=-1)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
switch (strtoupper($t)) {
|
||||
case 'VARCHAR':
|
||||
case 'VARCHAR2':
|
||||
case 'CHAR':
|
||||
case 'VARBINARY':
|
||||
case 'BINARY':
|
||||
if (isset($this) && $len <= $this->blobSize) return 'C';
|
||||
return 'X';
|
||||
|
||||
case 'NCHAR':
|
||||
case 'NVARCHAR2':
|
||||
case 'NVARCHAR':
|
||||
if (isset($this) && $len <= $this->blobSize) return 'C2';
|
||||
return 'X2';
|
||||
|
||||
case 'NCLOB':
|
||||
case 'CLOB':
|
||||
return 'XL';
|
||||
|
||||
case 'LONG RAW':
|
||||
case 'LONG VARBINARY':
|
||||
case 'BLOB':
|
||||
return 'B';
|
||||
|
||||
case 'DATE':
|
||||
return 'T';
|
||||
|
||||
case 'INT':
|
||||
case 'SMALLINT':
|
||||
case 'INTEGER':
|
||||
return 'I';
|
||||
|
||||
default:
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'X': return 'VARCHAR(4000)';
|
||||
case 'XL': return 'CLOB';
|
||||
|
||||
case 'C2': return 'NVARCHAR';
|
||||
case 'X2': return 'NVARCHAR(2000)';
|
||||
|
||||
case 'B': return 'BLOB';
|
||||
|
||||
case 'D':
|
||||
case 'T': return 'DATE';
|
||||
case 'L': return 'DECIMAL(1)';
|
||||
case 'I1': return 'DECIMAL(3)';
|
||||
case 'I2': return 'DECIMAL(5)';
|
||||
case 'I':
|
||||
case 'I4': return 'DECIMAL(10)';
|
||||
|
||||
case 'I8': return 'DECIMAL(20)';
|
||||
case 'F': return 'DECIMAL';
|
||||
case 'N': return 'DECIMAL';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function CreateDatabase($dbname, $options=false)
|
||||
{
|
||||
$options = $this->_Options($options);
|
||||
$password = isset($options['PASSWORD']) ? $options['PASSWORD'] : 'tiger';
|
||||
$tablespace = isset($options["TABLESPACE"]) ? " DEFAULT TABLESPACE ".$options["TABLESPACE"] : '';
|
||||
$sql[] = "CREATE USER ".$dbname." IDENTIFIED BY ".$password.$tablespace;
|
||||
$sql[] = "GRANT CREATE SESSION, CREATE TABLE,UNLIMITED TABLESPACE,CREATE SEQUENCE TO $dbname";
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AddColumnSQL($tabname, $flds)
|
||||
{
|
||||
$f = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$s = "ALTER TABLE $tabname ADD (";
|
||||
foreach($lines as $v) {
|
||||
$f[] = "\n $v";
|
||||
}
|
||||
|
||||
$s .= implode(',',$f).')';
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
$f = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$s = "ALTER TABLE $tabname MODIFY(";
|
||||
foreach($lines as $v) {
|
||||
$f[] = "\n $v";
|
||||
}
|
||||
$s .= implode(',',$f).')';
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if (!is_array($flds)) $flds = explode(',',$flds);
|
||||
$sql = array();
|
||||
$s = "ALTER TABLE $tabname DROP(";
|
||||
$s .= implode(',',$flds).') CASCADE COSTRAINTS';
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function _DropAutoIncrement($t)
|
||||
{
|
||||
if (strpos($t,'.') !== false) {
|
||||
$tarr = explode('.',$t);
|
||||
return "drop sequence ".$tarr[0].".seq_".$tarr[1];
|
||||
}
|
||||
return "drop sequence seq_".$t;
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
|
||||
{
|
||||
$suffix = '';
|
||||
|
||||
if ($fdefault == "''" && $fnotnull) {// this is null in oracle
|
||||
$fnotnull = false;
|
||||
if ($this->debug) ADOConnection::outp("NOT NULL and DEFAULT='' illegal in Oracle");
|
||||
}
|
||||
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
|
||||
if ($fautoinc) $this->seqField = $fname;
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE or replace TRIGGER jaddress_insert
|
||||
before insert on jaddress
|
||||
for each row
|
||||
begin
|
||||
select seqaddress.nextval into :new.A_ID from dual;
|
||||
end;
|
||||
*/
|
||||
function _Triggers($tabname,$tableoptions)
|
||||
{
|
||||
if (!$this->seqField) return array();
|
||||
|
||||
if ($this->schema) {
|
||||
$t = strpos($tabname,'.');
|
||||
if ($t !== false) $tab = substr($tabname,$t+1);
|
||||
else $tab = $tabname;
|
||||
$seqname = $this->schema.'.'.$this->seqPrefix.$tab;
|
||||
$trigname = $this->schema.'.'.$this->trigPrefix.$this->seqPrefix.$tab;
|
||||
} else {
|
||||
$seqname = $this->seqPrefix.$tabname;
|
||||
$trigname = $this->trigPrefix.$seqname;
|
||||
}
|
||||
if (isset($tableoptions['REPLACE'])) $sql[] = "DROP SEQUENCE $seqname";
|
||||
$seqCache = '';
|
||||
if (isset($tableoptions['SEQUENCE_CACHE'])){$seqCache = $tableoptions['SEQUENCE_CACHE'];}
|
||||
$seqIncr = '';
|
||||
if (isset($tableoptions['SEQUENCE_INCREMENT'])){$seqIncr = ' INCREMENT BY '.$tableoptions['SEQUENCE_INCREMENT'];}
|
||||
$seqStart = '';
|
||||
if (isset($tableoptions['SEQUENCE_START'])){$seqIncr = ' START WITH '.$tableoptions['SEQUENCE_START'];}
|
||||
$sql[] = "CREATE SEQUENCE $seqname $seqStart $seqIncr $seqCache";
|
||||
$sql[] = "CREATE OR REPLACE TRIGGER $trigname BEFORE insert ON $tabname FOR EACH ROW WHEN (NEW.$this->seqField IS NULL OR NEW.$this->seqField = 0) BEGIN select $seqname.nextval into :new.$this->seqField from dual; END;";
|
||||
|
||||
$this->seqField = false;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
|
||||
[table_options] [select_statement]
|
||||
create_definition:
|
||||
col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
|
||||
[PRIMARY KEY] [reference_definition]
|
||||
or PRIMARY KEY (index_col_name,...)
|
||||
or KEY [index_name] (index_col_name,...)
|
||||
or INDEX [index_name] (index_col_name,...)
|
||||
or UNIQUE [INDEX] [index_name] (index_col_name,...)
|
||||
or FULLTEXT [INDEX] [index_name] (index_col_name,...)
|
||||
or [CONSTRAINT symbol] FOREIGN KEY [index_name] (index_col_name,...)
|
||||
[reference_definition]
|
||||
or CHECK (expr)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
function _IndexSQL($idxname, $tabname, $flds,$idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if (isset($idxoptions['BITMAP'])) {
|
||||
$unique = ' BITMAP';
|
||||
} elseif (isset($idxoptions['UNIQUE'])) {
|
||||
$unique = ' UNIQUE';
|
||||
} else {
|
||||
$unique = '';
|
||||
}
|
||||
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
if (isset($idxoptions['oci8']))
|
||||
$s .= $idxoptions['oci8'];
|
||||
|
||||
|
||||
$sql[] = $s;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function GetCommentSQL($table,$col)
|
||||
{
|
||||
$table = $this->connection->qstr($table);
|
||||
$col = $this->connection->qstr($col);
|
||||
return "select comments from USER_COL_COMMENTS where TABLE_NAME=$table and COLUMN_NAME=$col";
|
||||
}
|
||||
|
||||
function SetCommentSQL($table,$col,$cmt)
|
||||
{
|
||||
$cmt = $this->connection->qstr($cmt);
|
||||
return "COMMENT ON COLUMN $table.$col IS $cmt";
|
||||
}
|
||||
}
|
||||
?>
|
217
phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php
Normal file
217
phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_postgres extends ADODB_DataDict {
|
||||
|
||||
var $databaseType = 'postgres';
|
||||
var $seqField = false;
|
||||
var $seqPrefix = 'SEQ_';
|
||||
var $addCol = ' ADD COLUMN';
|
||||
var $quote = '"';
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
switch (strtoupper($t)) {
|
||||
case 'INTERVAL':
|
||||
case 'CHAR':
|
||||
case 'CHARACTER':
|
||||
case 'VARCHAR':
|
||||
case 'NAME':
|
||||
case 'BPCHAR':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
return 'X';
|
||||
|
||||
case 'IMAGE': // user defined type
|
||||
case 'BLOB': // user defined type
|
||||
case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
|
||||
case 'VARBIT':
|
||||
case 'BYTEA':
|
||||
return 'B';
|
||||
|
||||
case 'BOOL':
|
||||
case 'BOOLEAN':
|
||||
return 'L';
|
||||
|
||||
case 'DATE':
|
||||
return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP':
|
||||
case 'TIMESTAMPTZ':
|
||||
return 'T';
|
||||
|
||||
case 'INTEGER': return (empty($fieldobj->primary_key) && empty($fieldobj->unique))? 'I' : 'R';
|
||||
case 'SMALLINT':
|
||||
case 'INT2': return (empty($fieldobj->primary_key) && empty($fieldobj->unique))? 'I2' : 'R';
|
||||
case 'INT4': return (empty($fieldobj->primary_key) && empty($fieldobj->unique))? 'I4' : 'R';
|
||||
case 'BIGINT':
|
||||
case 'INT8': return (empty($fieldobj->primary_key) && empty($fieldobj->unique))? 'I8' : 'R';
|
||||
|
||||
case 'OID':
|
||||
case 'SERIAL':
|
||||
return 'R';
|
||||
|
||||
case 'FLOAT4':
|
||||
case 'FLOAT8':
|
||||
case 'DOUBLE PRECISION':
|
||||
case 'REAL':
|
||||
return 'F';
|
||||
|
||||
default:
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch($meta) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'VARCHAR';
|
||||
case 'X2': return 'TEXT';
|
||||
|
||||
case 'B': return 'BYTEA';
|
||||
|
||||
case 'D': return 'DATE';
|
||||
case 'T': return 'TIMESTAMP';
|
||||
|
||||
case 'L': return 'SMALLINT';
|
||||
case 'I': return 'INTEGER';
|
||||
case 'I1': return 'SMALLINT';
|
||||
case 'I2': return 'INT2';
|
||||
case 'I4': return 'INT4';
|
||||
case 'I8': return 'INT8';
|
||||
|
||||
case 'F': return 'FLOAT8';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
/* The following does not work in Pg 6.0 - does anyone want to contribute code?
|
||||
|
||||
//"ALTER TABLE table ALTER COLUMN column SET DEFAULT mydef" and
|
||||
//"ALTER TABLE table ALTER COLUMN column DROP DEFAULT mydef"
|
||||
//"ALTER TABLE table ALTER COLUMN column SET NOT NULL" and
|
||||
//"ALTER TABLE table ALTER COLUMN column DROP NOT NULL"*/
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("AlterColumnSQL not supported for PostgreSQL");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("DropColumnSQL only works with PostgreSQL 7.3+");
|
||||
return ADODB_DataDict::DropColumnSQL($tabname, $flds)."/* only works for PostgreSQL 7.3+ */";
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
if ($fautoinc) {
|
||||
$ftype = 'SERIAL';
|
||||
return '';
|
||||
}
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
function _DropAutoIncrement($t)
|
||||
{
|
||||
return "drop sequence ".$t."_m_id_seq";
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
|
||||
{ column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ]
|
||||
| table_constraint } [, ... ]
|
||||
)
|
||||
[ INHERITS ( parent_table [, ... ] ) ]
|
||||
[ WITH OIDS | WITHOUT OIDS ]
|
||||
where column_constraint is:
|
||||
[ CONSTRAINT constraint_name ]
|
||||
{ NOT NULL | NULL | UNIQUE | PRIMARY KEY |
|
||||
CHECK (expression) |
|
||||
REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL ]
|
||||
[ ON DELETE action ] [ ON UPDATE action ] }
|
||||
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
|
||||
and table_constraint is:
|
||||
[ CONSTRAINT constraint_name ]
|
||||
{ UNIQUE ( column_name [, ... ] ) |
|
||||
PRIMARY KEY ( column_name [, ... ] ) |
|
||||
CHECK ( expression ) |
|
||||
FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
|
||||
[ MATCH FULL | MATCH PARTIAL ] [ ON DELETE action ] [ ON UPDATE action ] }
|
||||
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
CREATE [ UNIQUE ] INDEX index_name ON table
|
||||
[ USING acc_method ] ( column [ ops_name ] [, ...] )
|
||||
[ WHERE predicate ]
|
||||
CREATE [ UNIQUE ] INDEX index_name ON table
|
||||
[ USING acc_method ] ( func_name( column [, ... ]) [ ops_name ] )
|
||||
[ WHERE predicate ]
|
||||
*/
|
||||
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
|
||||
|
||||
$s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' ';
|
||||
|
||||
if (isset($idxoptions['HASH']))
|
||||
$s .= 'USING HASH ';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s .= '(' . $flds . ')';
|
||||
$sql[] = $s;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
?>
|
228
phpgwapi/inc/adodb/datadict/datadict-sybase.inc.php
Normal file
228
phpgwapi/inc/adodb/datadict/datadict-sybase.inc.php
Normal file
@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB2_sybase extends ADODB_DataDict {
|
||||
var $databaseType = 'sybase';
|
||||
|
||||
var $dropIndex = 'DROP INDEX %2$s.%1$s';
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
$len = -1; // mysql max_length is not accurate
|
||||
switch (strtoupper($t)) {
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER': return 'I';
|
||||
case 'BIT':
|
||||
case 'TINYINT': return 'I1';
|
||||
case 'SMALLINT': return 'I2';
|
||||
case 'BIGINT': return 'I8';
|
||||
|
||||
case 'REAL':
|
||||
case 'FLOAT': return 'F';
|
||||
default: return parent::MetaType($t,$len,$fieldobj);
|
||||
}
|
||||
}
|
||||
|
||||
function ActualType($meta)
|
||||
{
|
||||
switch(strtoupper($meta)) {
|
||||
case 'C': return 'VARCHAR';
|
||||
case 'XL':
|
||||
case 'X': return 'TEXT';
|
||||
|
||||
case 'C2': return 'NVARCHAR';
|
||||
case 'X2': return 'NTEXT';
|
||||
|
||||
case 'B': return 'IMAGE';
|
||||
|
||||
case 'D': return 'DATETIME';
|
||||
case 'T': return 'DATETIME';
|
||||
case 'L': return 'BIT';
|
||||
|
||||
case 'I': return 'INT';
|
||||
case 'I1': return 'TINYINT';
|
||||
case 'I2': return 'SMALLINT';
|
||||
case 'I4': return 'INT';
|
||||
case 'I8': return 'BIGINT';
|
||||
|
||||
case 'F': return 'REAL';
|
||||
case 'N': return 'NUMERIC';
|
||||
default:
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function AddColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$f = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
$s = "ALTER TABLE $tabname $this->addCol";
|
||||
foreach($lines as $v) {
|
||||
$f[] = "\n $v";
|
||||
}
|
||||
$s .= implode(',',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function AlterColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
$sql = array();
|
||||
list($lines,$pkey) = $this->_GenFields($flds);
|
||||
foreach($lines as $v) {
|
||||
$sql[] = "ALTER TABLE $tabname $this->alterCol $v";
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function DropColumnSQL($tabname, $flds)
|
||||
{
|
||||
$tabname = $this->TableName ($tabname);
|
||||
if (!is_array($flds)) $flds = explode(',',$flds);
|
||||
$f = array();
|
||||
$s = "ALTER TABLE $tabname";
|
||||
foreach($flds as $v) {
|
||||
$f[] = "\n$this->dropCol $v";
|
||||
}
|
||||
$s .= implode(',',$f);
|
||||
$sql[] = $s;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// return string must begin with space
|
||||
function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint)
|
||||
{
|
||||
$suffix = '';
|
||||
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
|
||||
if ($fautoinc) $suffix .= ' DEFAULT AUTOINCREMENT';
|
||||
if ($fnotnull) $suffix .= ' NOT NULL';
|
||||
else if ($suffix == '') $suffix .= ' NULL';
|
||||
if ($fconstraint) $suffix .= ' '.$fconstraint;
|
||||
return $suffix;
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE TABLE
|
||||
[ database_name.[ owner ] . | owner. ] table_name
|
||||
( { < column_definition >
|
||||
| column_name AS computed_column_expression
|
||||
| < table_constraint > ::= [ CONSTRAINT constraint_name ] }
|
||||
|
||||
| [ { PRIMARY KEY | UNIQUE } [ ,...n ]
|
||||
)
|
||||
|
||||
[ ON { filegroup | DEFAULT } ]
|
||||
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
|
||||
|
||||
< column_definition > ::= { column_name data_type }
|
||||
[ COLLATE < collation_name > ]
|
||||
[ [ DEFAULT constant_expression ]
|
||||
| [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
|
||||
]
|
||||
[ ROWGUIDCOL]
|
||||
[ < column_constraint > ] [ ...n ]
|
||||
|
||||
< column_constraint > ::= [ CONSTRAINT constraint_name ]
|
||||
{ [ NULL | NOT NULL ]
|
||||
| [ { PRIMARY KEY | UNIQUE }
|
||||
[ CLUSTERED | NONCLUSTERED ]
|
||||
[ WITH FILLFACTOR = fillfactor ]
|
||||
[ON {filegroup | DEFAULT} ] ]
|
||||
]
|
||||
| [ [ FOREIGN KEY ]
|
||||
REFERENCES ref_table [ ( ref_column ) ]
|
||||
[ ON DELETE { CASCADE | NO ACTION } ]
|
||||
[ ON UPDATE { CASCADE | NO ACTION } ]
|
||||
[ NOT FOR REPLICATION ]
|
||||
]
|
||||
| CHECK [ NOT FOR REPLICATION ]
|
||||
( logical_expression )
|
||||
}
|
||||
|
||||
< table_constraint > ::= [ CONSTRAINT constraint_name ]
|
||||
{ [ { PRIMARY KEY | UNIQUE }
|
||||
[ CLUSTERED | NONCLUSTERED ]
|
||||
{ ( column [ ASC | DESC ] [ ,...n ] ) }
|
||||
[ WITH FILLFACTOR = fillfactor ]
|
||||
[ ON { filegroup | DEFAULT } ]
|
||||
]
|
||||
| FOREIGN KEY
|
||||
[ ( column [ ,...n ] ) ]
|
||||
REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
|
||||
[ ON DELETE { CASCADE | NO ACTION } ]
|
||||
[ ON UPDATE { CASCADE | NO ACTION } ]
|
||||
[ NOT FOR REPLICATION ]
|
||||
| CHECK [ NOT FOR REPLICATION ]
|
||||
( search_conditions )
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
|
||||
ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
|
||||
[ WITH < index_option > [ ,...n] ]
|
||||
[ ON filegroup ]
|
||||
< index_option > :: =
|
||||
{ PAD_INDEX |
|
||||
FILLFACTOR = fillfactor |
|
||||
IGNORE_DUP_KEY |
|
||||
DROP_EXISTING |
|
||||
STATISTICS_NORECOMPUTE |
|
||||
SORT_IN_TEMPDB
|
||||
}
|
||||
*/
|
||||
function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
|
||||
{
|
||||
$sql = array();
|
||||
|
||||
if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
|
||||
$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
|
||||
if ( isset($idxoptions['DROP']) )
|
||||
return $sql;
|
||||
}
|
||||
|
||||
if ( empty ($flds) ) {
|
||||
return $sql;
|
||||
}
|
||||
|
||||
$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
|
||||
$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
|
||||
|
||||
if ( is_array($flds) )
|
||||
$flds = implode(', ',$flds);
|
||||
$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
|
||||
|
||||
if ( isset($idxoptions[$this->upperName]) )
|
||||
$s .= $idxoptions[$this->upperName];
|
||||
|
||||
$sql[] = $s;
|
||||
|
||||
return $sql;
|
||||
}
|
||||
}
|
||||
?>
|
3667
phpgwapi/inc/adodb/docs/docs-adodb.htm
Normal file
3667
phpgwapi/inc/adodb/docs/docs-adodb.htm
Normal file
File diff suppressed because it is too large
Load Diff
276
phpgwapi/inc/adodb/docs/docs-datadict.htm
Normal file
276
phpgwapi/inc/adodb/docs/docs-datadict.htm
Normal file
@ -0,0 +1,276 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ADODB Data Dictionary Manual</title>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<style type="text/css">
|
||||
body, td {
|
||||
/*font-family: Arial, Helvetica, sans-serif;*/
|
||||
font-size: 11pt;
|
||||
}
|
||||
pre {
|
||||
font-size: 9pt;
|
||||
background-color: #EEEEEE; padding: .5em; margin: 0px;
|
||||
}
|
||||
.toplink {
|
||||
font-size: 8pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: rgb(255, 255, 255);">
|
||||
<h2>ADOdb Data Dictionary Library for PHP</h2>
|
||||
<p>V4.50 6 July 2004 (c) 2000-2004 John Lim (<a
|
||||
href="mailto:jlim#natsoft.com.my">jlim#natsoft.com.my</a>).<br>
|
||||
AXMLS (c) 2004 ars Cognita, Inc</p>
|
||||
<p><font size="1">This software is dual licensed using BSD-Style and
|
||||
LGPL. This means you can use it in compiled proprietary and commercial
|
||||
products.</font></p>
|
||||
<table border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><font color="red">Kindly note that the ADOdb home page has
|
||||
moved to <a href="http://adodb.sourceforge.net/">http://adodb.sourceforge.net/</a>
|
||||
because of the persistent unreliability of http://php.weblogs.com. <b>Please
|
||||
change your links</b>!</font></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Useful ADOdb links: <a href="http://adodb.sourceforge.net/#download">Download</a>
|
||||
<a href="http://adodb.sourceforge.net/#docs">Other Docs</a>
|
||||
</p>
|
||||
<p>This documentation describes a PHP class library to automate the
|
||||
creation of tables, indexes and foreign key constraints portably for
|
||||
multiple databases. Richard Tango-Lowy and Dan Cech have been kind
|
||||
enough to contribute <a href="#xmlschema">AXMLS</a>, an XML schema
|
||||
system for defining databases. You can contact them at
|
||||
dcech#phpwerx.net and richtl#arscognita.com.</p>
|
||||
<p>Currently the following databases are supported:</p>
|
||||
<p> <b>Well-tested:</b> PostgreSQL, MySQL, Oracle, MSSQL.<br>
|
||||
<b>Beta-quality:</b> DB2, Informix, Sybase, Interbase, Firebird.<br>
|
||||
<b>Alpha-quality:</b> MS Access (does not support DEFAULT values) and
|
||||
generic ODBC.
|
||||
</p>
|
||||
<h3>Example Usage</h3>
|
||||
<pre> include_once('adodb.inc.php');<br> <font color="#006600"># First create a normal connection</font><br> $db->NewADOConnection('mysql');<br> $db->Connect(...);<br><br> <font
|
||||
color="#006600"># Then create a data dictionary object, using this connection</font><br> $dict = <strong>NewDataDictionary</strong>($db);<br><br> <font
|
||||
color="#006600"># We have a portable declarative data dictionary format in ADOdb, similar to SQL.<br> # Field types use 1 character codes, and fields are separated by commas.<br> # The following example creates three fields: "col1", "col2" and "col3":</font><br> $flds = " <br> <font
|
||||
color="#663300"><strong> col1 C(32) NOTNULL DEFAULT 'abc',<br> col2 I DEFAULT 0,<br> col3 N(12.2)</strong></font><br> ";<br><br> <font
|
||||
color="#006600"># We demonstrate creating tables and indexes</font><br> $sqlarray = $dict-><strong>CreateTableSQL</strong>($tabname, $flds, $taboptarray);<br> $dict-><strong>ExecuteSQLArray</strong>($sqlarray);<br><br> $idxflds = 'co11, col2';<br> $sqlarray = $dict-><strong>CreateIndexSQL</strong>($idxname, $tabname, $idxflds);<br> $dict-><strong>ExecuteSQLArray</strong>($sqlarray);<br></pre>
|
||||
<h3>Functions</h3>
|
||||
<h4>function CreateDatabase($dbname, $optionsarray=false)</h4>
|
||||
<p>Create a database with the name $dbname;</p>
|
||||
<h4>function CreateTableSQL($tabname, $fldarray, $taboptarray=false)</h4>
|
||||
<pre> RETURNS: an array of strings, the sql to be executed, or false<br> $tabname: name of table<br> $fldarray: string (or array) containing field info<br> $taboptarray: array containing table options<br></pre>
|
||||
<p>The new format of $fldarray uses a free text format, where each
|
||||
field is comma-delimited.
|
||||
The first token for each field is the field name, followed by the type
|
||||
and optional
|
||||
field size. Then optional keywords in $otheroptions:</p>
|
||||
<pre> "$fieldname $type $colsize $otheroptions"</pre>
|
||||
<p>The older (and still supported) format of $fldarray is a
|
||||
2-dimensional array, where each row in the 1st dimension represents one
|
||||
field. Each row has this format:</p>
|
||||
<pre> array($fieldname, $type, [,$colsize] [,$otheroptions]*)</pre>
|
||||
<p>The first 2 fields must be the field name and the field type. The
|
||||
field type can be a portable type codes or the actual type for that
|
||||
database.</p>
|
||||
<p>Legal portable type codes include:</p>
|
||||
<pre> C: varchar<br> X: Largest varchar size <br> XL: For Oracle, returns CLOB, otherwise same as 'X' above<br><br> C2: Multibyte varchar<br> X2: Multibyte varchar (largest size)<br><br> B: BLOB (binary large object)<br><br> D: Date (some databases do not support this, and we return a datetime type)<br> T: Datetime or Timestamp<br> L: Integer field suitable for storing booleans (0 or 1)<br> I: Integer (mapped to I4)<br> I1: 1-byte integer<br> I2: 2-byte integer<br> I4: 4-byte integer<br> I8: 8-byte integer<br> F: Floating point number<br> N: Numeric or decimal number<br></pre>
|
||||
<p>The $colsize field represents the size of the field. If a decimal
|
||||
number is used, then it is assumed that the number following the dot is
|
||||
the precision, so 6.2 means a number of size 6 digits and 2 decimal
|
||||
places. It is recommended that the default for number types be
|
||||
represented as a string to avoid any rounding errors.</p>
|
||||
<p>The $otheroptions include the following keywords (case-insensitive):</p>
|
||||
<pre> AUTO For autoincrement number. Emulated with triggers if not available.<br> Sets NOTNULL also.<br> AUTOINCREMENT Same as auto.<br> KEY Primary key field. Sets NOTNULL also. Compound keys are supported.<br> PRIMARY Same as KEY.<br> DEF Synonym for DEFAULT for lazy typists.<br> DEFAULT The default value. Character strings are auto-quoted unless<br> the string begins and ends with spaces, eg ' SYSDATE '.<br> NOTNULL If field is not null.<br> DEFDATE Set default value to call function to get today's date.<br> DEFTIMESTAMP Set default to call function to get today's datetime.<br> NOQUOTE Prevents autoquoting of default string values.<br> CONSTRAINTS Additional constraints defined at the end of the field<br> definition.<br></pre>
|
||||
<p>The Data Dictonary accepts two formats, the older array
|
||||
specification:</p>
|
||||
<pre> $flds = array(<br> array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NOTNULL'),<br> array('id', 'I' , 'AUTO'),<br> array('`MY DATE`', 'D' , 'DEFDATE'),<br> array('NAME', 'C' , '32', 'CONSTRAINTS' => 'FOREIGN KEY REFERENCES reftable')<br> );<br></pre>
|
||||
<p>Or the simpler declarative format:</p>
|
||||
<pre> $flds = "<font color="#660000"><strong><br> COLNAME DECIMAL(8.4) DEFAULT 0 NOTNULL,<br> id I AUTO,<br> `MY DATE` D DEFDATE,<br> NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable'</strong></font><br> ";<br></pre>
|
||||
<p>Note that if you have special characters in the field name (e.g. My
|
||||
Date), you should enclose it in back-quotes. Normally field names are
|
||||
not case-sensitive, but if you enclose it in back-quotes, some
|
||||
databases will treat the names as case-sensitive (eg. Oracle) , and
|
||||
others won't. So be careful.</p>
|
||||
<p>The $taboptarray is the 3rd parameter of the CreateTableSQL
|
||||
function. This contains table specific settings. Legal keywords include:</p>
|
||||
<ul>
|
||||
<li><b>REPLACE</b><br>
|
||||
Indicates that the previous table definition should be removed
|
||||
(dropped)together with ALL data. See first example below. </li>
|
||||
<li><b>DROP</b><br>
|
||||
Drop table. Useful for removing unused tables. </li>
|
||||
<li><b>CONSTRAINTS</b><br>
|
||||
Define this as the key, with the constraint as the value. See the
|
||||
postgresql example below. Additional constraints defined for the whole
|
||||
table. You will probably need to prefix this with a comma. </li>
|
||||
</ul>
|
||||
<p>Database specific table options can be defined also using the name
|
||||
of the database type as the array key. In the following example, <em>create
|
||||
the table as ISAM with MySQL, and store the table in the "users"
|
||||
tablespace if using Oracle</em>. And because we specified REPLACE, drop
|
||||
the table first.</p>
|
||||
<pre> $taboptarray = array('mysql' => 'TYPE=ISAM', 'oci8' => 'tablespace users', 'REPLACE');</pre>
|
||||
<p>You can also define foreignkey constraints. The following is syntax
|
||||
for postgresql:
|
||||
</p>
|
||||
<pre> $taboptarray = array('constraints' => ', FOREIGN KEY (col1) REFERENCES reftable (refcol)');</pre>
|
||||
<h4>function DropTableSQL($tabname)</h4>
|
||||
<p>Returns the SQL to drop the specified table.</p>
|
||||
<h4>function ChangeTableSQL($tabname, $flds)</h4>
|
||||
<p>Checks to see if table exists, if table does not exist, behaves like
|
||||
CreateTableSQL. If table exists, generates appropriate ALTER TABLE
|
||||
MODIFY COLUMN commands if field already exists, or ALTER TABLE ADD
|
||||
$column if field does not exist.</p>
|
||||
<p>The class must be connected to the database for ChangeTableSQL to
|
||||
detect the existence of the table. Idea and code contributed by Florian
|
||||
Buzin.</p>
|
||||
<h4>function CreateIndexSQL($idxname, $tabname, $flds,
|
||||
$idxoptarray=false)</h4>
|
||||
<pre> RETURNS: an array of strings, the sql to be executed, or false<br> $idxname: name of index<br> $tabname: name of table<br> $flds: list of fields as a comma delimited string or an array of strings<br> $idxoptarray: array of index creation options<br></pre>
|
||||
<p>$idxoptarray is similar to $taboptarray in that index specific
|
||||
information can be embedded in the array. Other options include:</p>
|
||||
<pre> CLUSTERED Create clustered index (only mssql)<br> BITMAP Create bitmap index (only oci8)<br> UNIQUE Make unique index<br> FULLTEXT Make fulltext index (only mysql)<br> HASH Create hash index (only postgres)<br> DROP Drop legacy index<br></pre>
|
||||
<h4>function DropIndexSQL ($idxname, $tabname = NULL)</h4>
|
||||
<p>Returns the SQL to drop the specified index.</p>
|
||||
<h4>function AddColumnSQL($tabname, $flds)</h4>
|
||||
<p>Add one or more columns. Not guaranteed to work under all situations.</p>
|
||||
<h4>function AlterColumnSQL($tabname, $flds)</h4>
|
||||
<p>Warning, not all databases support this feature.</p>
|
||||
<h4>function DropColumnSQL($tabname, $flds)</h4>
|
||||
<p>Drop 1 or more columns.</p>
|
||||
<h4>function SetSchema($schema)</h4>
|
||||
<p>Set the schema.</p>
|
||||
<h4>function &MetaTables()</h4>
|
||||
<h4>function &MetaColumns($tab, $upper=true, $schema=false)</h4>
|
||||
<h4>function &MetaPrimaryKeys($tab,$owner=false,$intkey=false)</h4>
|
||||
<h4>function &MetaIndexes($table, $primary = false, $owner = false)</h4>
|
||||
<p>These functions are wrappers for the corresponding functions in the
|
||||
connection object. However, the table names will be autoquoted by the
|
||||
TableName function (see below) before being passed to the connection
|
||||
object.</p>
|
||||
<h4>function NameQuote($name = NULL)</h4>
|
||||
<p>If the provided name is quoted with backquotes (`) or contains
|
||||
special characters, returns the name quoted with the appropriate quote
|
||||
character, otherwise the name is returned unchanged.</p>
|
||||
<h4>function TableName($name)</h4>
|
||||
<p>The same as NameQuote, but will prepend the current schema if
|
||||
specified</p>
|
||||
<h4>function MetaType($t,$len=-1,$fieldobj=false)</h4>
|
||||
<h4>function ActualType($meta)</h4>
|
||||
<p>Convert between database-independent 'Meta' and database-specific
|
||||
'Actual' type codes.</p>
|
||||
<h4>function ExecuteSQLArray($sqlarray, $contOnError = true)</h4>
|
||||
<pre> RETURNS: 0 if failed, 1 if executed all but with errors, 2 if executed successfully<br> $sqlarray: an array of strings with sql code (no semicolon at the end of string)<br> $contOnError: if true, then continue executing even if error occurs<br></pre>
|
||||
<p>Executes an array of SQL strings returned by CreateTableSQL or
|
||||
CreateIndexSQL.</p>
|
||||
<hr>
|
||||
<a name="xmlschema"></a>
|
||||
<h2>ADOdb XML Schema (AXMLS)</h2>
|
||||
<p>This is a class contributed by Richard Tango-Lowy and Dan Cech that
|
||||
allows the user to quickly
|
||||
and easily build a database using the excellent ADODB database library
|
||||
and a simple XML formatted file.
|
||||
You can <a href="http://sourceforge.net/projects/adodb-xmlschema/">download
|
||||
the latest version of AXMLS here</a>.</p>
|
||||
<h3>Quick Start</h3>
|
||||
<p>Adodb-xmlschema, or AXMLS, is a set of classes that allow the user
|
||||
to quickly and easily build or upgrade a database on almost any RDBMS
|
||||
using the excellent ADOdb database library and a simple XML formatted
|
||||
schema file. Our goal is to give developers a tool that's simple to
|
||||
use, but that will allow them to create a single file that can build,
|
||||
upgrade, and manipulate databases on most RDBMS platforms.</p>
|
||||
<span style="font-weight: bold;"> Installing axmls</span>
|
||||
<p>The easiest way to install AXMLS to download and install any recent
|
||||
version of the ADOdb database abstraction library. To install AXMLS
|
||||
manually, simply copy the adodb-xmlschema.inc.php file and the xsl
|
||||
directory into your adodb directory.</p>
|
||||
<span style="font-weight: bold;"> Using AXMLS in Your Application</span>
|
||||
<p>There are two steps involved in using AXMLS in your application:
|
||||
first, you must create a schema, or XML representation of your
|
||||
database, and second, you must create the PHP code that will parse and
|
||||
execute the schema.</p>
|
||||
<p>Let's begin with a schema that describes a typical, if simplistic
|
||||
user management table for an application.</p>
|
||||
<pre class="listing"><pre><?xml version="1.0"?><br><schema version="0.2"><br><br> <table name="users"><br> <desc>A typical users table for our application.</desc><br> <field name="userId" type="I"><br> <descr>A unique ID assigned to each user.</descr><br><br> <KEY/><br> <AUTOINCREMENT/><br> </field><br> <br> <field name="userName" type="C" size="16"><NOTNULL/></field><br><br> <br> <index name="userName"><br> <descr>Put a unique index on the user name</descr><br> <col>userName</col><br> <UNIQUE/><br><br> </index><br> </table><br> <br> <sql><br> <descr>Insert some data into the users table.</descr><br> <query>insert into users (userName) values ( 'admin' )</query><br><br> <query>insert into users (userName) values ( 'Joe' )</query><br> </sql><br></schema> <br></pre></pre>
|
||||
<p>Let's take a detailed look at this schema.</p>
|
||||
<p>The opening <?xml version="1.0"?> tag is required by XML. The
|
||||
<schema> tag tells the parser that the enclosed markup defines an
|
||||
XML schema. The version="0.2" attribute sets <em>the version of the
|
||||
AXMLS DTD used by the XML schema.</em> </p>
|
||||
<p>All versions of AXMLS prior to version 1.0 have a schema version of
|
||||
"0.1". The current schema version is "0.2".</p>
|
||||
<pre class="listing"><pre><?xml version="1.0"?><br><schema version="0.2"><br> ...<br></schema><br></pre></pre>
|
||||
<p>Next we define one or more tables. A table consists of a fields (and
|
||||
other objects) enclosed by <table> tags. The name="" attribute
|
||||
specifies the name of the table that will be created in the database.</p>
|
||||
<pre class="listing"><pre><table name="users"><br><br> <desc>A typical users table for our application.</desc><br> <field name="userId" type="I"><br><br> <descr>A unique ID assigned to each user.</descr><br> <KEY/><br> <AUTOINCREMENT/><br> </field><br> <br> <field name="userName" type="C" size="16"><NOTNULL/></field><br><br> <br></table><br></pre></pre>
|
||||
<p>This table is called "users" and has a description and two fields.
|
||||
The description is optional, and is currently only for your own
|
||||
information; it is not applied to the database.</p>
|
||||
<p>The first <field> tag will create a field named "userId" of
|
||||
type "I", or integer. (See the ADOdb Data Dictionary documentation for
|
||||
a list of valid types.) This <field> tag encloses two special
|
||||
field options: <KEY/>, which specifies this field as a primary
|
||||
key, and <AUTOINCREMENT/>, which specifies that the database
|
||||
engine should automatically fill this field with the next available
|
||||
value when a new row is inserted.</p>
|
||||
<p>The second <field> tag will create a field named "userName" of
|
||||
type "C", or character, and of length 16 characters. The
|
||||
<NOTNULL/> option specifies that this field does not allow NULLs.</p>
|
||||
<p>There are two ways to add indexes to a table. The simplest is to
|
||||
mark a field with the <KEY/> option as described above; a primary
|
||||
key is a unique index. The second and more powerful method uses the
|
||||
<index> tags.</p>
|
||||
<pre class="listing"><pre><table name="users"><br> ...<br> <br> <index name="userName"><br> <descr>Put a unique index on the user name</descr><br> <col>userName</col><br><br> <UNIQUE/><br> </index><br> <br></table><br></pre></pre>
|
||||
<p>The <index> tag specifies that an index should be created on
|
||||
the enclosing table. The name="" attribute provides the name of the
|
||||
index that will be created in the database. The description, as above,
|
||||
is for your information only. The <col> tags list each column
|
||||
that will be included in the index. Finally, the <UNIQUE/> tag
|
||||
specifies that this will be created as a unique index.</p>
|
||||
<p>Finally, AXMLS allows you to include arbitrary SQL that will be
|
||||
applied to the database when the schema is executed.</p>
|
||||
<pre class="listing"><pre><sql><br> <descr>Insert some data into the users table.</descr><br> <query>insert into users (userName) values ( 'admin' )</query><br><br> <query>insert into users (userName) values ( 'Joe' )</query><br></sql><br></pre></pre>
|
||||
<p>The <sql> tag encloses any number of SQL queries that you
|
||||
define for your own use.</p>
|
||||
<p>Now that we've defined an XML schema, you need to know how to apply
|
||||
it to your database. Here's a simple PHP script that shows how to load
|
||||
the schema.</p>
|
||||
<pre class="listing"><pre><?PHP<br>/* You must tell the script where to find the ADOdb and<br> * the AXMLS libraries.<br> */<br>require( "path_to_adodb/adodb.inc.php");<br>require( "path_to_adodb/adodb-xmlschema.inc.php" );<br><br>/* Configuration information. Define the schema filename,<br> * RDBMS platform (see the ADODB documentation for valid<br> * platform names), and database connection information here.<br> */<br>$schemaFile = 'example.xml';<br>$platform = 'mysql';<br>$dbHost = 'localhost';<br>$dbName = 'database';<br>$dbUser = 'username';<br>$dbPassword = 'password';<br><br>/* Start by creating a normal ADODB connection.<br> */<br>$db = ADONewConnection( $platform );<br>$db->Connect( $dbHost, $dbUser, $dbPassword, $dbName );<br><br>/* Use the database connection to create a new adoSchema object.<br> */<br>$schema = new adoSchema( $db );<br><br>/* Call ParseSchema() to build SQL from the XML schema file.<br> * Then call ExecuteSchema() to apply the resulting SQL to <br> * the database.<br> */<br>$sql = $schema->ParseSchema( $schemaFile );<br>$result = $schema->ExecuteSchema();<br>?><br></pre></pre>
|
||||
<p>Let's look at each part of the example in turn. After you manually
|
||||
create the database, there are three steps required to load (or
|
||||
upgrade) your schema.</p>
|
||||
<p>First, create a normal ADOdb connection. The variables and values
|
||||
here should be those required to connect to your database.</p>
|
||||
<pre class="listing"><pre>$db = ADONewConnection( 'mysql' );<br>$db->Connect( 'host', 'user', 'password', 'database' );<br></pre></pre>
|
||||
<p>Second, create the adoSchema object that load and manipulate your
|
||||
schema. You must pass an ADOdb database connection object in order to
|
||||
create the adoSchema object.</p>
|
||||
<pre class="listing"><pre>$schema = new adoSchema( $db );<br></pre></pre>
|
||||
<p>Third, call ParseSchema() to parse the schema and then
|
||||
ExecuteSchema() to apply it to the database. You must pass
|
||||
ParseSchema() the path and filename of your schema file.</p>
|
||||
<pre class="listing"><pre><br>$schema->ParseSchema( $schemaFile ); <br>$schema->ExecuteSchema(); <br></pre></pre>
|
||||
<p>Execute the above code and then log into your database. If you've
|
||||
done all this right, you should see your tables, indexes, and SQL.</p>
|
||||
<p>You can find the source files for this tutorial in the examples
|
||||
directory as tutorial_shema.xml and tutorial.php. See the class
|
||||
documentation for a more detailed description of the adoSchema methods,
|
||||
including methods and schema elements that are not described in this
|
||||
tutorial.</p>
|
||||
<h3>Upgrading</h3>
|
||||
If your schema version is older, than XSLT is used to transform the
|
||||
schema to the newest version. This means that if you are using an older
|
||||
XML schema format, you need to have the XSLT extension installed.
|
||||
If you do not want to require your users to have the XSLT extension
|
||||
installed, make sure you modify your XML schema to conform to the
|
||||
latest version.
|
||||
<hr>
|
||||
<address>If you have any questions or comments, please email them to
|
||||
Richard at richtl#arscognita.com.
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
972
phpgwapi/inc/adodb/docs/docs-perf.htm
Normal file
972
phpgwapi/inc/adodb/docs/docs-perf.htm
Normal file
@ -0,0 +1,972 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ADOdb Performance Monitoring Library</title>
|
||||
<style type="text/css">
|
||||
body, td {
|
||||
/*font-family: Arial, Helvetica, sans-serif;*/
|
||||
font-size: 11pt;
|
||||
}
|
||||
pre {
|
||||
font-size: 9pt;
|
||||
background-color: #EEEEEE; padding: .5em; margin: 0px;
|
||||
}
|
||||
.toplink {
|
||||
font-size: 8pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>The ADOdb Performance Monitoring Library</h3>
|
||||
<p>V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)</p>
|
||||
<p><font size="1">This software is dual licensed using BSD-Style and
|
||||
LGPL. This means you can use it in compiled proprietary and commercial
|
||||
products.</font></p>
|
||||
<table border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><font color="red">Kindly note that the ADOdb home page has
|
||||
moved to <a href="http://adodb.sourceforge.net/">http://adodb.sourceforge.net/</a>
|
||||
because of the persistent unreliability of http://php.weblogs.com. <b>Please
|
||||
change your links</b>!</font></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Useful ADOdb links: <a href="http://adodb.sourceforge.net/#download">Download</a>
|
||||
<a href="http://adodb.sourceforge.net/#docs">Other Docs</a>
|
||||
</p>
|
||||
<h3>Introduction</h3>
|
||||
<p>This module, part of the ADOdb package, provides both CLI and HTML
|
||||
interfaces for viewing key performance indicators of your database.
|
||||
This is very useful because web apps such as the popular phpMyAdmin
|
||||
currently do not provide effective database health monitoring tools.
|
||||
The module provides the following: </p>
|
||||
<ul>
|
||||
<li>A quick health check of your database server using <code>$perf->HealthCheck()</code>
|
||||
or <code>$perf->HealthCheckCLI()</code>. </li>
|
||||
<li>User interface for performance monitoring, <code>$perf->UI()</code>.
|
||||
This UI displays:
|
||||
<ul>
|
||||
<li>the health check, </li>
|
||||
<li>all SQL logged and their query plans, </li>
|
||||
<li>a list of all tables in the current database</li>
|
||||
<li>an interface to continiously poll the server for key
|
||||
performance indicators such as CPU, Hit Ratio, Disk I/O</li>
|
||||
<li>a form where you can enter and run SQL interactively.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Gives you an API to build database monitoring tools for a server
|
||||
farm, for example calling <code>$perf->DBParameter('data cache hit
|
||||
ratio')</code> returns this very important statistic in a database
|
||||
independant manner. </li>
|
||||
</ul>
|
||||
<p>ADOdb also has the ability to log all SQL executed, using <a
|
||||
href="docs-adodb.htm#logsql">LogSQL</a>. All SQL logged can be
|
||||
analyzed through the performance monitor <a href="#ui">UI</a>. In the <i>View
|
||||
SQL</i> mode, we categorize the SQL into 3 types:
|
||||
</p>
|
||||
<ul>
|
||||
<li><b>Suspicious SQL</b>: queries with high average execution times,
|
||||
and are potential candidates for rewriting</li>
|
||||
<li><b>Expensive SQL</b>: queries with high total execution times
|
||||
(#executions * avg execution time). Optimizing these queries will
|
||||
reduce your database server load.</li>
|
||||
<li><b>Invalid SQL</b>: queries that generate errors.</li>
|
||||
</ul>
|
||||
<p>Each query is hyperlinked to a description of the query plan, and
|
||||
every PHP script that executed that query is also shown.</p>
|
||||
<p>Please note that the information presented is a very basic database
|
||||
health check, and does not provide a complete overview of database
|
||||
performance. Although some attempt has been made to make it work across
|
||||
multiple databases in the same way, it is impossible to do so. For the
|
||||
health check, we do try to display the following key database
|
||||
parameters for all drivers:</p>
|
||||
<ul>
|
||||
<li><b>data cache size</b> - The amount of memory allocated to the
|
||||
cache.</li>
|
||||
<li><b>data cache hit ratio</b> - A measure of how effective the
|
||||
cache is, as a percentage. The higher, the better.</li>
|
||||
<li><b>current connections</b> - The number of sessions currently
|
||||
connected to the database. </li>
|
||||
</ul>
|
||||
<p>You will need to connect to the database as an administrator to view
|
||||
most of the parameters. </p>
|
||||
<p>Code improvements as very welcome, particularly adding new database
|
||||
parameters and automated tuning hints.</p>
|
||||
<a name="usage"></a>
|
||||
<h3>Usage</h3>
|
||||
<p>Currently, the following drivers: <em>mysql</em>, <em>postgres</em>,
|
||||
<em>oci8</em>, <em>mssql</em>, <i>informix</i> and <em>db2</em> are
|
||||
supported. To create a new performance monitor, call NewPerfMonitor( )
|
||||
as demonstrated below: </p>
|
||||
<pre><?php<br>include_once('adodb.inc.php');<br>session_start(); <font
|
||||
color="#006600"># session variables required for monitoring</font><br>$conn = ADONewConnection($driver);<br>$conn->Connect($server,$user,$pwd,$db);<br>$perf =& NewPerfMonitor($conn);<br>$perf->UI($pollsecs=5);<br>?><br></pre>
|
||||
<p>It is also possible to retrieve a single database parameter:</p>
|
||||
<pre>$size = $perf->DBParameter('data cache size');<br></pre>
|
||||
<p>
|
||||
Thx to Fernando Ortiz for the informix module. </p>
|
||||
<h3>Methods</h3>
|
||||
<a name="ui"></a>
|
||||
<p><font face="Courier New, Courier, mono">function <b>UI($pollsecs=5)</b></font></p>
|
||||
<p>Creates a web-based user interface for performance monitoring. When
|
||||
you click on Poll, server statistics will be displayed every $pollsecs
|
||||
seconds. See <a href="#usage">Usage</a> above. </p>
|
||||
<p>Since 4.11, we allow users to enter and run SQL interactively via
|
||||
the "Run SQL" link. To disable this for security reasons, set this
|
||||
constant before calling $perf->UI(). </p>
|
||||
<p> </p>
|
||||
<pre>define('ADODB_PERF_NO_RUN_SQL',1);</pre>
|
||||
<p>Sample output follows below:</p>
|
||||
<table bgcolor="lightyellow" border="1" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td> <b><a href="http://php.weblogs.com/adodb?perf=1">ADOdb</a>
|
||||
Performance Monitor</b> for localhost, db=test<br>
|
||||
<font size="-1">PostgreSQL 7.3.2 on i686-pc-cygwin, compiled by
|
||||
GCC gcc (GCC) 3.2 20020927 (prerelease)</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <a href="#">Performance Stats</a> <a href="#">View
|
||||
SQL</a> <a href="#">View Tables</a> <a href="#">Poll
|
||||
Stats</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>postgres7</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Parameter</b></td>
|
||||
<td><b>Value</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Ratios</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>statistics collector</td>
|
||||
<td>TRUE</td>
|
||||
<td>Value must be TRUE to enable hit ratio statistics (<i>stats_start_collector</i>,<i>stats_row_level</i>
|
||||
and <i>stats_block_level</i> must be set to true in postgresql.conf)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache hit ratio</td>
|
||||
<td>99.7967555299239</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>IO</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data reads</td>
|
||||
<td>125</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data writes</td>
|
||||
<td>21.78125000000000000</td>
|
||||
<td>Count of inserts/updates/deletes * coef</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Data Cache</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache buffers</td>
|
||||
<td>640</td>
|
||||
<td>Number of cache buffers. <a
|
||||
href="http://www.varlena.com/GeneralBits/Tidbits/perf.html#basic">Tuning</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cache blocksize</td>
|
||||
<td>8192</td>
|
||||
<td>(estimate)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache size</td>
|
||||
<td>5M</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>operating system cache size</td>
|
||||
<td>80M</td>
|
||||
<td>(effective cache size)</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Memory Usage</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sort buffer size</td>
|
||||
<td>1M</td>
|
||||
<td>Size of sort buffer (per query)</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Connections</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>current connections</td>
|
||||
<td>0</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max connections</td>
|
||||
<td>32</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Parameters</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rollback buffers</td>
|
||||
<td>8</td>
|
||||
<td>WAL buffers</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>random page cost</td>
|
||||
<td>4</td>
|
||||
<td>Cost of doing a seek (default=4). See <a
|
||||
href="http://www.varlena.com/GeneralBits/Tidbits/perf.html#less">random_page_cost</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><font face="Courier New, Courier, mono">function <b>HealthCheck</b>()</font></p>
|
||||
<p>Returns database health check parameters as a HTML table. You will
|
||||
need to echo or print the output of this function,</p>
|
||||
<p><font face="Courier New, Courier, mono">function <b>HealthCheckCLI</b>()</font></p>
|
||||
<p>Returns database health check parameters formatted for a command
|
||||
line interface. You will need to echo or print the output of this
|
||||
function. Sample output for mysql:</p>
|
||||
<pre>-- Ratios -- <br> MyISAM cache hit ratio => 56.5635738832 <br> InnoDB cache hit ratio => 0 <br> sql cache hit ratio => 0 <br> -- IO -- <br> data reads => 2622 <br> data writes => 2415.5 <br> -- Data Cache -- <br> MyISAM data cache size => 512K <br> BDB data cache size => 8388600<br> InnoDB data cache size => 8M<br> -- Memory Pools -- <br> read buffer size => 131072 <br> sort buffer size => 65528 <br> table cache => 4 <br> -- Connections -- <br> current connections => 3<br> max connections => 100</pre>
|
||||
<p><font face="Courier New, Courier, mono">function <b>Poll</b>($pollSecs=5)
|
||||
</font> </p>
|
||||
<p> Run in infinite loop, displaying the following information every
|
||||
$pollSecs. This will not work properly if output buffering is enabled.
|
||||
In the example below, $pollSecs=3:
|
||||
</p>
|
||||
<pre>Accumulating statistics...<br> Time WS-CPU% Hit% Sess Reads/s Writes/s<br>11:08:30 0.7 56.56 1 0.0000 0.0000<br>11:08:33 1.8 56.56 2 0.0000 0.0000<br>11:08:36 11.1 56.55 3 2.5000 0.0000<br>11:08:39 9.8 56.55 2 3.1121 0.0000<br>11:08:42 2.8 56.55 1 0.0000 0.0000<br>11:08:45 7.4 56.55 2 0.0000 1.5000<br></pre>
|
||||
<p><b>WS-CPU%</b> is the Web Server CPU load of the server that PHP is
|
||||
running from (eg. the database client), and not the database. The <b>Hit%</b>
|
||||
is the data cache hit ratio. <b>Sess</b> is the current number of
|
||||
sessions connected to the database. If you are using persistent
|
||||
connections, this should not change much. The <b>Reads/s</b> and <b>Writes/s</b>
|
||||
are synthetic values to give the viewer a rough guide to I/O, and are
|
||||
not to be taken literally. </p>
|
||||
<p><font face="Courier New, Courier, mono">function <b>SuspiciousSQL</b>($numsql=10)</font></p>
|
||||
<p>Returns SQL which have high average execution times as a HTML table.
|
||||
Each sql statement
|
||||
is hyperlinked to a new window which details the execution plan and the
|
||||
scripts that execute this SQL.
|
||||
</p>
|
||||
<p> The number of statements returned is determined by $numsql. Data is
|
||||
taken from the adodb_logsql table, where the sql statements are logged
|
||||
when
|
||||
$connection->LogSQL(true) is enabled. The adodb_logsql table is
|
||||
populated using <a href="docs-adodb.htm#logsql">$conn->LogSQL</a>.
|
||||
</p>
|
||||
<p>For Oracle, Ixora Suspicious SQL returns a list of SQL statements
|
||||
that are most cache intensive as a HTML table. These are data intensive
|
||||
SQL statements that could benefit most from tuning. </p>
|
||||
<p><font face="Courier New, Courier, mono">function <b>ExpensiveSQL</b>($numsql=10)</font></p>
|
||||
<p>Returns SQL whose total execution time (avg time * #executions) is
|
||||
high as a HTML table. Each sql statement
|
||||
is hyperlinked to a new window which details the execution plan and the
|
||||
scripts that execute this SQL.
|
||||
</p>
|
||||
<p> The number of statements returned is determined by $numsql. Data is
|
||||
taken from the adodb_logsql table, where the sql statements are logged
|
||||
when
|
||||
$connection->LogSQL(true) is enabled. The adodb_logsql table is
|
||||
populated using <a href="docs-adodb.htm#logsql">$conn->LogSQL</a>.
|
||||
</p>
|
||||
<p>For Oracle, Ixora Expensive SQL returns a list of SQL statements
|
||||
that are taking the most CPU load when run.
|
||||
</p>
|
||||
<p><font face="Courier New, Courier, mono">function <b>InvalidSQL</b>($numsql=10)</font></p>
|
||||
<p>Returns a list of invalid SQL as an HTML table.
|
||||
</p>
|
||||
<p>Data is taken from the adodb_logsql table, where the sql statements
|
||||
are logged when
|
||||
$connection->LogSQL(true) is enabled.
|
||||
</p>
|
||||
<p><font face="Courier New, Courier, mono">function <b>Tables</b>($orderby=1)</font></p>
|
||||
<p>Returns information on all tables in a database, with the first two
|
||||
fields containing the table name and table size, the remaining fields
|
||||
depend on the database driver. If $orderby is set to 1, it will sort by
|
||||
name. If $orderby is set to 2, then it will sort by table size. Some
|
||||
database drivers (mssql and mysql) will ignore the $orderby clause. For
|
||||
postgresql, the information is up-to-date since the last <i>vacuum</i>.
|
||||
Not supported currently for db2.</p>
|
||||
<h3>Raw Functions</h3>
|
||||
<p>Raw functions return values without any formatting.</p>
|
||||
<p><font face="Courier New, Courier, mono">function <b>DBParameter</b>($paramname)</font></p>
|
||||
<p>Returns the value of a database parameter, such as
|
||||
$this->DBParameter("data cache size").</p>
|
||||
<p><font face="Courier New, Courier, mono">function <b>CPULoad</b>()</font></p>
|
||||
<p>Returns the CPU load of the database client (NOT THE SERVER) as a
|
||||
percentage. Only works for Linux and Windows. For Windows, WMI must be
|
||||
available.</p>
|
||||
<h3>Format of $settings Property</h3>
|
||||
<p> To create new database parameters, you need to understand
|
||||
$settings. The $settings data structure is an associative array. Each
|
||||
element of the array defines a database parameter. The key is the name
|
||||
of the database parameter. If no key is defined, then it is assumed to
|
||||
be a section break, and the value is the name of the section break. If
|
||||
this is too confusing, looking at the source code will help a lot!</p>
|
||||
<p> Each database parameter is itself an array consisting of the
|
||||
following elements:</p>
|
||||
<ol start="0">
|
||||
<li> Category code, used to group related db parameters. If the
|
||||
category code is 'HIDE', then
|
||||
the database parameter is not shown when HTML() is called. <br>
|
||||
</li>
|
||||
<li> either
|
||||
<ol type="a">
|
||||
<li>sql string to retrieve value, eg. "select value from
|
||||
v\$parameter where name='db_block_size'", </li>
|
||||
<li>array holding sql string and field to look for, e.g.
|
||||
array('show variables','table_cache'); optional 3rd parameter is the
|
||||
$rs->fields[$index] to use (otherwise $index=1), and optional 4th
|
||||
parameter is a constant to multiply the result with (typically 100 for
|
||||
percentage calculations),</li>
|
||||
<li>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', <br>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li> Description of database parameter. If description begins with an
|
||||
=, then it is interpreted as a method call, just as in (1c) above,
|
||||
taking one parameter, the current value. E.g. '=GetIndexDescription'
|
||||
will invoke $this->GetIndexDescription($val). This is useful for
|
||||
generating tuning suggestions. For an example, see WarnCacheRatio().</li>
|
||||
</ol>
|
||||
<p>Example from MySQL, table_cache database parameter:</p>
|
||||
<pre>'table cache' => array('CACHE', # category code<br> array("show variables", 'table_cache'), # array (type 1b)<br> 'Number of tables to keep open'), # description</pre>
|
||||
<h3>Example Health Check Output</h3>
|
||||
<p><a href="#db2">db2</a> <a href="#informix">informix</a> <a
|
||||
href="#mysql">mysql</a> <a href="#mssql">mssql</a> <a href="#oci8">oci8</a>
|
||||
<a href="#postgres">postgres</a></p>
|
||||
<p><a name="db2"></a></p>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>db2</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Parameter</b></td>
|
||||
<td><b>Value</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Ratios</i> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#ffffff">
|
||||
<td>data cache hit ratio</td>
|
||||
<td>0 </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Data Cache</i></td>
|
||||
</tr>
|
||||
<tr bgcolor="#ffffff">
|
||||
<td>data cache buffers</td>
|
||||
<td>250 </td>
|
||||
<td>See <a
|
||||
href="http://www7b.boulder.ibm.com/dmdd/library/techarticle/anshum/0107anshum.html#bufferpoolsize">tuning
|
||||
reference</a>.</td>
|
||||
</tr>
|
||||
<tr bgcolor="#ffffff">
|
||||
<td>cache blocksize</td>
|
||||
<td>4096 </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#ffffff">
|
||||
<td>data cache size</td>
|
||||
<td>1000K </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Connections</i></td>
|
||||
</tr>
|
||||
<tr bgcolor="#ffffff">
|
||||
<td>current connections</td>
|
||||
<td>2 </td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p> </p>
|
||||
<p><a name="informix"></a>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>informix</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Parameter</b></td>
|
||||
<td><b>Val
|
||||
ue</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Ratios</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache hit
|
||||
ratio</td>
|
||||
<td>95.89</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>IO</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data
|
||||
reads</td>
|
||||
<td>1883884</td>
|
||||
<td>Page reads</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data writes</td>
|
||||
<td>1716724</td>
|
||||
<td>Page writes</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Connections</i>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>current connections</td>
|
||||
<td>263.0</td>
|
||||
<td>Number of
|
||||
sessions</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
<p> </p>
|
||||
<p><a name="mysql" id="mysql"></a></p>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>mysql</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Parameter</b></td>
|
||||
<td><b>Value</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Ratios</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MyISAM cache hit ratio</td>
|
||||
<td>56.5658301822</td>
|
||||
<td><font color="red"><b>Cache ratio should be at least 90%</b></font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>InnoDB cache hit ratio</td>
|
||||
<td>0</td>
|
||||
<td><font color="red"><b>Cache ratio should be at least 90%</b></font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sql cache hit ratio</td>
|
||||
<td>0</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>IO</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data reads</td>
|
||||
<td>2622</td>
|
||||
<td>Number of selects (Key_reads is not accurate)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data writes</td>
|
||||
<td>2415.5</td>
|
||||
<td>Number of inserts/updates/deletes * coef (Key_writes is not
|
||||
accurate)</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Data Cache</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MyISAM data cache size</td>
|
||||
<td>512K</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>BDB data cache size</td>
|
||||
<td>8388600</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>InnoDB data cache size</td>
|
||||
<td>8M</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Memory Pools</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>read buffer size</td>
|
||||
<td>131072</td>
|
||||
<td>(per session)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sort buffer size</td>
|
||||
<td>65528</td>
|
||||
<td>Size of sort buffer (per session)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>table cache</td>
|
||||
<td>4</td>
|
||||
<td>Number of tables to keep open</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Connections</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>current connections</td>
|
||||
<td>3</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max connections</td>
|
||||
<td>100</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p> </p>
|
||||
<p><a name="mssql" id="mssql"></a></p>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>mssql</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Parameter</b></td>
|
||||
<td><b>Value</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Ratios</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache hit ratio</td>
|
||||
<td>99.9999694824</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>prepared sql hit ratio</td>
|
||||
<td>99.7738579828</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>adhoc sql hit ratio</td>
|
||||
<td>98.4540169133</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>IO</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data reads</td>
|
||||
<td>2858</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data writes</td>
|
||||
<td>1438</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Data Cache</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache size</td>
|
||||
<td>4362</td>
|
||||
<td>in K</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Connections</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>current connections</td>
|
||||
<td>14</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max connections</td>
|
||||
<td>32767</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p> </p>
|
||||
<p><a name="oci8" id="oci8"></a></p>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>oci8</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Parameter</b></td>
|
||||
<td><b>Value</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Ratios</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache hit ratio</td>
|
||||
<td>96.98</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sql cache hit ratio</td>
|
||||
<td>99.96</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>IO</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data reads</td>
|
||||
<td>842938</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data writes</td>
|
||||
<td>16852</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Data Cache</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache buffers</td>
|
||||
<td>3072</td>
|
||||
<td>Number of cache buffers</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache blocksize</td>
|
||||
<td>8192</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache size</td>
|
||||
<td>48M</td>
|
||||
<td>shared_pool_size</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Memory Pools</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>java pool size</td>
|
||||
<td>0</td>
|
||||
<td>java_pool_size</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sort buffer size</td>
|
||||
<td>512K</td>
|
||||
<td>sort_area_size (per query)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>user session buffer size</td>
|
||||
<td>8M</td>
|
||||
<td>large_pool_size</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Connections</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>current connections</td>
|
||||
<td>1</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max connections</td>
|
||||
<td>170</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache utilization ratio</td>
|
||||
<td>88.46</td>
|
||||
<td>Percentage of data cache actually in use</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>user cache utilization ratio</td>
|
||||
<td>91.76</td>
|
||||
<td>Percentage of user cache (large_pool) actually in use</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rollback segments</td>
|
||||
<td>11</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Transactions</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>peak transactions</td>
|
||||
<td>24</td>
|
||||
<td>Taken from high-water-mark</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max transactions</td>
|
||||
<td>187</td>
|
||||
<td>max transactions / rollback segments < 3.5 (or
|
||||
transactions_per_rollback_segment)</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Parameters</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cursor sharing</td>
|
||||
<td>EXACT</td>
|
||||
<td>Cursor reuse strategy. Recommended is FORCE (8i+) or SIMILAR
|
||||
(9i+). See <a
|
||||
href="http://www.praetoriate.com/oracle_tips_cursor_sharing.htm">cursor_sharing</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>index cache cost</td>
|
||||
<td>0</td>
|
||||
<td>% of indexed data blocks expected in the cache. Recommended
|
||||
is 20-80. Default is 0. See <a
|
||||
href="http://www.dba-oracle.com/oracle_tips_cbo_part1.htm">optimizer_index_caching</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>random page cost</td>
|
||||
<td>100</td>
|
||||
<td>Recommended is 10-50 for TP, and 50 for data warehouses.
|
||||
Default is 100. See <a
|
||||
href="http://www.dba-oracle.com/oracle_tips_cost_adj.htm">optimizer_index_cost_adj</a>.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Suspicious SQL</h3>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>LOAD</b></td>
|
||||
<td><b>EXECUTES</b></td>
|
||||
<td><b>SQL_TEXT</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"> .73%</td>
|
||||
<td align="right">89</td>
|
||||
<td>select u.name, o.name, t.spare1, t.pctfree$ from sys.obj$ o,
|
||||
sys.user$ u, sys.tab$ t where (bitand(t.trigflag, 1048576) = 1048576)
|
||||
and o.obj#=t.obj# and o.owner# = u.user# select i.obj#, i.flags,
|
||||
u.name, o.name from sys.obj$ o, sys.user$ u, sys.ind$ i where
|
||||
(bitand(i.flags, 256) = 256 or bitand(i.flags, 512) = 512) and
|
||||
(not((i.type# = 9) and bitand(i.flags,8) = 8)) and o.obj#=i.obj# and
|
||||
o.owner# = u.user# </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"> .84%</td>
|
||||
<td align="right">3</td>
|
||||
<td>select /*+ RULE */ distinct tabs.table_name, tabs.owner ,
|
||||
partitioned, iot_type , TEMPORARY, table_type, table_type_owner from
|
||||
DBA_ALL_TABLES tabs where tabs.owner = :own </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"> 3.95%</td>
|
||||
<td align="right">6</td>
|
||||
<td>SELECT round(count(1)*avg(buf.block_size)/1048576) FROM
|
||||
DBA_OBJECTS obj, V$BH bh, dba_segments seg, v$buffer_pool buf WHERE
|
||||
obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner =
|
||||
seg.owner and obj.object_name = seg.segment_name and obj.object_type =
|
||||
seg.segment_type and seg.buffer_pool = buf.name and buf.name =
|
||||
'DEFAULT' </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"> 4.50%</td>
|
||||
<td align="right">6</td>
|
||||
<td>SELECT round(count(1)*avg(tsp.block_size)/1048576) FROM
|
||||
DBA_OBJECTS obj, V$BH bh, dba_segments seg, dba_tablespaces tsp WHERE
|
||||
obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner =
|
||||
seg.owner and obj.object_name = seg.segment_name and obj.object_type =
|
||||
seg.segment_type and seg.tablespace_name = tsp.tablespace_name </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">57.34%</td>
|
||||
<td align="right">9267</td>
|
||||
<td>select t.schema, t.name, t.flags, q.name from
|
||||
system.aq$_queue_tables t, sys.aq$_queue_table_affinities aft,
|
||||
system.aq$_queues q where aft.table_objno = t.objno and
|
||||
aft.owner_instance = :1 and q.table_objno = t.objno and q.usage = 0 and
|
||||
bitand(t.flags, 4+16+32+64+128+256) = 0 for update of t.name,
|
||||
aft.table_objno skip locked </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>Expensive SQL</h3>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>LOAD</b></td>
|
||||
<td><b>EXECUTES</b></td>
|
||||
<td><b>SQL_TEXT</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"> 5.24%</td>
|
||||
<td align="right">1</td>
|
||||
<td>select round(sum(bytes)/1048576) from dba_segments </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"> 6.89%</td>
|
||||
<td align="right">6</td>
|
||||
<td>SELECT round(count(1)*avg(buf.block_size)/1048576) FROM
|
||||
DBA_OBJECTS obj, V$BH bh, dba_segments seg, v$buffer_pool buf WHERE
|
||||
obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner =
|
||||
seg.owner and obj.object_name = seg.segment_name and obj.object_type =
|
||||
seg.segment_type and seg.buffer_pool = buf.name and buf.name =
|
||||
'DEFAULT' </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right"> 7.85%</td>
|
||||
<td align="right">6</td>
|
||||
<td>SELECT round(count(1)*avg(tsp.block_size)/1048576) FROM
|
||||
DBA_OBJECTS obj, V$BH bh, dba_segments seg, dba_tablespaces tsp WHERE
|
||||
obj.object_id = bh.objd AND obj.owner != 'SYS' and obj.owner =
|
||||
seg.owner and obj.object_name = seg.segment_name and obj.object_type =
|
||||
seg.segment_type and seg.tablespace_name = tsp.tablespace_name </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">33.69%</td>
|
||||
<td align="right">89</td>
|
||||
<td>select u.name, o.name, t.spare1, t.pctfree$ from sys.obj$ o,
|
||||
sys.user$ u, sys.tab$ t where (bitand(t.trigflag, 1048576) = 1048576)
|
||||
and o.obj#=t.obj# and o.owner# = u.user# </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">36.44%</td>
|
||||
<td align="right">89</td>
|
||||
<td>select i.obj#, i.flags, u.name, o.name from sys.obj$ o,
|
||||
sys.user$ u, sys.ind$ i where (bitand(i.flags, 256) = 256 or
|
||||
bitand(i.flags, 512) = 512) and (not((i.type# = 9) and
|
||||
bitand(i.flags,8) = 8)) and o.obj#=i.obj# and o.owner# = u.user# </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><a name="postgres" id="postgres"></a></p>
|
||||
<table bgcolor="white" border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<h3>postgres7</h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Parameter</b></td>
|
||||
<td><b>Value</b></td>
|
||||
<td><b>Description</b></td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Ratios</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>statistics collector</td>
|
||||
<td>FALSE</td>
|
||||
<td>Must be set to TRUE to enable hit ratio statistics (<i>stats_start_collector</i>,<i>stats_row_level</i>
|
||||
and <i>stats_block_level</i> must be set to true in postgresql.conf)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache hit ratio</td>
|
||||
<td>99.9666031916603</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>IO</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data reads</td>
|
||||
<td>15</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data writes</td>
|
||||
<td>0.000000000000000000</td>
|
||||
<td>Count of inserts/updates/deletes * coef</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Data Cache</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache buffers</td>
|
||||
<td>1280</td>
|
||||
<td>Number of cache buffers. <a
|
||||
href="http://www.varlena.com/GeneralBits/Tidbits/perf.html#basic">Tuning</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cache blocksize</td>
|
||||
<td>8192</td>
|
||||
<td>(estimate)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>data cache size</td>
|
||||
<td>10M</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>operating system cache size</td>
|
||||
<td>80000K</td>
|
||||
<td>(effective cache size)</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Memory Pools</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>sort buffer size</td>
|
||||
<td>1M</td>
|
||||
<td>Size of sort buffer (per query)</td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Connections</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>current connections</td>
|
||||
<td>13</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>max connections</td>
|
||||
<td>32</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr bgcolor="#f0f0f0">
|
||||
<td colspan="3"><i>Parameters</i> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rollback buffers</td>
|
||||
<td>8</td>
|
||||
<td>WAL buffers</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>random page cost</td>
|
||||
<td>4</td>
|
||||
<td>Cost of doing a seek (default=4). See <a
|
||||
href="http://www.varlena.com/GeneralBits/Tidbits/perf.html#less">random_page_cost</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
179
phpgwapi/inc/adodb/docs/docs-session.htm
Normal file
179
phpgwapi/inc/adodb/docs/docs-session.htm
Normal file
@ -0,0 +1,179 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ADODB Session Management Manual</title>
|
||||
<meta http-equiv="Content-Type"
|
||||
content="text/html; charset=iso-8859-1">
|
||||
<style type="text/css">
|
||||
body, td {
|
||||
/*font-family: Arial, Helvetica, sans-serif;*/
|
||||
font-size: 11pt;
|
||||
}
|
||||
pre {
|
||||
font-size: 9pt;
|
||||
background-color: #EEEEEE; padding: .5em; margin: 0px;
|
||||
}
|
||||
.toplink {
|
||||
font-size: 8pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: rgb(255, 255, 255);">
|
||||
<h3>ADODB Session Management Manual</h3>
|
||||
<p>
|
||||
V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)
|
||||
</p>
|
||||
<p> <font size="1">This software is dual licensed using BSD-Style and
|
||||
LGPL. This means you can use it in compiled proprietary and commercial
|
||||
products. </font>
|
||||
<table border="1">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><font color="red">Kindly note that the ADOdb home page has
|
||||
moved to <a href="http://adodb.sourceforge.net/">http://adodb.sourceforge.net/</a>
|
||||
because of the persistent unreliability of http://php.weblogs.com. <b>Please
|
||||
change your links</b>!</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
<p>Useful ADOdb links: <a href="http://adodb.sourceforge.net/#download">Download</a>
|
||||
<a href="http://adodb.sourceforge.net/#docs">Other Docs</a>
|
||||
</p>
|
||||
<h3>Introduction</h3>
|
||||
<p> We store state information specific to a user or web client in
|
||||
session variables. These session variables persist throughout a
|
||||
session, as the user moves from page to page. </p>
|
||||
<p>To use session variables, call session_start() at the beginning of
|
||||
your web page, before your HTTP headers are sent. Then for every
|
||||
variable you want to keep alive for the duration of the session, call
|
||||
session_register($variable_name). By default, the session handler will
|
||||
keep track of the session by using a cookie. You can save objects or
|
||||
arrays in session variables also.
|
||||
</p>
|
||||
<p>The default method of storing sessions is to store it in a file.
|
||||
However if you have special needs such as you:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Have multiple web servers that need to share session info</li>
|
||||
<li>Need to do special processing of each session</li>
|
||||
<li>Require notification when a session expires</li>
|
||||
</ul>
|
||||
<p>Then the ADOdb session handler provides you with the above
|
||||
additional capabilities by storing the session information as records
|
||||
in a database table that can be shared across multiple servers. </p>
|
||||
<p><b>Important Upgrade Notice:</b> Since ADOdb 4.05, the session files
|
||||
have been moved to its own folder, adodb/session. This is a rewrite
|
||||
of the session code by Ross Smith. The old session code is in
|
||||
adodb/session/old. </p>
|
||||
<h4>ADOdb Session Handler Features</h4>
|
||||
<ul>
|
||||
<li>Ability to define a notification function that is called when a
|
||||
session expires. Typically
|
||||
used to detect session logout and release global resources. </li>
|
||||
<li>Optimization of database writes. We crc32 the session data and
|
||||
only perform an update
|
||||
to the session data if there is a data change. </li>
|
||||
<li>Support for large amounts of session data with CLOBs (see
|
||||
adodb-session-clob.php). Useful
|
||||
for Oracle. </li>
|
||||
<li>Support for encrypted session data, see
|
||||
adodb-cryptsession.inc.php. Enabling encryption is simply a matter of
|
||||
including adodb-cryptsession.inc.php instead of adodb-session.inc.php. </li>
|
||||
</ul>
|
||||
<h3>Setup</h3>
|
||||
<p>There are 3 session management files that you can use:
|
||||
</p>
|
||||
<pre>adodb-session.php : The default<br>adodb-session-clob.php : Use this if you are storing DATA in clobs<br>adodb-cryptsession.php : Use this if you want to store encrypted session data in the database<br><br>
|
||||
</pre>
|
||||
<p><strong>Examples</strong>
|
||||
<p><pre>
|
||||
<font
|
||||
color="#004040"> include('adodb/adodb.inc.php');<br> <br><b> $ADODB_SESSION_DRIVER='mysql';<br> $ADODB_SESSION_CONNECT='localhost';<br> $ADODB_SESSION_USER ='scott';<br> $ADODB_SESSION_PWD ='tiger';<br> $ADODB_SESSION_DB ='sessiondb';</b><br> <br> <b>include('adodb/session/adodb-session.php');</b><br> session_start();<br> <br> #<br> # Test session vars, the following should increment on refresh<br> #<br> $_SESSION['AVAR'] += 1;<br> print "<p>\$_SESSION['AVAR']={$_SESSION['AVAR']}</p>";<br></font></pre>
|
||||
<p>To force non-persistent connections, call adodb_session_open first before session_start():<p>
|
||||
<pre>
|
||||
<font color="#004040"><br> include('adodb/adodb.inc.php');<br> <br><b> $ADODB_SESSION_DRIVER='mysql';<br> $ADODB_SESSION_CONNECT='localhost';<br> $ADODB_SESSION_USER ='scott';<br> $ADODB_SESSION_PWD ='tiger';<br> $ADODB_SESSION_DB ='sessiondb';</b><br> <br> <b>include('adodb/session/adodb-session.php');<br> adodb_sess_open(false,false,false);</b><br> session_start();<br> </font>
|
||||
</pre>
|
||||
<p> To use a encrypted sessions, simply replace the file:</p>
|
||||
<pre> <font
|
||||
color="#004040"><br> include('adodb/adodb.inc.php');<br> <br><b> $ADODB_SESSION_DRIVER='mysql';<br> $ADODB_SESSION_CONNECT='localhost';<br> $ADODB_SESSION_USER ='scott';<br> $ADODB_SESSION_PWD ='tiger';<br> $ADODB_SESSION_DB ='sessiondb';<br> <br> include('adodb/session/adodb-cryptsession.php');</b><br> session_start();</font><br>
|
||||
</pre>
|
||||
<p>And the same technique for adodb-session-clob.php:</p>
|
||||
<pre> <font
|
||||
color="#004040"><br> include('adodb/adodb.inc.php');<br> <br><b> $ADODB_SESSION_DRIVER='mysql';<br> $ADODB_SESSION_CONNECT='localhost';<br> $ADODB_SESSION_USER ='scott';<br> $ADODB_SESSION_PWD ='tiger';<br> $ADODB_SESSION_DB ='sessiondb';<br> <br> include('adodb/session/adodb-session-clob.php');</b><br> session_start();</font>
|
||||
</pre>
|
||||
<h4>Installation</h4>
|
||||
<p>1. Create this table in your database (syntax might vary depending on your db):
|
||||
<p><pre> <a
|
||||
name="sessiontab"></a> <font color="#004040"><br> create table sessions (<br> SESSKEY char(32) not null,<br> EXPIRY int(11) unsigned not null,<br> EXPIREREF varchar(64),<br> DATA text not null,<br> primary key (sesskey)<br> );</font><br>
|
||||
</pre>
|
||||
<p> For the adodb-session-clob.php version, create this:
|
||||
<pre>
|
||||
<font
|
||||
color="#004040"><br> create table sessions (<br> SESSKEY char(32) not null,<br> EXPIRY int(11) unsigned not null,<br> EXPIREREF varchar(64),<br> DATA CLOB,<br> primary key (sesskey)<br> );</font>
|
||||
</pre>
|
||||
<p>2. Then define the following parameters. You can either modify this file, or define them before this file is included:
|
||||
<pre> <font
|
||||
color="#004040"><br> $ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';<br> $ADODB_SESSION_CONNECT='server to connect to';<br> $ADODB_SESSION_USER ='user';<br> $ADODB_SESSION_PWD ='password';<br> $ADODB_SESSION_DB ='database';<br> $ADODB_SESSION_TBL = 'sessions'; # setting this is optional<br> </font>
|
||||
</pre><p>
|
||||
When the session is created, $<b>ADODB_SESS_CONN</b> holds the connection object.<br> <br> 3. Recommended is PHP 4.0.6 or later. There are documented session bugs <br> in earlier versions of PHP.
|
||||
<h3>Notifications</h3>
|
||||
<p>If you want to receive notification when a session expires, then tag
|
||||
the session record with a <a href="#sessiontab">EXPIREREF</a> tag (see
|
||||
the definition of the sessions table above). Before any session record
|
||||
is deleted, ADOdb will call a notification function, passing in the
|
||||
EXPIREREF.
|
||||
</p>
|
||||
<p>When a session is first created, we check a global variable
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY. This is an array with 2 elements, the
|
||||
first being the name of the session variable you would like to store in
|
||||
the EXPIREREF field, and the 2nd is the notification function's name. </p>
|
||||
<p> Suppose we want to be notified when a user's session has expired,
|
||||
based on the userid. The user id in the global session variable
|
||||
$USERID. The function name is 'NotifyFn'. So we define: </p>
|
||||
<pre> <font color="#004040"><br> $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');<br> </font></pre>
|
||||
And when the NotifyFn is called (when the session expires), we pass the
|
||||
$USERID as the first parameter, eg. NotifyFn($userid, $sesskey). The
|
||||
session key (which is the primary key of the record in the sessions
|
||||
table) is the 2nd parameter.
|
||||
<p> Here is an example of a Notification function that deletes some
|
||||
records in the database and temporary files: </p>
|
||||
<pre><font color="#004040"><br> function NotifyFn($expireref, $sesskey)<br> {<br> global $ADODB_SESS_CONN; # the session connection object<br><br> $user = $ADODB_SESS_CONN->qstr($expireref);<br> $ADODB_SESS_CONN->Execute("delete from shopping_cart where user=$user");<br> system("rm /work/tmpfiles/$expireref/*");<br> }</font><br> </pre>
|
||||
<p> NOTE 1: If you have register_globals disabled in php.ini, then you
|
||||
will have to manually set the EXPIREREF. E.g. </p>
|
||||
<pre> <font color="#004040">
|
||||
$GLOBALS['USERID'] =& $_SESSION['USERID'];
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');</font>
|
||||
</pre>
|
||||
<p> NOTE 2: If you want to change the EXPIREREF after the session
|
||||
record has been created, you will need to modify any session variable
|
||||
to force a database record update.
|
||||
</p>
|
||||
<h4>Neat Notification Tricks</h4>
|
||||
<p><i>ExpireRef</i> normally holds the user id of the current session.
|
||||
</p>
|
||||
<p>1. You can then write a session monitor, scanning expireref to see
|
||||
who is currently logged on.
|
||||
</p>
|
||||
<p>2. If you delete the sessions record for a specific user, eg.
|
||||
</p>
|
||||
<pre>delete from sessions where expireref = '$USER'<br></pre>
|
||||
then the user is logged out. Useful for ejecting someone from a
|
||||
site.
|
||||
<p>3. You can scan the sessions table to ensure no user
|
||||
can be logged in twice. Useful for security reasons.
|
||||
</p>
|
||||
<h3>Compression/Encryption Schemes</h3>
|
||||
Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and
|
||||
compression schemes are supported. Currently, supported are:
|
||||
<p>
|
||||
<pre> MD5Crypt (crypt.inc.php)<br> MCrypt<br> Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)<br> GZip<br> BZip2<br></pre>
|
||||
<p>These are stackable. E.g.
|
||||
<p><pre>ADODB_Session::filter(new ADODB_Compress_Bzip2());<br>ADODB_Session::filter(new ADODB_Encrypt_MD5());<br></pre>
|
||||
will compress and then encrypt the record in the database.
|
||||
<p>Also see the <a href="docs-adodb.htm">core ADOdb documentation</a>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
86
phpgwapi/inc/adodb/drivers/adodb-access.inc.php
Normal file
86
phpgwapi/inc/adodb/drivers/adodb-access.inc.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Microsoft Access data driver. Requires ODBC. Works only on MS Windows.
|
||||
*/
|
||||
if (!defined('_ADODB_ODBC_LAYER')) {
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
|
||||
}
|
||||
if (!defined('_ADODB_ACCESS')) {
|
||||
define('_ADODB_ACCESS',1);
|
||||
|
||||
class ADODB_access extends ADODB_odbc {
|
||||
var $databaseType = 'access';
|
||||
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
|
||||
var $fmtDate = "#Y-m-d#";
|
||||
var $fmtTimeStamp = "#Y-m-d h:i:sA#"; // note not comma
|
||||
var $_bindInputArray = false; // strangely enough, setting to true does not work reliably
|
||||
var $sysDate = "FORMAT(NOW,'yyyy-mm-dd')";
|
||||
var $sysTimeStamp = 'NOW';
|
||||
var $hasTransactions = false;
|
||||
|
||||
function ADODB_access()
|
||||
{
|
||||
global $ADODB_EXTENSION;
|
||||
|
||||
$ADODB_EXTENSION = false;
|
||||
$this->ADODB_odbc();
|
||||
}
|
||||
|
||||
function Time()
|
||||
{
|
||||
return time();
|
||||
}
|
||||
|
||||
function BeginTrans() { return false;}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " IIF(IsNull($field), $ifNull, $field) "; // if Access
|
||||
}
|
||||
/*
|
||||
function &MetaTables()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$qid = odbc_tables($this->_connectionID);
|
||||
$rs = new ADORecordSet_odbc($qid);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
if (!$rs) return false;
|
||||
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
|
||||
$arr = &$rs->GetArray();
|
||||
//print_pre($arr);
|
||||
$arr2 = array();
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if ($arr[$i][2] && $arr[$i][3] != 'SYSTEM TABLE')
|
||||
$arr2[] = $arr[$i][2];
|
||||
}
|
||||
return $arr2;
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
class ADORecordSet_access extends ADORecordSet_odbc {
|
||||
|
||||
var $databaseType = "access";
|
||||
|
||||
function ADORecordSet_access($id,$mode=false)
|
||||
{
|
||||
return $this->ADORecordSet_odbc($id,$mode);
|
||||
}
|
||||
}// class
|
||||
}
|
||||
?>
|
630
phpgwapi/inc/adodb/drivers/adodb-ado.inc.php
Normal file
630
phpgwapi/inc/adodb/drivers/adodb-ado.inc.php
Normal file
@ -0,0 +1,630 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Microsoft ADO data driver. Requires ADO. Works only on MS Windows.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
define("_ADODB_ADO_LAYER", 1 );
|
||||
/*--------------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
class ADODB_ado extends ADOConnection {
|
||||
var $databaseType = "ado";
|
||||
var $_bindInputArray = false;
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $dataProvider = "ado";
|
||||
var $hasAffectedRows = true;
|
||||
var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary
|
||||
var $_affectedRows = false;
|
||||
var $_thisTransactions;
|
||||
var $_cursor_type = 3; // 3=adOpenStatic,0=adOpenForwardOnly,1=adOpenKeyset,2=adOpenDynamic
|
||||
var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient;
|
||||
var $_lock_type = -1;
|
||||
var $_execute_option = -1;
|
||||
var $poorAffectedRows = true;
|
||||
var $charPage;
|
||||
|
||||
function ADODB_ado()
|
||||
{
|
||||
$this->_affectedRows = new VARIANT;
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider;
|
||||
return array('description' => $desc, 'version' => '');
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
if (PHP_VERSION >= 5) return $this->_affectedRows;
|
||||
|
||||
return $this->_affectedRows->value;
|
||||
}
|
||||
|
||||
// you can also pass a connection string like this:
|
||||
//
|
||||
// $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB');
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argProvider= 'MSDASQL')
|
||||
{
|
||||
$u = 'UID';
|
||||
$p = 'PWD';
|
||||
|
||||
if (!empty($this->charPage))
|
||||
$dbc = new COM('ADODB.Connection',null,$this->charPage);
|
||||
else
|
||||
$dbc = new COM('ADODB.Connection');
|
||||
|
||||
if (! $dbc) return false;
|
||||
|
||||
/* special support if provider is mssql or access */
|
||||
if ($argProvider=='mssql') {
|
||||
$u = 'User Id'; //User parameter name for OLEDB
|
||||
$p = 'Password';
|
||||
$argProvider = "SQLOLEDB"; // SQL Server Provider
|
||||
|
||||
// not yet
|
||||
//if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
|
||||
|
||||
//use trusted conection for SQL if username not specified
|
||||
if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
|
||||
} else if ($argProvider=='access')
|
||||
$argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
|
||||
|
||||
if ($argProvider) $dbc->Provider = $argProvider;
|
||||
|
||||
if ($argUsername) $argHostname .= ";$u=$argUsername";
|
||||
if ($argPassword)$argHostname .= ";$p=$argPassword";
|
||||
|
||||
if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
|
||||
// @ added below for php 4.0.1 and earlier
|
||||
@$dbc->Open((string) $argHostname);
|
||||
|
||||
$this->_connectionID = $dbc;
|
||||
|
||||
$dbc->CursorLocation = $this->_cursor_location;
|
||||
return $dbc->State > 0;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
|
||||
{
|
||||
return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider);
|
||||
}
|
||||
|
||||
/*
|
||||
adSchemaCatalogs = 1,
|
||||
adSchemaCharacterSets = 2,
|
||||
adSchemaCollations = 3,
|
||||
adSchemaColumns = 4,
|
||||
adSchemaCheckConstraints = 5,
|
||||
adSchemaConstraintColumnUsage = 6,
|
||||
adSchemaConstraintTableUsage = 7,
|
||||
adSchemaKeyColumnUsage = 8,
|
||||
adSchemaReferentialContraints = 9,
|
||||
adSchemaTableConstraints = 10,
|
||||
adSchemaColumnsDomainUsage = 11,
|
||||
adSchemaIndexes = 12,
|
||||
adSchemaColumnPrivileges = 13,
|
||||
adSchemaTablePrivileges = 14,
|
||||
adSchemaUsagePrivileges = 15,
|
||||
adSchemaProcedures = 16,
|
||||
adSchemaSchemata = 17,
|
||||
adSchemaSQLLanguages = 18,
|
||||
adSchemaStatistics = 19,
|
||||
adSchemaTables = 20,
|
||||
adSchemaTranslations = 21,
|
||||
adSchemaProviderTypes = 22,
|
||||
adSchemaViews = 23,
|
||||
adSchemaViewColumnUsage = 24,
|
||||
adSchemaViewTableUsage = 25,
|
||||
adSchemaProcedureParameters = 26,
|
||||
adSchemaForeignKeys = 27,
|
||||
adSchemaPrimaryKeys = 28,
|
||||
adSchemaProcedureColumns = 29,
|
||||
adSchemaDBInfoKeywords = 30,
|
||||
adSchemaDBInfoLiterals = 31,
|
||||
adSchemaCubes = 32,
|
||||
adSchemaDimensions = 33,
|
||||
adSchemaHierarchies = 34,
|
||||
adSchemaLevels = 35,
|
||||
adSchemaMeasures = 36,
|
||||
adSchemaProperties = 37,
|
||||
adSchemaMembers = 38
|
||||
|
||||
*/
|
||||
|
||||
function &MetaTables()
|
||||
{
|
||||
$arr= array();
|
||||
$dbc = $this->_connectionID;
|
||||
|
||||
$adors=@$dbc->OpenSchema(20);//tables
|
||||
if ($adors){
|
||||
$f = $adors->Fields(2);//table/view name
|
||||
$t = $adors->Fields(3);//table type
|
||||
while (!$adors->EOF){
|
||||
$tt=substr($t->value,0,6);
|
||||
if ($tt!='SYSTEM' && $tt !='ACCESS')
|
||||
$arr[]=$f->value;
|
||||
//print $f->value . ' ' . $t->value.'<br>';
|
||||
$adors->MoveNext();
|
||||
}
|
||||
$adors->Close();
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
$arr= array();
|
||||
$dbc = $this->_connectionID;
|
||||
|
||||
$adors=@$dbc->OpenSchema(4);//tables
|
||||
|
||||
if ($adors){
|
||||
$t = $adors->Fields(2);//table/view name
|
||||
while (!$adors->EOF){
|
||||
|
||||
|
||||
if (strtoupper($t->Value) == $table) {
|
||||
|
||||
$fld = new ADOFieldObject();
|
||||
$c = $adors->Fields(3);
|
||||
$fld->name = $c->Value;
|
||||
$fld->type = 'CHAR'; // cannot discover type in ADO!
|
||||
$fld->max_length = -1;
|
||||
$arr[strtoupper($fld->name)]=$fld;
|
||||
}
|
||||
|
||||
$adors->MoveNext();
|
||||
}
|
||||
$adors->Close();
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* returns queryID or false */
|
||||
function &_query($sql,$inputarr=false)
|
||||
{
|
||||
|
||||
$dbc = $this->_connectionID;
|
||||
|
||||
// return rs
|
||||
if ($inputarr) {
|
||||
|
||||
if (!empty($this->charPage))
|
||||
$oCmd = new COM('ADODB.Command',null,$this->charPage);
|
||||
else
|
||||
$oCmd = new COM('ADODB.Command');
|
||||
$oCmd->ActiveConnection = $dbc;
|
||||
$oCmd->CommandText = $sql;
|
||||
$oCmd->CommandType = 1;
|
||||
|
||||
foreach($inputarr as $val) {
|
||||
// name, type, direction 1 = input, len,
|
||||
$this->adoParameterType = 130;
|
||||
$p = $oCmd->CreateParameter('name',$this->adoParameterType,1,strlen($val),$val);
|
||||
//print $p->Type.' '.$p->value;
|
||||
$oCmd->Parameters->Append($p);
|
||||
}
|
||||
$p = false;
|
||||
$rs = $oCmd->Execute();
|
||||
$e = $dbc->Errors;
|
||||
if ($dbc->Errors->Count > 0) return false;
|
||||
return $rs;
|
||||
}
|
||||
|
||||
$rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option);
|
||||
/*
|
||||
$rs = new COM('ADODB.Recordset');
|
||||
if ($rs) {
|
||||
$rs->Open ($sql, $dbc, $this->_cursor_type,$this->_lock_type, $this->_execute_option);
|
||||
}
|
||||
*/
|
||||
if ($dbc->Errors->Count > 0) return false;
|
||||
if (! $rs) return false;
|
||||
|
||||
if ($rs->State == 0) return true; // 0 = adStateClosed means no records returned
|
||||
return $rs;
|
||||
}
|
||||
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
|
||||
if (isset($this->_thisTransactions))
|
||||
if (!$this->_thisTransactions) return false;
|
||||
else {
|
||||
$o = $this->_connectionID->Properties("Transaction DDL");
|
||||
$this->_thisTransactions = $o ? true : false;
|
||||
if (!$o) return false;
|
||||
}
|
||||
@$this->_connectionID->BeginTrans();
|
||||
$this->transCnt += 1;
|
||||
return true;
|
||||
}
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
if ($this->transOff) return true;
|
||||
|
||||
@$this->_connectionID->CommitTrans();
|
||||
if ($this->transCnt) @$this->transCnt -= 1;
|
||||
return true;
|
||||
}
|
||||
function RollbackTrans() {
|
||||
if ($this->transOff) return true;
|
||||
@$this->_connectionID->RollbackTrans();
|
||||
if ($this->transCnt) @$this->transCnt -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns: the last error message from previous database operation */
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
$errc = $this->_connectionID->Errors;
|
||||
if ($errc->Count == 0) return '';
|
||||
$err = $errc->Item($errc->Count-1);
|
||||
return $err->Description;
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
$errc = $this->_connectionID->Errors;
|
||||
if ($errc->Count == 0) return 0;
|
||||
$err = $errc->Item($errc->Count-1);
|
||||
return $err->NativeError;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
if ($this->_connectionID) $this->_connectionID->Close();
|
||||
$this->_connectionID = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_ado extends ADORecordSet {
|
||||
|
||||
var $bind = false;
|
||||
var $databaseType = "ado";
|
||||
var $dataProvider = "ado";
|
||||
var $_tarr = false; // caches the types
|
||||
var $_flds; // and field objects
|
||||
var $canSeek = true;
|
||||
var $hideErrors = true;
|
||||
|
||||
function ADORecordSet_ado($id,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
$this->fetchMode = $mode;
|
||||
return $this->ADORecordSet($id,$mode);
|
||||
}
|
||||
|
||||
|
||||
// returns the field object
|
||||
function FetchField($fieldOffset = -1) {
|
||||
$off=$fieldOffset+1; // offsets begin at 1
|
||||
|
||||
$o= new ADOFieldObject();
|
||||
$rs = $this->_queryID;
|
||||
$f = $rs->Fields($fieldOffset);
|
||||
$o->name = $f->Name;
|
||||
$t = $f->Type;
|
||||
$o->type = $this->MetaType($t);
|
||||
$o->max_length = $f->DefinedSize;
|
||||
$o->ado_type = $t;
|
||||
|
||||
|
||||
//print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
|
||||
return $o;
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
$rs = $this->_queryID;
|
||||
$this->_numOfRows = $rs->RecordCount;
|
||||
|
||||
$f = $rs->Fields;
|
||||
$this->_numOfFields = $f->Count;
|
||||
}
|
||||
|
||||
|
||||
// should only be used to move forward as we normally use forward-only cursors
|
||||
function _seek($row)
|
||||
{
|
||||
$rs = $this->_queryID;
|
||||
// absoluteposition doesn't work -- my maths is wrong ?
|
||||
// $rs->AbsolutePosition->$row-2;
|
||||
// return true;
|
||||
if ($this->_currentRow > $row) return false;
|
||||
@$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
OLEDB types
|
||||
|
||||
enum DBTYPEENUM
|
||||
{ DBTYPE_EMPTY = 0,
|
||||
DBTYPE_NULL = 1,
|
||||
DBTYPE_I2 = 2,
|
||||
DBTYPE_I4 = 3,
|
||||
DBTYPE_R4 = 4,
|
||||
DBTYPE_R8 = 5,
|
||||
DBTYPE_CY = 6,
|
||||
DBTYPE_DATE = 7,
|
||||
DBTYPE_BSTR = 8,
|
||||
DBTYPE_IDISPATCH = 9,
|
||||
DBTYPE_ERROR = 10,
|
||||
DBTYPE_BOOL = 11,
|
||||
DBTYPE_VARIANT = 12,
|
||||
DBTYPE_IUNKNOWN = 13,
|
||||
DBTYPE_DECIMAL = 14,
|
||||
DBTYPE_UI1 = 17,
|
||||
DBTYPE_ARRAY = 0x2000,
|
||||
DBTYPE_BYREF = 0x4000,
|
||||
DBTYPE_I1 = 16,
|
||||
DBTYPE_UI2 = 18,
|
||||
DBTYPE_UI4 = 19,
|
||||
DBTYPE_I8 = 20,
|
||||
DBTYPE_UI8 = 21,
|
||||
DBTYPE_GUID = 72,
|
||||
DBTYPE_VECTOR = 0x1000,
|
||||
DBTYPE_RESERVED = 0x8000,
|
||||
DBTYPE_BYTES = 128,
|
||||
DBTYPE_STR = 129,
|
||||
DBTYPE_WSTR = 130,
|
||||
DBTYPE_NUMERIC = 131,
|
||||
DBTYPE_UDT = 132,
|
||||
DBTYPE_DBDATE = 133,
|
||||
DBTYPE_DBTIME = 134,
|
||||
DBTYPE_DBTIMESTAMP = 135
|
||||
|
||||
ADO Types
|
||||
|
||||
adEmpty = 0,
|
||||
adTinyInt = 16,
|
||||
adSmallInt = 2,
|
||||
adInteger = 3,
|
||||
adBigInt = 20,
|
||||
adUnsignedTinyInt = 17,
|
||||
adUnsignedSmallInt = 18,
|
||||
adUnsignedInt = 19,
|
||||
adUnsignedBigInt = 21,
|
||||
adSingle = 4,
|
||||
adDouble = 5,
|
||||
adCurrency = 6,
|
||||
adDecimal = 14,
|
||||
adNumeric = 131,
|
||||
adBoolean = 11,
|
||||
adError = 10,
|
||||
adUserDefined = 132,
|
||||
adVariant = 12,
|
||||
adIDispatch = 9,
|
||||
adIUnknown = 13,
|
||||
adGUID = 72,
|
||||
adDate = 7,
|
||||
adDBDate = 133,
|
||||
adDBTime = 134,
|
||||
adDBTimeStamp = 135,
|
||||
adBSTR = 8,
|
||||
adChar = 129,
|
||||
adVarChar = 200,
|
||||
adLongVarChar = 201,
|
||||
adWChar = 130,
|
||||
adVarWChar = 202,
|
||||
adLongVarWChar = 203,
|
||||
adBinary = 128,
|
||||
adVarBinary = 204,
|
||||
adLongVarBinary = 205,
|
||||
adChapter = 136,
|
||||
adFileTime = 64,
|
||||
adDBFileTime = 137,
|
||||
adPropVariant = 138,
|
||||
adVarNumeric = 139
|
||||
*/
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
if (!is_numeric($t)) return $t;
|
||||
|
||||
switch ($t) {
|
||||
case 0:
|
||||
case 12: // variant
|
||||
case 8: // bstr
|
||||
case 129: //char
|
||||
case 130: //wc
|
||||
case 200: // varc
|
||||
case 202:// varWC
|
||||
case 128: // bin
|
||||
case 204: // varBin
|
||||
case 72: // guid
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 201:
|
||||
case 203:
|
||||
return 'X';
|
||||
case 128:
|
||||
case 204:
|
||||
case 205:
|
||||
return 'B';
|
||||
case 7:
|
||||
case 133: return 'D';
|
||||
|
||||
case 134:
|
||||
case 135: return 'T';
|
||||
|
||||
case 11: return 'L';
|
||||
|
||||
case 16:// adTinyInt = 16,
|
||||
case 2://adSmallInt = 2,
|
||||
case 3://adInteger = 3,
|
||||
case 4://adBigInt = 20,
|
||||
case 17://adUnsignedTinyInt = 17,
|
||||
case 18://adUnsignedSmallInt = 18,
|
||||
case 19://adUnsignedInt = 19,
|
||||
case 20://adUnsignedBigInt = 21,
|
||||
return 'I';
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
// time stamp not supported yet
|
||||
function _fetch()
|
||||
{
|
||||
$rs = $this->_queryID;
|
||||
if (!$rs or $rs->EOF) {
|
||||
$this->fields = false;
|
||||
return false;
|
||||
}
|
||||
$this->fields = array();
|
||||
|
||||
if (!$this->_tarr) {
|
||||
$tarr = array();
|
||||
$flds = array();
|
||||
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
|
||||
$f = $rs->Fields($i);
|
||||
$flds[] = $f;
|
||||
$tarr[] = $f->Type;
|
||||
}
|
||||
// bind types and flds only once
|
||||
$this->_tarr = $tarr;
|
||||
$this->_flds = $flds;
|
||||
}
|
||||
$t = reset($this->_tarr);
|
||||
$f = reset($this->_flds);
|
||||
|
||||
if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
|
||||
for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
|
||||
//echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
|
||||
switch($t) {
|
||||
case 135: // timestamp
|
||||
if (!strlen((string)$f->value)) $this->fields[] = false;
|
||||
else {
|
||||
if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
|
||||
else $val = $f->value;
|
||||
$this->fields[] = adodb_date('Y-m-d H:i:s',$val);
|
||||
}
|
||||
break;
|
||||
case 133:// A date value (yyyymmdd)
|
||||
if ($val = $f->value) {
|
||||
$this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
|
||||
} else
|
||||
$this->fields[] = false;
|
||||
break;
|
||||
case 7: // adDate
|
||||
if (!strlen((string)$f->value)) $this->fields[] = false;
|
||||
else {
|
||||
if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
|
||||
else $val = $f->value;
|
||||
|
||||
if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val);
|
||||
else $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
|
||||
}
|
||||
break;
|
||||
case 1: // null
|
||||
$this->fields[] = false;
|
||||
break;
|
||||
case 6: // currency is not supported properly;
|
||||
ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>');
|
||||
$this->fields[] = (float) $f->value;
|
||||
break;
|
||||
default:
|
||||
$this->fields[] = $f->value;
|
||||
break;
|
||||
}
|
||||
//print " $f->value $t, ";
|
||||
$f = next($this->_flds);
|
||||
$t = next($this->_tarr);
|
||||
} // for
|
||||
if ($this->hideErrors) error_reporting($olde);
|
||||
@$rs->MoveNext(); // @ needed for some versions of PHP!
|
||||
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
$this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function NextRecordSet()
|
||||
{
|
||||
$rs = $this->_queryID;
|
||||
$this->_queryID = $rs->NextRecordSet();
|
||||
//$this->_queryID = $this->_QueryId->NextRecordSet();
|
||||
if ($this->_queryID == null) return false;
|
||||
|
||||
$this->_currentRow = -1;
|
||||
$this->_currentPage = -1;
|
||||
$this->bind = false;
|
||||
$this->fields = false;
|
||||
$this->_flds = false;
|
||||
$this->_tarr = false;
|
||||
|
||||
$this->_inited = false;
|
||||
$this->Init();
|
||||
return true;
|
||||
}
|
||||
|
||||
function _close() {
|
||||
$this->_flds = false;
|
||||
@$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
|
||||
$this->_queryID = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
49
phpgwapi/inc/adodb/drivers/adodb-ado_access.inc.php
Normal file
49
phpgwapi/inc/adodb/drivers/adodb-ado_access.inc.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Microsoft Access ADO data driver. Requires ADO and ODBC. Works only on MS Windows.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('_ADODB_ADO_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-ado.inc.php");
|
||||
}
|
||||
|
||||
class ADODB_ado_access extends ADODB_ado {
|
||||
var $databaseType = 'ado_access';
|
||||
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
|
||||
var $fmtDate = "#Y-m-d#";
|
||||
var $fmtTimeStamp = "#Y-m-d h:i:sA#";// note no comma
|
||||
var $sysDate = "FORMAT(NOW,'yyyy-mm-dd')";
|
||||
var $sysTimeStamp = 'NOW';
|
||||
var $hasTransactions = false;
|
||||
|
||||
function ADODB_ado_access()
|
||||
{
|
||||
$this->ADODB_ado();
|
||||
}
|
||||
|
||||
function BeginTrans() { return false;}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ADORecordSet_ado_access extends ADORecordSet_ado {
|
||||
|
||||
var $databaseType = "ado_access";
|
||||
|
||||
function ADORecordSet_ado_access($id,$mode=false)
|
||||
{
|
||||
return $this->ADORecordSet_ado($id,$mode);
|
||||
}
|
||||
}
|
||||
?>
|
96
phpgwapi/inc/adodb/drivers/adodb-ado_mssql.inc.php
Normal file
96
phpgwapi/inc/adodb/drivers/adodb-ado_mssql.inc.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Microsoft SQL Server ADO data driver. Requires ADO and MSSQL client.
|
||||
Works only on MS Windows.
|
||||
|
||||
It is normally better to use the mssql driver directly because it is much faster.
|
||||
This file is only a technology demonstration and for test purposes.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('_ADODB_ADO_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-ado.inc.php");
|
||||
}
|
||||
|
||||
|
||||
class ADODB_ado_mssql extends ADODB_ado {
|
||||
var $databaseType = 'ado_mssql';
|
||||
var $hasTop = 'top';
|
||||
var $hasInsertID = true;
|
||||
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
||||
var $sysTimeStamp = 'GetDate()';
|
||||
var $leftOuter = '*=';
|
||||
var $rightOuter = '=*';
|
||||
var $ansiOuter = true; // for mssql7 or later
|
||||
var $substr = "substring";
|
||||
var $length = 'len';
|
||||
|
||||
//var $_inTransaction = 1; // always open recordsets, so no transaction problems.
|
||||
|
||||
function ADODB_ado_mssql()
|
||||
{
|
||||
$this->ADODB_ado();
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
return $this->GetOne('select @@identity');
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
return $this->GetOne('select @@rowcount');
|
||||
}
|
||||
|
||||
function MetaColumns($table)
|
||||
{
|
||||
$table = strtoupper($table);
|
||||
$arr= array();
|
||||
$dbc = $this->_connectionID;
|
||||
|
||||
$osoptions = array();
|
||||
$osoptions[0] = null;
|
||||
$osoptions[1] = null;
|
||||
$osoptions[2] = $table;
|
||||
$osoptions[3] = null;
|
||||
|
||||
$adors=@$dbc->OpenSchema(4, $osoptions);//tables
|
||||
|
||||
if ($adors){
|
||||
while (!$adors->EOF){
|
||||
$fld = new ADOFieldObject();
|
||||
$c = $adors->Fields(3);
|
||||
$fld->name = $c->Value;
|
||||
$fld->type = 'CHAR'; // cannot discover type in ADO!
|
||||
$fld->max_length = -1;
|
||||
$arr[strtoupper($fld->name)]=$fld;
|
||||
|
||||
$adors->MoveNext();
|
||||
}
|
||||
$adors->Close();
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
|
||||
class ADORecordSet_ado_mssql extends ADORecordSet_ado {
|
||||
|
||||
var $databaseType = 'ado_mssql';
|
||||
|
||||
function ADORecordSet_ado_mssql($id,$mode=false)
|
||||
{
|
||||
return $this->ADORecordSet_ado($id,$mode);
|
||||
}
|
||||
}
|
||||
?>
|
91
phpgwapi/inc/adodb/drivers/adodb-borland_ibase.inc.php
Normal file
91
phpgwapi/inc/adodb/drivers/adodb-borland_ibase.inc.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Support Borland Interbase 6.5 and later
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
|
||||
|
||||
class ADODB_borland_ibase extends ADODB_ibase {
|
||||
var $databaseType = "borland_ibase";
|
||||
|
||||
function ADODB_borland_ibase()
|
||||
{
|
||||
$this->ADODB_ibase();
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->autoCommit = false;
|
||||
$this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);
|
||||
return $this->_transactionID;
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
$arr['dialect'] = $this->dialect;
|
||||
switch($arr['dialect']) {
|
||||
case '':
|
||||
case '1': $s = 'Interbase 6.5, Dialect 1'; break;
|
||||
case '2': $s = 'Interbase 6.5, Dialect 2'; break;
|
||||
default:
|
||||
case '3': $s = 'Interbase 6.5, Dialect 3'; break;
|
||||
}
|
||||
$arr['version'] = '6.5';
|
||||
$arr['description'] = $s;
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// Note that Interbase 6.5 uses ROWS instead - don't you love forking wars!
|
||||
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
|
||||
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
|
||||
// Firebird uses
|
||||
// SELECT FIRST 5 SKIP 2 col1, col2 FROM TABLE
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
|
||||
{
|
||||
if ($nrows > 0) {
|
||||
if ($offset <= 0) $str = " ROWS $nrows ";
|
||||
else {
|
||||
$a = $offset+1;
|
||||
$b = $offset+$nrows;
|
||||
$str = " ROWS $a TO $b";
|
||||
}
|
||||
} else {
|
||||
// ok, skip
|
||||
$a = $offset + 1;
|
||||
$str = " ROWS $a TO 999999999"; // 999 million
|
||||
}
|
||||
$sql .= $str;
|
||||
|
||||
return ($secs2cache) ?
|
||||
$this->CacheExecute($secs2cache,$sql,$inputarr)
|
||||
:
|
||||
$this->Execute($sql,$inputarr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ADORecordSet_borland_ibase extends ADORecordSet_ibase {
|
||||
|
||||
var $databaseType = "borland_ibase";
|
||||
|
||||
function ADORecordSet_borland_ibase($id,$mode=false)
|
||||
{
|
||||
$this->ADORecordSet_ibase($id,$mode);
|
||||
}
|
||||
}
|
||||
?>
|
203
phpgwapi/inc/adodb/drivers/adodb-csv.inc.php
Normal file
203
phpgwapi/inc/adodb/drivers/adodb-csv.inc.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4.
|
||||
|
||||
Currently unsupported: MetaDatabases, MetaTables and MetaColumns, and also inputarr in Execute.
|
||||
Native types have been converted to MetaTypes.
|
||||
Transactions not supported yet.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (! defined("_ADODB_CSV_LAYER")) {
|
||||
define("_ADODB_CSV_LAYER", 1 );
|
||||
|
||||
include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
|
||||
|
||||
class ADODB_csv extends ADOConnection {
|
||||
var $databaseType = 'csv';
|
||||
var $databaseProvider = 'csv';
|
||||
var $hasInsertID = true;
|
||||
var $hasAffectedRows = true;
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $_affectedrows=0;
|
||||
var $_insertid=0;
|
||||
var $_url;
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $hasTransactions = false;
|
||||
var $_errorNo = false;
|
||||
|
||||
function ADODB_csv()
|
||||
{
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
return $this->_insertid;
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
return $this->_affectedrows;
|
||||
}
|
||||
|
||||
function &MetaDatabases()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (strtolower(substr($argHostname,0,7)) !== 'http://') return false;
|
||||
$this->_url = $argHostname;
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (strtolower(substr($argHostname,0,7)) !== 'http://') return false;
|
||||
$this->_url = $argHostname;
|
||||
return true;
|
||||
}
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// parameters use PostgreSQL convention, not MySQL
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$url = $this->_url.'?sql='.urlencode($sql)."&nrows=$nrows&fetch=".
|
||||
(($this->fetchMode !== false)?$this->fetchMode : $ADODB_FETCH_MODE).
|
||||
"&offset=$offset";
|
||||
$err = false;
|
||||
$rs = csv2rs($url,$err,false);
|
||||
|
||||
if ($this->debug) print "$url<br><i>$err</i><br>";
|
||||
|
||||
$at = strpos($err,'::::');
|
||||
if ($at === false) {
|
||||
$this->_errorMsg = $err;
|
||||
$this->_errorNo = (integer)$err;
|
||||
} else {
|
||||
$this->_errorMsg = substr($err,$at+4,1024);
|
||||
$this->_errorNo = -9999;
|
||||
}
|
||||
if ($this->_errorNo)
|
||||
if ($fn = $this->raiseErrorFn) {
|
||||
$fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,'');
|
||||
}
|
||||
|
||||
if (is_object($rs)) {
|
||||
|
||||
$rs->databaseType='csv';
|
||||
$rs->fetchMode = ($this->fetchMode !== false) ? $this->fetchMode : $ADODB_FETCH_MODE;
|
||||
$rs->connection = &$this;
|
||||
}
|
||||
return $rs;
|
||||
}
|
||||
|
||||
// returns queryID or false
|
||||
function &_Execute($sql,$inputarr=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if (!$this->_bindInputArray && $inputarr) {
|
||||
$sqlarr = explode('?',$sql);
|
||||
$sql = '';
|
||||
$i = 0;
|
||||
foreach($inputarr as $v) {
|
||||
|
||||
$sql .= $sqlarr[$i];
|
||||
if (gettype($v) == 'string')
|
||||
$sql .= $this->qstr($v);
|
||||
else if ($v === null)
|
||||
$sql .= 'NULL';
|
||||
else
|
||||
$sql .= $v;
|
||||
$i += 1;
|
||||
|
||||
}
|
||||
$sql .= $sqlarr[$i];
|
||||
if ($i+1 != sizeof($sqlarr))
|
||||
print "Input Array does not match ?: ".htmlspecialchars($sql);
|
||||
$inputarr = false;
|
||||
}
|
||||
|
||||
$url = $this->_url.'?sql='.urlencode($sql)."&fetch=".
|
||||
(($this->fetchMode !== false)?$this->fetchMode : $ADODB_FETCH_MODE);
|
||||
$err = false;
|
||||
|
||||
|
||||
$rs = csv2rs($url,$err,false);
|
||||
if ($this->debug) print urldecode($url)."<br><i>$err</i><br>";
|
||||
$at = strpos($err,'::::');
|
||||
if ($at === false) {
|
||||
$this->_errorMsg = $err;
|
||||
$this->_errorNo = (integer)$err;
|
||||
} else {
|
||||
$this->_errorMsg = substr($err,$at+4,1024);
|
||||
$this->_errorNo = -9999;
|
||||
}
|
||||
|
||||
if ($this->_errorNo)
|
||||
if ($fn = $this->raiseErrorFn) {
|
||||
$fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr);
|
||||
}
|
||||
if (is_object($rs)) {
|
||||
$rs->fetchMode = ($this->fetchMode !== false) ? $this->fetchMode : $ADODB_FETCH_MODE;
|
||||
|
||||
$this->_affectedrows = $rs->affectedrows;
|
||||
$this->_insertid = $rs->insertid;
|
||||
$rs->databaseType='csv';
|
||||
$rs->connection = &$this;
|
||||
}
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/* Returns: the last error message from previous database operation */
|
||||
function ErrorMsg()
|
||||
{
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
/* Returns: the last error number from previous database operation */
|
||||
function ErrorNo()
|
||||
{
|
||||
return $this->_errorNo;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
} // class
|
||||
|
||||
class ADORecordset_csv extends ADORecordset {
|
||||
function ADORecordset_csv($id,$mode=false)
|
||||
{
|
||||
$this->ADORecordset($id,$mode);
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // define
|
||||
|
||||
?>
|
316
phpgwapi/inc/adodb/drivers/adodb-db2.inc.php
Normal file
316
phpgwapi/inc/adodb/drivers/adodb-db2.inc.php
Normal file
@ -0,0 +1,316 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
DB2 data driver. Requires ODBC.
|
||||
|
||||
From phpdb list:
|
||||
|
||||
Hi Andrew,
|
||||
|
||||
thanks a lot for your help. Today we discovered what
|
||||
our real problem was:
|
||||
|
||||
After "playing" a little bit with the php-scripts that try
|
||||
to connect to the IBM DB2, we set the optional parameter
|
||||
Cursortype when calling odbc_pconnect(....).
|
||||
|
||||
And the exciting thing: When we set the cursor type
|
||||
to SQL_CUR_USE_ODBC Cursor Type, then
|
||||
the whole query speed up from 1 till 10 seconds
|
||||
to 0.2 till 0.3 seconds for 100 records. Amazing!!!
|
||||
|
||||
Therfore, PHP is just almost fast as calling the DB2
|
||||
from Servlets using JDBC (don't take too much care
|
||||
about the speed at whole: the database was on a
|
||||
completely other location, so the whole connection
|
||||
was made over a slow network connection).
|
||||
|
||||
I hope this helps when other encounter the same
|
||||
problem when trying to connect to DB2 from
|
||||
PHP.
|
||||
|
||||
Kind regards,
|
||||
Christian Szardenings
|
||||
|
||||
2 Oct 2001
|
||||
Mark Newnham has discovered that the SQL_CUR_USE_ODBC is not supported by
|
||||
IBM's DB2 ODBC driver, so this must be a 3rd party ODBC driver.
|
||||
|
||||
From the IBM CLI Reference:
|
||||
|
||||
SQL_ATTR_ODBC_CURSORS (DB2 CLI v5)
|
||||
This connection attribute is defined by ODBC, but is not supported by DB2
|
||||
CLI. Any attempt to set or get this attribute will result in an SQLSTATE of
|
||||
HYC00 (Driver not capable).
|
||||
|
||||
A 32-bit option specifying how the Driver Manager uses the ODBC cursor
|
||||
library.
|
||||
|
||||
So I guess this means the message [above] was related to using a 3rd party
|
||||
odbc driver.
|
||||
|
||||
Setting SQL_CUR_USE_ODBC
|
||||
========================
|
||||
To set SQL_CUR_USE_ODBC for drivers that require it, do this:
|
||||
|
||||
$db = NewADOConnection('db2');
|
||||
$db->curMode = SQL_CUR_USE_ODBC;
|
||||
$db->Connect($dsn, $userid, $pwd);
|
||||
|
||||
|
||||
|
||||
USING CLI INTERFACE
|
||||
===================
|
||||
|
||||
I have had reports that the $host and $database params have to be reversed in
|
||||
Connect() when using the CLI interface. From Halmai Csongor csongor.halmai#nexum.hu:
|
||||
|
||||
> The symptom is that if I change the database engine from postgres or any other to DB2 then the following
|
||||
> connection command becomes wrong despite being described this version to be correct in the docs.
|
||||
>
|
||||
> $connection_object->Connect( $DATABASE_HOST, $DATABASE_AUTH_USER_NAME, $DATABASE_AUTH_PASSWORD, $DATABASE_NAME )
|
||||
>
|
||||
> In case of DB2 I had to swap the first and last arguments in order to connect properly.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('_ADODB_ODBC_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
|
||||
}
|
||||
if (!defined('ADODB_DB2')){
|
||||
define('ADODB_DB2',1);
|
||||
|
||||
class ADODB_DB2 extends ADODB_odbc {
|
||||
var $databaseType = "db2";
|
||||
var $concat_operator = '||';
|
||||
var $sysDate = 'CURRENT_DATE';
|
||||
var $sysTimeStamp = 'CURRENT TIMESTAMP';
|
||||
// The complete string representation of a timestamp has the form
|
||||
// yyyy-mm-dd-hh.mm.ss.nnnnnn.
|
||||
var $fmtTimeStamp = "'Y-m-d-H.i.s'";
|
||||
var $ansiOuter = true;
|
||||
var $identitySQL = 'values IDENTITY_VAL_LOCAL()';
|
||||
var $_bindInputArray = true;
|
||||
var $hasInsertID = true;
|
||||
|
||||
function ADODB_DB2()
|
||||
{
|
||||
if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC;
|
||||
$this->ADODB_odbc();
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " COALESCE($field, $ifNull) "; // if DB2 UDB
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
//odbc_setoption($this->_connectionID,1,101 /*SQL_ATTR_ACCESS_MODE*/, 1 /*SQL_MODE_READ_ONLY*/);
|
||||
$vers = $this->GetOne('select versionnumber from sysibm.sysversions');
|
||||
//odbc_setoption($this->_connectionID,1,101, 0 /*SQL_MODE_READ_WRITE*/);
|
||||
return array('description'=>'DB2 ODBC driver', 'version'=>$vers);
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
return $this->GetOne($this->identitySQL);
|
||||
}
|
||||
|
||||
function RowLock($tables,$where)
|
||||
{
|
||||
if ($this->_autocommit) $this->BeginTrans();
|
||||
return $this->GetOne("select 1 as ignore from $tables where $where for update");
|
||||
}
|
||||
|
||||
function &MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%")
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$qid = odbc_tables($this->_connectionID, "", $qschema, $qtable, "");
|
||||
|
||||
$rs = new ADORecordSet_odbc($qid);
|
||||
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
if (!$rs) return false;
|
||||
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
|
||||
$arr =& $rs->GetArray();
|
||||
//print_r($arr);
|
||||
|
||||
$rs->Close();
|
||||
$arr2 = array();
|
||||
|
||||
if ($ttype) {
|
||||
$isview = strncmp($ttype,'V',1) === 0;
|
||||
}
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
|
||||
if (!$arr[$i][2]) continue;
|
||||
if (strncmp($arr[$i][1],'SYS',3) === 0) continue;
|
||||
|
||||
$type = $arr[$i][3];
|
||||
|
||||
if ($showSchema) $arr[$i][2] = $arr[$i][1].'.'.$arr[$i][2];
|
||||
|
||||
if ($ttype) {
|
||||
if ($isview) {
|
||||
if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
|
||||
} else if (strncmp($type,'T',1) === 0) $arr2[] = $arr[$i][2];
|
||||
} else if (strncmp($type,'S',1) !== 0) $arr2[] = $arr[$i][2];
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
// use right() and replace() ?
|
||||
if (!$col) $col = $this->sysDate;
|
||||
$s = '';
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($s) $s .= '||';
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= "char(year($col))";
|
||||
break;
|
||||
case 'M':
|
||||
$s .= "substr(monthname($col),1,3)";
|
||||
break;
|
||||
case 'm':
|
||||
$s .= "right(digits(month($col)),2)";
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= "right(digits(day($col)),2)";
|
||||
break;
|
||||
case 'H':
|
||||
case 'h':
|
||||
if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
|
||||
else $s .= "''";
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
if ($col != $this->sysDate)
|
||||
$s .= "right(digits(minute($col)),2)";
|
||||
else $s .= "''";
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
if ($col != $this->sysDate)
|
||||
$s .= "right(digits(second($col)),2)";
|
||||
else $s .= "''";
|
||||
break;
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $this->qstr($ch);
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
|
||||
{
|
||||
if ($offset <= 0) {
|
||||
// could also use " OPTIMIZE FOR $nrows ROWS "
|
||||
if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY ";
|
||||
$rs =& $this->Execute($sql,$inputArr);
|
||||
} else {
|
||||
if ($offset > 0 && $nrows < 0);
|
||||
else {
|
||||
$nrows += $offset;
|
||||
$sql .= " FETCH FIRST $nrows ROWS ONLY ";
|
||||
}
|
||||
$rs =& ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
|
||||
}
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ADORecordSet_db2 extends ADORecordSet_odbc {
|
||||
|
||||
var $databaseType = "db2";
|
||||
|
||||
function ADORecordSet_db2($id,$mode=false)
|
||||
{
|
||||
$this->ADORecordSet_odbc($id,$mode);
|
||||
}
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
switch (strtoupper($t)) {
|
||||
case 'VARCHAR':
|
||||
case 'CHAR':
|
||||
case 'CHARACTER':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'LONGCHAR':
|
||||
case 'TEXT':
|
||||
case 'CLOB':
|
||||
case 'DBCLOB': // double-byte
|
||||
return 'X';
|
||||
|
||||
case 'BLOB':
|
||||
case 'GRAPHIC':
|
||||
case 'VARGRAPHIC':
|
||||
return 'B';
|
||||
|
||||
case 'DATE':
|
||||
return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'TIMESTAMP':
|
||||
return 'T';
|
||||
|
||||
//case 'BOOLEAN':
|
||||
//case 'BIT':
|
||||
// return 'L';
|
||||
|
||||
//case 'COUNTER':
|
||||
// return 'R';
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER':
|
||||
case 'BIGINT':
|
||||
case 'SMALLINT':
|
||||
return 'I';
|
||||
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //define
|
||||
?>
|
75
phpgwapi/inc/adodb/drivers/adodb-firebird.inc.php
Normal file
75
phpgwapi/inc/adodb/drivers/adodb-firebird.inc.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include_once(ADODB_DIR."/drivers/adodb-ibase.inc.php");
|
||||
|
||||
class ADODB_firebird extends ADODB_ibase {
|
||||
var $databaseType = "firebird";
|
||||
var $dialect = 3;
|
||||
|
||||
var $sysTimeStamp = "cast('NOW' as timestamp)";
|
||||
|
||||
function ADODB_firebird()
|
||||
{
|
||||
$this->ADODB_ibase();
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
$arr['dialect'] = $this->dialect;
|
||||
switch($arr['dialect']) {
|
||||
case '':
|
||||
case '1': $s = 'Firebird Dialect 1'; break;
|
||||
case '2': $s = 'Firebird Dialect 2'; break;
|
||||
default:
|
||||
case '3': $s = 'Firebird Dialect 3'; break;
|
||||
}
|
||||
$arr['version'] = ADOConnection::_findvers($s);
|
||||
$arr['description'] = $s;
|
||||
return $arr;
|
||||
}
|
||||
|
||||
// Note that Interbase 6.5 uses this ROWS instead - don't you love forking wars!
|
||||
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
|
||||
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
|
||||
{
|
||||
$str = 'SELECT ';
|
||||
if ($nrows >= 0) $str .= "FIRST $nrows ";
|
||||
$str .=($offset>=0) ? "SKIP $offset " : '';
|
||||
|
||||
$sql = preg_replace('/^[ \t]*select/i',$str,$sql);
|
||||
if ($secs)
|
||||
$rs =& $this->CacheExecute($secs,$sql,$inputarr);
|
||||
else
|
||||
$rs =& $this->Execute($sql,$inputarr);
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ADORecordSet_firebird extends ADORecordSet_ibase {
|
||||
|
||||
var $databaseType = "firebird";
|
||||
|
||||
function ADORecordSet_firebird($id,$mode=false)
|
||||
{
|
||||
$this->ADORecordSet_ibase($id,$mode);
|
||||
}
|
||||
}
|
||||
?>
|
856
phpgwapi/inc/adodb/drivers/adodb-ibase.inc.php
Normal file
856
phpgwapi/inc/adodb/drivers/adodb-ibase.inc.php
Normal file
@ -0,0 +1,856 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Interbase data driver. Requires interbase client. Works on Windows and Unix.
|
||||
|
||||
3 Jan 2002 -- suggestions by Hans-Peter Oeri <kampfcaspar75@oeri.ch>
|
||||
changed transaction handling and added experimental blob stuff
|
||||
|
||||
Docs to interbase at the website
|
||||
http://www.synectics.co.za/php3/tutorial/IB_PHP3_API.html
|
||||
|
||||
To use gen_id(), see
|
||||
http://www.volny.cz/iprenosil/interbase/ip_ib_code.htm#_code_creategen
|
||||
|
||||
$rs = $conn->Execute('select gen_id(adodb,1) from rdb$database');
|
||||
$id = $rs->fields[0];
|
||||
$conn->Execute("insert into table (id, col1,...) values ($id, $val1,...)");
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB_ibase extends ADOConnection {
|
||||
var $databaseType = "ibase";
|
||||
var $dataProvider = "ibase";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $ibase_datefmt = '%Y-%m-%d'; // For hours,mins,secs change to '%Y-%m-%d %H:%M:%S';
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $ibase_timestampfmt = "%Y-%m-%d %H:%M:%S";
|
||||
var $ibase_timefmt = "%H:%M:%S";
|
||||
var $fmtTimeStamp = "'Y-m-d, H:i:s'";
|
||||
var $concat_operator='||';
|
||||
var $_transactionID;
|
||||
var $metaTablesSQL = "select rdb\$relation_name from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
|
||||
//OPN STUFF start
|
||||
var $metaColumnsSQL = "select a.rdb\$field_name, a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";
|
||||
//OPN STUFF end
|
||||
var $ibasetrans;
|
||||
var $hasGenID = true;
|
||||
var $_bindInputArray = true;
|
||||
var $buffers = 0;
|
||||
var $dialect = 1;
|
||||
var $sysDate = "cast('TODAY' as timestamp)";
|
||||
var $sysTimeStamp = "cast('NOW' as timestamp)";
|
||||
var $ansiOuter = true;
|
||||
var $hasAffectedRows = false;
|
||||
var $poorAffectedRows = true;
|
||||
var $blobEncodeType = 'C';
|
||||
|
||||
function ADODB_ibase()
|
||||
{
|
||||
if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist=false)
|
||||
{
|
||||
if (!function_exists('ibase_pconnect')) return null;
|
||||
if ($argDatabasename) $argHostname .= ':'.$argDatabasename;
|
||||
$fn = ($persist) ? 'ibase_pconnect':'ibase_connect';
|
||||
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
|
||||
$this->charSet,$this->buffers,$this->dialect);
|
||||
|
||||
if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
|
||||
$this->replaceQuote = "''";
|
||||
}
|
||||
if ($this->_connectionID === false) {
|
||||
$this->_handleerror();
|
||||
return false;
|
||||
}
|
||||
|
||||
// PHP5 change.
|
||||
if (function_exists('ibase_timefmt')) {
|
||||
ibase_timefmt($this->ibase_datefmt,IBASE_DATE );
|
||||
if ($this->dialect == 1) ibase_timefmt($this->ibase_datefmt,IBASE_TIMESTAMP );
|
||||
else ibase_timefmt($this->ibase_timestampfmt,IBASE_TIMESTAMP );
|
||||
ibase_timefmt($this->ibase_timefmt,IBASE_TIME );
|
||||
|
||||
} else {
|
||||
ini_set("ibase.timestampformat", $this->ibase_timestampfmt);
|
||||
ini_set("ibase.dateformat", $this->ibase_datefmt);
|
||||
ini_set("ibase.timeformat", $this->ibase_timefmt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,true);
|
||||
}
|
||||
|
||||
|
||||
function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)
|
||||
{
|
||||
if ($internalKey) return array('RDB$DB_KEY');
|
||||
|
||||
$table = strtoupper($table);
|
||||
|
||||
$sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
|
||||
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
|
||||
WHERE I.RDB$RELATION_NAME=\''.$table.'\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'
|
||||
ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
|
||||
|
||||
$a = $this->GetCol($sql,false,true);
|
||||
if ($a && sizeof($a)>0) return $a;
|
||||
return false;
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
$arr['dialect'] = $this->dialect;
|
||||
switch($arr['dialect']) {
|
||||
case '':
|
||||
case '1': $s = 'Interbase 5.5 or earlier'; break;
|
||||
case '2': $s = 'Interbase 5.6'; break;
|
||||
default:
|
||||
case '3': $s = 'Interbase 6.0'; break;
|
||||
}
|
||||
$arr['version'] = ADOConnection::_findvers($s);
|
||||
$arr['description'] = $s;
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->autoCommit = false;
|
||||
$this->_transactionID = $this->_connectionID;//ibase_trans($this->ibasetrans, $this->_connectionID);
|
||||
return $this->_transactionID;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$ret = false;
|
||||
$this->autoCommit = true;
|
||||
if ($this->_transactionID) {
|
||||
//print ' commit ';
|
||||
$ret = ibase_commit($this->_transactionID);
|
||||
}
|
||||
$this->_transactionID = false;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
|
||||
// it appears that ibase extension cannot support multiple concurrent queryid's
|
||||
function &_Execute($sql,$inputarr=false)
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
|
||||
if ($this->_logsql) {
|
||||
$savecrecs = $ADODB_COUNTRECS;
|
||||
$ADODB_COUNTRECS = true; // force countrecs
|
||||
$ret =& ADOConnection::_Execute($sql,$inputarr);
|
||||
$ADODB_COUNTRECS = $savecrecs;
|
||||
} else {
|
||||
$ret =& ADOConnection::_Execute($sql,$inputarr);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$ret = false;
|
||||
$this->autoCommit = true;
|
||||
if ($this->_transactionID)
|
||||
$ret = ibase_rollback($this->_transactionID);
|
||||
$this->_transactionID = false;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function &MetaIndexes ($table, $primary = FALSE, $owner=false)
|
||||
{
|
||||
// save old fetch mode
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== FALSE) {
|
||||
$savem = $this->SetFetchMode(FALSE);
|
||||
}
|
||||
$table = strtoupper($table);
|
||||
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";
|
||||
if (!$primary) {
|
||||
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
|
||||
} else {
|
||||
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
|
||||
}
|
||||
// get index details
|
||||
$rs = $this->Execute($sql);
|
||||
if (!is_object($rs)) {
|
||||
// restore fetchmode
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$indexes = array ();
|
||||
while ($row = $rs->FetchRow()) {
|
||||
$index = $row[0];
|
||||
if (!isset($indexes[$index])) {
|
||||
if (is_null($row[3])) {$row[3] = 0;}
|
||||
$indexes[$index] = array(
|
||||
'unique' => ($row[3] == 1),
|
||||
'columns' => array()
|
||||
);
|
||||
}
|
||||
$sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$name."' ORDER BY RDB\$FIELD_POSITION ASC";
|
||||
$rs1 = $this->Execute($sql);
|
||||
while ($row1 = $rs1->FetchRow()) {
|
||||
$indexes[$index]['columns'][$row1[2]] = $row1[1];
|
||||
}
|
||||
}
|
||||
// restore fetchmode
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
|
||||
// See http://community.borland.com/article/0,1410,25844,00.html
|
||||
function RowLock($tables,$where,$col)
|
||||
{
|
||||
if ($this->autoCommit) $this->BeginTrans();
|
||||
$this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
function CreateSequence($seqname,$startID=1)
|
||||
{
|
||||
$ok = $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
|
||||
if (!$ok) return false;
|
||||
return $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
|
||||
}
|
||||
|
||||
function DropSequence($seqname)
|
||||
{
|
||||
$seqname = strtoupper($seqname);
|
||||
$this->Execute("delete from RDB\$GENERATORS where RDB\$GENERATOR_NAME='$seqname'");
|
||||
}
|
||||
|
||||
function GenID($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
$getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
|
||||
$rs = @$this->Execute($getnext);
|
||||
if (!$rs) {
|
||||
$this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
|
||||
$this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');
|
||||
$rs = $this->Execute($getnext);
|
||||
}
|
||||
if ($rs && !$rs->EOF) $this->genID = (integer) reset($rs->fields);
|
||||
else $this->genID = 0; // false
|
||||
|
||||
if ($rs) $rs->Close();
|
||||
|
||||
return $this->genID;
|
||||
}
|
||||
|
||||
function SelectDB($dbName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function _handleerror()
|
||||
{
|
||||
$this->_errorMsg = ibase_errmsg();
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if (preg_match('/error code = ([\-0-9]*)/i', $this->_errorMsg,$arr)) return (integer) $arr[1];
|
||||
else return 0;
|
||||
}
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
function Prepare($sql)
|
||||
{
|
||||
$stmt = ibase_prepare($this->_connectionID,$sql);
|
||||
if (!$stmt) return false;
|
||||
return array($sql,$stmt);
|
||||
}
|
||||
|
||||
// returns query ID if successful, otherwise false
|
||||
// there have been reports of problems with nested queries - the code is probably not re-entrant?
|
||||
function _query($sql,$iarr=false)
|
||||
{
|
||||
|
||||
if (!$this->autoCommit && $this->_transactionID) {
|
||||
$conn = $this->_transactionID;
|
||||
$docommit = false;
|
||||
} else {
|
||||
$conn = $this->_connectionID;
|
||||
$docommit = true;
|
||||
}
|
||||
if (is_array($sql)) {
|
||||
$fn = 'ibase_execute';
|
||||
$sql = $sql[1];
|
||||
if (is_array($iarr)) {
|
||||
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
|
||||
if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
|
||||
$fnarr =& array_merge( array($sql) , $iarr);
|
||||
$ret = call_user_func_array($fn,$fnarr);
|
||||
} else {
|
||||
switch(sizeof($iarr)) {
|
||||
case 1: $ret = $fn($sql,$iarr[0]); break;
|
||||
case 2: $ret = $fn($sql,$iarr[0],$iarr[1]); break;
|
||||
case 3: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;
|
||||
case 4: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
|
||||
case 5: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
|
||||
case 6: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
|
||||
case 7: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
|
||||
default: ADOConnection::outp( "Too many parameters to ibase query $sql");
|
||||
case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
|
||||
}
|
||||
}
|
||||
} else $ret = $fn($sql);
|
||||
} else {
|
||||
$fn = 'ibase_query';
|
||||
|
||||
if (is_array($iarr)) {
|
||||
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
|
||||
if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
|
||||
$fnarr =& array_merge( array($conn,$sql) , $iarr);
|
||||
$ret = call_user_func_array($fn,$fnarr);
|
||||
} else {
|
||||
switch(sizeof($iarr)) {
|
||||
case 1: $ret = $fn($conn,$sql,$iarr[0]); break;
|
||||
case 2: $ret = $fn($conn,$sql,$iarr[0],$iarr[1]); break;
|
||||
case 3: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;
|
||||
case 4: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
|
||||
case 5: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
|
||||
case 6: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
|
||||
case 7: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
|
||||
default: ADOConnection::outp( "Too many parameters to ibase query $sql");
|
||||
case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
|
||||
}
|
||||
}
|
||||
} else $ret = $fn($conn,$sql);
|
||||
}
|
||||
if ($docommit && $ret === true) ibase_commit($this->_connectionID);
|
||||
|
||||
$this->_handleerror();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
if (!$this->autoCommit) @ibase_rollback($this->_connectionID);
|
||||
return @ibase_close($this->_connectionID);
|
||||
}
|
||||
|
||||
//OPN STUFF start
|
||||
function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3)
|
||||
{
|
||||
$fscale = abs($fscale);
|
||||
$fld->max_length = $flen;
|
||||
$fld->scale = null;
|
||||
switch($ftype){
|
||||
case 7:
|
||||
case 8:
|
||||
if ($dialect3) {
|
||||
switch($fsubtype){
|
||||
case 0:
|
||||
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
|
||||
break;
|
||||
case 1:
|
||||
$fld->type = 'numeric';
|
||||
$fld->max_length = $fprecision;
|
||||
$fld->scale = $fscale;
|
||||
break;
|
||||
case 2:
|
||||
$fld->type = 'decimal';
|
||||
$fld->max_length = $fprecision;
|
||||
$fld->scale = $fscale;
|
||||
break;
|
||||
} // switch
|
||||
} else {
|
||||
if ($fscale !=0) {
|
||||
$fld->type = 'decimal';
|
||||
$fld->scale = $fscale;
|
||||
$fld->max_length = ($ftype == 7 ? 4 : 9);
|
||||
} else {
|
||||
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if ($dialect3) {
|
||||
switch($fsubtype){
|
||||
case 0:
|
||||
$fld->type = 'decimal';
|
||||
$fld->max_length = 18;
|
||||
$fld->scale = 0;
|
||||
break;
|
||||
case 1:
|
||||
$fld->type = 'numeric';
|
||||
$fld->max_length = $fprecision;
|
||||
$fld->scale = $fscale;
|
||||
break;
|
||||
case 2:
|
||||
$fld->type = 'decimal';
|
||||
$fld->max_length = $fprecision;
|
||||
$fld->scale = $fscale;
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
$fld->type = 'float';
|
||||
break;
|
||||
case 14:
|
||||
$fld->type = 'char';
|
||||
break;
|
||||
case 27:
|
||||
if ($fscale !=0) {
|
||||
$fld->type = 'decimal';
|
||||
$fld->max_length = 15;
|
||||
$fld->scale = 5;
|
||||
} else {
|
||||
$fld->type = 'double';
|
||||
}
|
||||
break;
|
||||
case 35:
|
||||
if ($dialect3) {
|
||||
$fld->type = 'timestamp';
|
||||
} else {
|
||||
$fld->type = 'date';
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
$fld->type = 'date';
|
||||
break;
|
||||
case 13:
|
||||
$fld->type = 'time';
|
||||
break;
|
||||
case 37:
|
||||
$fld->type = 'varchar';
|
||||
break;
|
||||
case 40:
|
||||
$fld->type = 'cstring';
|
||||
break;
|
||||
case 261:
|
||||
$fld->type = 'blob';
|
||||
$fld->max_length = -1;
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
//OPN STUFF end
|
||||
// returns array of ADOFieldObjects for current table
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->metaColumnsSQL) {
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false) return false;
|
||||
|
||||
$retarr = array();
|
||||
//OPN STUFF start
|
||||
$dialect3 = ($this->dialect==3 ? true : false);
|
||||
//OPN STUFF end
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = trim($rs->fields[0]);
|
||||
//OPN STUFF start
|
||||
$this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
|
||||
if (isset($rs->fields[1]) && $rs->fields[1]) {
|
||||
$fld->not_null = true;
|
||||
}
|
||||
if (isset($rs->fields[2])) {
|
||||
|
||||
$fld->has_default = true;
|
||||
$d = substr($rs->fields[2],strlen('default '));
|
||||
switch ($fld->type)
|
||||
{
|
||||
case 'smallint':
|
||||
case 'integer': $fld->default_value = (int) $d; break;
|
||||
case 'char':
|
||||
case 'blob':
|
||||
case 'text':
|
||||
case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;
|
||||
case 'double':
|
||||
case 'float': $fld->default_value = (float) $d; break;
|
||||
default: $fld->default_value = $d; break;
|
||||
}
|
||||
// case 35:$tt = 'TIMESTAMP'; break;
|
||||
}
|
||||
if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {
|
||||
$fld->sub_type = $rs->fields[5];
|
||||
} else {
|
||||
$fld->sub_type = null;
|
||||
}
|
||||
//OPN STUFF end
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function BlobEncode( $blob )
|
||||
{
|
||||
$blobid = ibase_blob_create( $this->_connectionID);
|
||||
ibase_blob_add( $blobid, $blob );
|
||||
return ibase_blob_close( $blobid );
|
||||
}
|
||||
|
||||
// since we auto-decode all blob's since 2.42,
|
||||
// BlobDecode should not do any transforms
|
||||
function BlobDecode($blob)
|
||||
{
|
||||
return $blob;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// old blobdecode function
|
||||
// still used to auto-decode all blob's
|
||||
function _BlobDecode( $blob )
|
||||
{
|
||||
$blobid = ibase_blob_open( $blob );
|
||||
$realblob = ibase_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet <kevinboillet@yahoo.fr>
|
||||
while($string = ibase_blob_get($blobid, 8192)){
|
||||
$realblob .= $string;
|
||||
}
|
||||
ibase_blob_close( $blobid );
|
||||
|
||||
return( $realblob );
|
||||
}
|
||||
|
||||
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
|
||||
{
|
||||
$fd = fopen($path,'rb');
|
||||
if ($fd === false) return false;
|
||||
$blob_id = ibase_blob_create($this->_connectionID);
|
||||
|
||||
/* fill with data */
|
||||
|
||||
while ($val = fread($fd,32768)){
|
||||
ibase_blob_add($blob_id, $val);
|
||||
}
|
||||
|
||||
/* close and get $blob_id_str for inserting into table */
|
||||
$blob_id_str = ibase_blob_close($blob_id);
|
||||
|
||||
fclose($fd);
|
||||
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
|
||||
}
|
||||
|
||||
/*
|
||||
Insert a null into the blob field of the table first.
|
||||
Then use UpdateBlob to store the blob.
|
||||
|
||||
Usage:
|
||||
|
||||
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
|
||||
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
|
||||
*/
|
||||
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
|
||||
{
|
||||
$blob_id = ibase_blob_create($this->_connectionID);
|
||||
|
||||
// ibase_blob_add($blob_id, $val);
|
||||
|
||||
// replacement that solves the problem by which only the first modulus 64K /
|
||||
// of $val are stored at the blob field ////////////////////////////////////
|
||||
// Thx Abel Berenstein aberenstein#afip.gov.ar
|
||||
$len = strlen($val);
|
||||
$chunk_size = 32768;
|
||||
$tail_size = $len % $chunk_size;
|
||||
$n_chunks = ($len - $tail_size) / $chunk_size;
|
||||
|
||||
for ($n = 0; $n < $n_chunks; $n++) {
|
||||
$start = $n * $chunk_size;
|
||||
$data = substr($val, $start, $chunk_size);
|
||||
ibase_blob_add($blob_id, $data);
|
||||
}
|
||||
|
||||
if ($tail_size) {
|
||||
$start = $n_chunks * $chunk_size;
|
||||
$data = substr($val, $start, $tail_size);
|
||||
ibase_blob_add($blob_id, $data);
|
||||
}
|
||||
// end replacement /////////////////////////////////////////////////////////
|
||||
|
||||
$blob_id_str = ibase_blob_close($blob_id);
|
||||
|
||||
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
|
||||
{
|
||||
$blob_id = ibase_blob_create($this->_connectionID);
|
||||
ibase_blob_add($blob_id, $val);
|
||||
$blob_id_str = ibase_blob_close($blob_id);
|
||||
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
|
||||
}
|
||||
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
// Only since Interbase 6.0 - uses EXTRACT
|
||||
// problem - does not zero-fill the day and month yet
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysDate;
|
||||
$s = '';
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($s) $s .= '||';
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= "extract(year from $col)";
|
||||
break;
|
||||
case 'M':
|
||||
case 'm':
|
||||
$s .= "extract(month from $col)";
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "cast(((extract(month from $col)+2) / 3) as integer)";
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= "(extract(day from $col))";
|
||||
break;
|
||||
case 'H':
|
||||
case 'h':
|
||||
$s .= "(extract(hour from $col))";
|
||||
break;
|
||||
case 'I':
|
||||
case 'i':
|
||||
$s .= "(extract(minute from $col))";
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
$s .= "CAST((extract(second from $col)) AS INTEGER)";
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $this->qstr($ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordset_ibase extends ADORecordSet
|
||||
{
|
||||
|
||||
var $databaseType = "ibase";
|
||||
var $bind=false;
|
||||
var $_cacheType;
|
||||
|
||||
function ADORecordset_ibase($id,$mode=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
|
||||
$this->ADORecordSet($id);
|
||||
}
|
||||
|
||||
/* Returns: an object containing field information.
|
||||
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
|
||||
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
|
||||
fetchField() is retrieved. */
|
||||
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
$fld = new ADOFieldObject;
|
||||
$ibf = ibase_field_info($this->_queryID,$fieldOffset);
|
||||
switch (ADODB_ASSOC_CASE) {
|
||||
case 2: // the default
|
||||
$fld->name = ($ibf['alias']);
|
||||
if (empty($fld->name)) $fld->name = ($ibf['name']);
|
||||
break;
|
||||
case 0:
|
||||
$fld->name = strtoupper($ibf['alias']);
|
||||
if (empty($fld->name)) $fld->name = strtoupper($ibf['name']);
|
||||
break;
|
||||
case 1:
|
||||
$fld->name = strtolower($ibf['alias']);
|
||||
if (empty($fld->name)) $fld->name = strtolower($ibf['name']);
|
||||
break;
|
||||
}
|
||||
|
||||
$fld->type = $ibf['type'];
|
||||
$fld->max_length = $ibf['length'];
|
||||
|
||||
/* This needs to be populated from the metadata */
|
||||
$fld->not_null = false;
|
||||
$fld->has_default = false;
|
||||
$fld->default_value = 'null';
|
||||
return $fld;
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
$this->_numOfRows = -1;
|
||||
$this->_numOfFields = @ibase_num_fields($this->_queryID);
|
||||
|
||||
// cache types for blob decode check
|
||||
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
|
||||
$f1 = $this->FetchField($i);
|
||||
$this->_cacheType[] = $f1->type;
|
||||
}
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$f = @ibase_fetch_row($this->_queryID);
|
||||
if ($f === false) {
|
||||
$this->fields = false;
|
||||
return false;
|
||||
}
|
||||
// OPN stuff start - optimized
|
||||
// fix missing nulls and decode blobs automatically
|
||||
|
||||
global $ADODB_ANSI_PADDING_OFF;
|
||||
//$ADODB_ANSI_PADDING_OFF=1;
|
||||
$rtrim = !empty($ADODB_ANSI_PADDING_OFF);
|
||||
|
||||
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
|
||||
if ($this->_cacheType[$i]=="BLOB") {
|
||||
if (isset($f[$i])) {
|
||||
$f[$i] = $this->connection->_BlobDecode($f[$i]);
|
||||
} else {
|
||||
$f[$i] = null;
|
||||
}
|
||||
} else {
|
||||
if (!isset($f[$i])) {
|
||||
$f[$i] = null;
|
||||
} else if ($rtrim && is_string($f[$i])) {
|
||||
$f[$i] = rtrim($f[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// OPN stuff end
|
||||
|
||||
$this->fields = $f;
|
||||
if ($this->fetchMode == ADODB_FETCH_ASSOC) {
|
||||
$this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
} else if ($this->fetchMode == ADODB_FETCH_BOTH) {
|
||||
$this->fields =& array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
|
||||
}
|
||||
|
||||
|
||||
function _close()
|
||||
{
|
||||
return @ibase_free_result($this->_queryID);
|
||||
}
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
switch (strtoupper($t)) {
|
||||
case 'CHAR':
|
||||
return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
case 'VARCHAR':
|
||||
case 'VARYING':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
return 'X';
|
||||
case 'BLOB':
|
||||
return 'B';
|
||||
|
||||
case 'TIMESTAMP':
|
||||
case 'DATE': return 'D';
|
||||
case 'TIME': return 'T';
|
||||
//case 'T': return 'T';
|
||||
|
||||
//case 'L': return 'L';
|
||||
case 'INT':
|
||||
case 'SHORT':
|
||||
case 'INTEGER': return 'I';
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
404
phpgwapi/inc/adodb/drivers/adodb-informix72.inc.php
Normal file
404
phpgwapi/inc/adodb/drivers/adodb-informix72.inc.php
Normal file
@ -0,0 +1,404 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim. All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Informix port by Mitchell T. Young (mitch@youngfamily.org)
|
||||
|
||||
Further mods by "Samuel CARRIERE" <samuel_carriere@hotmail.com>
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('IFX_SCROLL')) define('IFX_SCROLL',1);
|
||||
|
||||
class ADODB_informix72 extends ADOConnection {
|
||||
var $databaseType = "informix72";
|
||||
var $dataProvider = "informix";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $hasInsertID = true;
|
||||
var $hasAffectedRows = true;
|
||||
var $substr = 'substr';
|
||||
var $metaTablesSQL="select tabname from systables where tabtype!=' ' and owner!='informix'"; //Don't get informix tables and pseudo-tables
|
||||
|
||||
|
||||
var $metaColumnsSQL =
|
||||
"select c.colname, c.coltype, c.collength, d.default,c.colno
|
||||
from syscolumns c, systables t,outer sysdefaults d
|
||||
where c.tabid=t.tabid and d.tabid=t.tabid and d.colno=c.colno
|
||||
and tabname='%s' order by c.colno";
|
||||
|
||||
var $metaPrimaryKeySQL =
|
||||
"select part1,part2,part3,part4,part5,part6,part7,part8 from
|
||||
systables t,sysconstraints s,sysindexes i where t.tabname='%s'
|
||||
and s.tabid=t.tabid and s.constrtype='P'
|
||||
and i.idxname=s.idxname";
|
||||
|
||||
var $concat_operator = '||';
|
||||
|
||||
var $lastQuery = false;
|
||||
var $has_insertid = true;
|
||||
|
||||
var $_autocommit = true;
|
||||
var $_bindInputArray = true; // set to true if ADOConnection.Execute() permits binding of array parameters.
|
||||
var $sysDate = 'TODAY';
|
||||
var $sysTimeStamp = 'CURRENT';
|
||||
var $cursorType = IFX_SCROLL; // IFX_SCROLL or IFX_HOLD or 0
|
||||
|
||||
function ADODB_informix72()
|
||||
{
|
||||
// alternatively, use older method:
|
||||
//putenv("DBDATE=Y4MD-");
|
||||
|
||||
// force ISO date format
|
||||
putenv('GL_DATE=%Y-%m-%d');
|
||||
|
||||
if (function_exists('ifx_byteasvarchar')) {
|
||||
ifx_byteasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
|
||||
ifx_textasvarchar(1); // Mode "0" will return a blob id, and mode "1" will return a varchar with text content.
|
||||
ifx_blobinfile_mode(0); // Mode "0" means save Byte-Blobs in memory, and mode "1" means save Byte-Blobs in a file.
|
||||
}
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
if (isset($this->version)) return $this->version;
|
||||
|
||||
$arr['description'] = $this->GetOne("select DBINFO('version','full') from systables where tabid = 1");
|
||||
$arr['version'] = $this->GetOne("select DBINFO('version','major')||"."||DBINFO('version','minor') from systables where tabid = 1");
|
||||
$this->version = $arr;
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
$sqlca =ifx_getsqlca($this->lastQuery);
|
||||
return @$sqlca["sqlerrd1"];
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
if ($this->lastQuery) {
|
||||
return @ifx_affected_rows ($this->lastQuery);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('BEGIN');
|
||||
$this->_autocommit = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('COMMIT');
|
||||
$this->_autocommit = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('ROLLBACK');
|
||||
$this->_autocommit = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
function RowLock($tables,$where)
|
||||
{
|
||||
if ($this->_autocommit) $this->BeginTrans();
|
||||
return $this->GetOne("select 1 as ignore from $tables where $where for update");
|
||||
}
|
||||
|
||||
/* Returns: the last error message from previous database operation
|
||||
Note: This function is NOT available for Microsoft SQL Server. */
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if (!empty($this->_logsql)) return $this->_errorMsg;
|
||||
$this->_errorMsg = ifx_errormsg();
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
preg_match("/.*SQLCODE=([^\]]*)/",ifx_error(),$parse); //!EOS
|
||||
if (is_array($parse) && isset($parse[1])) return (int)$parse[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if (!empty($this->metaColumnsSQL)) {
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false) return false;
|
||||
$rspkey = $this->Execute(sprintf($this->metaPrimaryKeySQL,$table)); //Added to get primary key colno items
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
$fld->primary_key=$rspkey->fields && array_search($rs->fields[4],$rspkey->fields); //Added to set primary key flag
|
||||
$fld->max_length = $rs->fields[2];
|
||||
if (trim($rs->fields[3]) != "AAAAAA 0") {
|
||||
$fld->has_default = 1;
|
||||
$fld->default_value = $rs->fields[3];
|
||||
} else {
|
||||
$fld->has_default = 0;
|
||||
}
|
||||
|
||||
$retarr[strtolower($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function &xMetaColumns($table)
|
||||
{
|
||||
return ADOConnection::MetaColumns($table,false);
|
||||
}
|
||||
|
||||
function UpdateBlob($table, $column, $val, $where, $blobtype = 'BLOB')
|
||||
{
|
||||
$type = ($blobtype == 'TEXT') ? 1 : 0;
|
||||
$blobid = ifx_create_blob($type,0,$val);
|
||||
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blobid));
|
||||
}
|
||||
|
||||
function BlobDecode($blobid)
|
||||
{
|
||||
return function_exists('ifx_byteasvarchar') ? $blobid : @ifx_get_blob($blobid);
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('ifx_connect')) return null;
|
||||
|
||||
$dbs = $argDatabasename . "@" . $argHostname;
|
||||
if ($argHostname) putenv("INFORMIXSERVER=$argHostname");
|
||||
putenv("INFORMIXSERVER=".trim($argHostname));
|
||||
$this->_connectionID = ifx_connect($dbs,$argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('ifx_connect')) return null;
|
||||
|
||||
$dbs = $argDatabasename . "@" . $argHostname;
|
||||
putenv("INFORMIXSERVER=".trim($argHostname));
|
||||
$this->_connectionID = ifx_pconnect($dbs,$argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
#if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
// ifx_do does not accept bind parameters - weird ???
|
||||
function Prepare($sql)
|
||||
{
|
||||
$stmt = ifx_prepare($sql);
|
||||
if (!$stmt) return $sql;
|
||||
else return array($sql,$stmt);
|
||||
}
|
||||
*/
|
||||
// returns query ID if successful, otherwise false
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
|
||||
// String parameters have to be converted using ifx_create_char
|
||||
if ($inputarr) {
|
||||
foreach($inputarr as $v) {
|
||||
if (gettype($v) == 'string') {
|
||||
$tab[] = ifx_create_char($v);
|
||||
}
|
||||
else {
|
||||
$tab[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In case of select statement, we use a scroll cursor in order
|
||||
// to be able to call "move", or "movefirst" statements
|
||||
if (!$ADODB_COUNTRECS && preg_match("/^\s*select/is", $sql)) {
|
||||
if ($inputarr) {
|
||||
$this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType, $tab);
|
||||
}
|
||||
else {
|
||||
$this->lastQuery = ifx_query($sql,$this->_connectionID, $this->cursorType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($inputarr) {
|
||||
$this->lastQuery = ifx_query($sql,$this->_connectionID, $tab);
|
||||
}
|
||||
else {
|
||||
$this->lastQuery = ifx_query($sql,$this->_connectionID);
|
||||
}
|
||||
}
|
||||
|
||||
// Following line have been commented because autocommit mode is
|
||||
// not supported by informix SE 7.2
|
||||
|
||||
//if ($this->_autocommit) ifx_query('COMMIT',$this->_connectionID);
|
||||
|
||||
return $this->lastQuery;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
$this->lastQuery = false;
|
||||
return ifx_close($this->_connectionID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordset_informix72 extends ADORecordSet {
|
||||
|
||||
var $databaseType = "informix72";
|
||||
var $canSeek = true;
|
||||
var $_fieldprops = false;
|
||||
|
||||
function ADORecordset_informix72($id,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
$this->fetchMode = $mode;
|
||||
return $this->ADORecordSet($id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Returns: an object containing field information.
|
||||
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
|
||||
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
|
||||
fetchField() is retrieved. */
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
if (empty($this->_fieldprops)) {
|
||||
$fp = ifx_fieldproperties($this->_queryID);
|
||||
foreach($fp as $k => $v) {
|
||||
$o = new ADOFieldObject;
|
||||
$o->name = $k;
|
||||
$arr = split(';',$v); //"SQLTYPE;length;precision;scale;ISNULLABLE"
|
||||
$o->type = $arr[0];
|
||||
$o->max_length = $arr[1];
|
||||
$this->_fieldprops[] = $o;
|
||||
$o->not_null = $arr[4]=="N";
|
||||
}
|
||||
}
|
||||
return $this->_fieldprops[$fieldOffset];
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
$this->_numOfRows = -1; // ifx_affected_rows not reliable, only returns estimate -- ($ADODB_COUNTRECS)? ifx_affected_rows($this->_queryID):-1;
|
||||
$this->_numOfFields = ifx_num_fields($this->_queryID);
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return @ifx_fetch_row($this->_queryID, $row);
|
||||
}
|
||||
|
||||
function MoveLast()
|
||||
{
|
||||
$this->fields = @ifx_fetch_row($this->_queryID, "LAST");
|
||||
if ($this->fields) $this->EOF = false;
|
||||
$this->_currentRow = -1;
|
||||
|
||||
if ($this->fetchMode == ADODB_FETCH_NUM) {
|
||||
foreach($this->fields as $v) {
|
||||
$arr[] = $v;
|
||||
}
|
||||
$this->fields = $arr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function MoveFirst()
|
||||
{
|
||||
$this->fields = @ifx_fetch_row($this->_queryID, "FIRST");
|
||||
if ($this->fields) $this->EOF = false;
|
||||
$this->_currentRow = 0;
|
||||
|
||||
if ($this->fetchMode == ADODB_FETCH_NUM) {
|
||||
foreach($this->fields as $v) {
|
||||
$arr[] = $v;
|
||||
}
|
||||
$this->fields = $arr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function _fetch($ignore_fields=false)
|
||||
{
|
||||
|
||||
$this->fields = @ifx_fetch_row($this->_queryID);
|
||||
|
||||
if (!is_array($this->fields)) return false;
|
||||
|
||||
if ($this->fetchMode == ADODB_FETCH_NUM) {
|
||||
foreach($this->fields as $v) {
|
||||
$arr[] = $v;
|
||||
}
|
||||
$this->fields = $arr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* close() only needs to be called if you are worried about using too much memory while your script
|
||||
is running. All associated result memory for the specified result identifier will automatically be freed. */
|
||||
function _close()
|
||||
{
|
||||
return ifx_free_result($this->_queryID);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
311
phpgwapi/inc/adodb/drivers/adodb-ldap.inc.php
Normal file
311
phpgwapi/inc/adodb/drivers/adodb-ldap.inc.php
Normal file
@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
|
||||
|
||||
Joshua Eldridge (joshuae74#hotmail.com)
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB_ldap extends ADOConnection {
|
||||
var $databaseType = 'ldap';
|
||||
var $dataProvider = 'ldap';
|
||||
|
||||
# Connection information
|
||||
var $username = false;
|
||||
var $password = false;
|
||||
|
||||
# Used during searches
|
||||
var $filter;
|
||||
var $dn;
|
||||
|
||||
|
||||
function ADODB_ldap()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
|
||||
function _connect( $host, $username, $password, $ldapbase )
|
||||
{
|
||||
|
||||
if ( !function_exists( 'ldap_connect' ) ) return null;
|
||||
|
||||
$conn_info = array( $host );
|
||||
|
||||
if ( strstr( $host, ':' ) ) {
|
||||
$conn_info = split( ':', $host );
|
||||
}
|
||||
|
||||
$this->_connectionID = ldap_connect( $conn_info[0], $conn_info[1] )
|
||||
or die( 'Could not connect to ' . $this->_connectionID );
|
||||
if ($username && $password) {
|
||||
$bind = ldap_bind( $this->_connectionID, $username, $password )
|
||||
or die( 'Could not bind to ' . $this->_connectionID . ' with $username & $password');
|
||||
} else {
|
||||
$bind = ldap_bind( $this->_connectionID )
|
||||
or die( 'Could not bind anonymously to ' . $this->_connectionID );
|
||||
}
|
||||
return $this->_connectionID;
|
||||
}
|
||||
|
||||
|
||||
/* returns _queryID or false */
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
$rs = ldap_search( $this->_connectionID, $this->database, $sql );
|
||||
return $rs;
|
||||
|
||||
}
|
||||
|
||||
/* closes the LDAP connection */
|
||||
function _close()
|
||||
{
|
||||
@ldap_close( $this->_connectionID );
|
||||
$this->_connectionID = false;
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
if( is_array( $this->version ) ) return $this->version;
|
||||
$version = array();
|
||||
/*
|
||||
Determines how aliases are handled during search.
|
||||
LDAP_DEREF_NEVER (0x00)
|
||||
LDAP_DEREF_SEARCHING (0x01)
|
||||
LDAP_DEREF_FINDING (0x02)
|
||||
LDAP_DEREF_ALWAYS (0x03)
|
||||
The LDAP_DEREF_SEARCHING value means aliases are dereferenced during the search but
|
||||
not when locating the base object of the search. The LDAP_DEREF_FINDING value means
|
||||
aliases are dereferenced when locating the base object but not during the search.
|
||||
Default: LDAP_DEREF_NEVER
|
||||
*/
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_DEREF, $version['LDAP_OPT_DEREF'] ) ;
|
||||
switch ( $version['LDAP_OPT_DEREF'] ) {
|
||||
case 0:
|
||||
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_NEVER';
|
||||
case 1:
|
||||
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_SEARCHING';
|
||||
case 2:
|
||||
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_FINDING';
|
||||
case 3:
|
||||
$version['LDAP_OPT_DEREF'] = 'LDAP_DEREF_ALWAYS';
|
||||
}
|
||||
|
||||
/*
|
||||
A limit on the number of entries to return from a search.
|
||||
LDAP_NO_LIMIT (0) means no limit.
|
||||
Default: LDAP_NO_LIMIT
|
||||
*/
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_SIZELIMIT, $version['LDAP_OPT_SIZELIMIT'] );
|
||||
if ( $version['LDAP_OPT_SIZELIMIT'] == 0 ) {
|
||||
$version['LDAP_OPT_SIZELIMIT'] = 'LDAP_NO_LIMIT';
|
||||
}
|
||||
|
||||
/*
|
||||
A limit on the number of seconds to spend on a search.
|
||||
LDAP_NO_LIMIT (0) means no limit.
|
||||
Default: LDAP_NO_LIMIT
|
||||
*/
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_TIMELIMIT, $version['LDAP_OPT_TIMELIMIT'] );
|
||||
if ( $version['LDAP_OPT_TIMELIMIT'] == 0 ) {
|
||||
$version['LDAP_OPT_TIMELIMIT'] = 'LDAP_NO_LIMIT';
|
||||
}
|
||||
|
||||
/*
|
||||
Determines whether the LDAP library automatically follows referrals returned by LDAP servers or not.
|
||||
LDAP_OPT_ON
|
||||
LDAP_OPT_OFF
|
||||
Default: ON
|
||||
*/
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_REFERRALS, $version['LDAP_OPT_REFERRALS'] );
|
||||
if ( $version['LDAP_OPT_REFERRALS'] == 0 ) {
|
||||
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_OFF';
|
||||
} else {
|
||||
$version['LDAP_OPT_REFERRALS'] = 'LDAP_OPT_ON';
|
||||
|
||||
}
|
||||
/*
|
||||
Determines whether LDAP I/O operations are automatically restarted if they abort prematurely.
|
||||
LDAP_OPT_ON
|
||||
LDAP_OPT_OFF
|
||||
Default: OFF
|
||||
*/
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_RESTART, $version['LDAP_OPT_RESTART'] );
|
||||
if ( $version['LDAP_OPT_RESTART'] == 0 ) {
|
||||
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_OFF';
|
||||
} else {
|
||||
$version['LDAP_OPT_RESTART'] = 'LDAP_OPT_ON';
|
||||
|
||||
}
|
||||
/*
|
||||
This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server.
|
||||
LDAP_VERSION2 (2)
|
||||
LDAP_VERSION3 (3)
|
||||
Default: LDAP_VERSION2 (2)
|
||||
*/
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_PROTOCOL_VERSION, $version['LDAP_OPT_PROTOCOL_VERSION'] );
|
||||
if ( $version['LDAP_OPT_PROTOCOL_VERSION'] == 2 ) {
|
||||
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION2';
|
||||
} else {
|
||||
$version['LDAP_OPT_PROTOCOL_VERSION'] = 'LDAP_VERSION3';
|
||||
|
||||
}
|
||||
/* The host name (or list of hosts) for the primary LDAP server. */
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_HOST_NAME, $version['LDAP_OPT_HOST_NAME'] );
|
||||
ldap_get_option( $this->_connectionID, OPT_ERROR_NUMBER, $version['OPT_ERROR_NUMBER'] );
|
||||
ldap_get_option( $this->_connectionID, OPT_ERROR_STRING, $version['OPT_ERROR_STRING'] );
|
||||
ldap_get_option( $this->_connectionID, LDAP_OPT_MATCHED_DN, $version['LDAP_OPT_MATCHED_DN'] );
|
||||
|
||||
return $this->version = $version;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_ldap extends ADORecordSet{
|
||||
|
||||
var $databaseType = "ldap";
|
||||
var $canSeek = false;
|
||||
var $_entryID; /* keeps track of the entry resource identifier */
|
||||
|
||||
function ADORecordSet_ldap($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM:
|
||||
$this->fetchMode = LDAP_NUM;
|
||||
break;
|
||||
case ADODB_FETCH_ASSOC:
|
||||
$this->fetchMode = LDAP_ASSOC;
|
||||
break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:
|
||||
$this->fetchMode = LDAP_BOTH;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
/*
|
||||
This could be teaked to respect the $COUNTRECS directive from ADODB
|
||||
It's currently being used in the _fetch() function and the
|
||||
GetAssoc() function
|
||||
*/
|
||||
$this->_numOfRows = ldap_count_entries( $this->connection->_connectionID, $this->_queryID );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Return whole recordset as a multi-dimensional associative array
|
||||
*/
|
||||
function &GetAssoc($force_array = false, $first2cols = false)
|
||||
{
|
||||
$records = $this->_numOfRows;
|
||||
$results = array();
|
||||
for ( $i=0; $i < $records; $i++ ) {
|
||||
foreach ( $this->fields as $k=>$v ) {
|
||||
if ( is_array( $v ) ) {
|
||||
if ( $v['count'] == 1 ) {
|
||||
$results[$i][$k] = $v[0];
|
||||
} else {
|
||||
array_shift( $v );
|
||||
$results[$i][$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
function &GetRowAssoc()
|
||||
{
|
||||
$results = array();
|
||||
foreach ( $this->fields as $k=>$v ) {
|
||||
if ( is_array( $v ) ) {
|
||||
if ( $v['count'] == 1 ) {
|
||||
$results[$k] = $v[0];
|
||||
} else {
|
||||
array_shift( $v );
|
||||
$results[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
function GetRowNums()
|
||||
{
|
||||
$results = array();
|
||||
foreach ( $this->fields as $k=>$v ) {
|
||||
static $i = 0;
|
||||
if (is_array( $v )) {
|
||||
if ( $v['count'] == 1 ) {
|
||||
$results[$i] = $v[0];
|
||||
} else {
|
||||
array_shift( $v );
|
||||
$results[$i] = $v;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
if ( $this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0 )
|
||||
return false;
|
||||
|
||||
if ( $this->_currentRow == 0 ) {
|
||||
$this->_entryID = ldap_first_entry( $this->connection->_connectionID, $this->_queryID );
|
||||
} else {
|
||||
$this->_entryID = ldap_next_entry( $this->connection->_connectionID, $this->_entryID );
|
||||
}
|
||||
|
||||
$this->fields = ldap_get_attributes( $this->connection->_connectionID, $this->_entryID );
|
||||
$this->_numOfFields = $this->fields['count'];
|
||||
switch ( $this->fetchMode ) {
|
||||
|
||||
case LDAP_ASSOC:
|
||||
$this->fields = $this->GetRowAssoc();
|
||||
break;
|
||||
|
||||
case LDAP_NUM:
|
||||
$this->fields = $this->GetRowNums();
|
||||
break;
|
||||
|
||||
case LDAP_BOTH:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ( is_array( $this->fields ) );
|
||||
}
|
||||
|
||||
function _close() {
|
||||
@ldap_free_result( $this->_queryID );
|
||||
$this->_queryID = false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
952
phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php
Normal file
952
phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php
Normal file
@ -0,0 +1,952 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Native mssql driver. Requires mssql client. Works on Windows.
|
||||
To configure for Unix, see
|
||||
http://phpbuilder.com/columns/alberto20000919.php3
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// MSSQL returns dates with the format Oct 13 2002 or 13 Oct 2002
|
||||
// and this causes tons of problems because localized versions of
|
||||
// MSSQL will return the dates in dmy or mdy order; and also the
|
||||
// month strings depends on what language has been configured. The
|
||||
// following two variables allow you to control the localization
|
||||
// settings - Ugh.
|
||||
//
|
||||
// MORE LOCALIZATION INFO
|
||||
// ----------------------
|
||||
// To configure datetime, look for and modify sqlcommn.loc,
|
||||
// typically found in c:\mssql\install
|
||||
// Also read :
|
||||
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
|
||||
// Alternatively use:
|
||||
// CONVERT(char(12),datecol,120)
|
||||
//----------------------------------------------------------------
|
||||
|
||||
|
||||
// has datetime converstion to YYYY-MM-DD format, and also mssql_fetch_assoc
|
||||
if (ADODB_PHPVER >= 0x4300) {
|
||||
// docs say 4.2.0, but testing shows only since 4.3.0 does it work!
|
||||
ini_set('mssql.datetimeconvert',0);
|
||||
} else {
|
||||
global $ADODB_mssql_mths; // array, months must be upper-case
|
||||
|
||||
|
||||
$ADODB_mssql_date_order = 'mdy';
|
||||
$ADODB_mssql_mths = array(
|
||||
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
|
||||
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Call this to autoset $ADODB_mssql_date_order at the beginning of your code,
|
||||
// just after you connect to the database. Supports mdy and dmy only.
|
||||
// Not required for PHP 4.2.0 and above.
|
||||
function AutoDetect_MSSQL_Date_Order($conn)
|
||||
{
|
||||
global $ADODB_mssql_date_order;
|
||||
$adate = $conn->GetOne('select getdate()');
|
||||
if ($adate) {
|
||||
$anum = (int) $adate;
|
||||
if ($anum > 0) {
|
||||
if ($anum > 31) {
|
||||
//ADOConnection::outp( "MSSQL: YYYY-MM-DD date format not supported currently");
|
||||
} else
|
||||
$ADODB_mssql_date_order = 'dmy';
|
||||
} else
|
||||
$ADODB_mssql_date_order = 'mdy';
|
||||
}
|
||||
}
|
||||
|
||||
class ADODB_mssql extends ADOConnection {
|
||||
var $databaseType = "mssql";
|
||||
var $dataProvider = "mssql";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d h:i:sA'";
|
||||
var $hasInsertID = true;
|
||||
var $substr = "substring";
|
||||
var $length = 'len';
|
||||
var $hasAffectedRows = true;
|
||||
var $metaDatabasesSQL = "select name from sysdatabases where name <> 'master'";
|
||||
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
|
||||
var $metaColumnsSQL = # xtype==61 is datetime
|
||||
"select c.name,t.name,c.length,
|
||||
(case when c.xusertype=61 then 0 else c.xprec end),
|
||||
(case when c.xusertype=61 then 0 else c.xscale end)
|
||||
from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
|
||||
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
|
||||
var $hasGenID = true;
|
||||
var $sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
||||
var $sysTimeStamp = 'GetDate()';
|
||||
var $_has_mssql_init;
|
||||
var $maxParameterLen = 4000;
|
||||
var $arrayClass = 'ADORecordSet_array_mssql';
|
||||
var $uniqueSort = true;
|
||||
var $leftOuter = '*=';
|
||||
var $rightOuter = '=*';
|
||||
var $ansiOuter = true; // for mssql7 or later
|
||||
var $poorAffectedRows = true;
|
||||
var $identitySQL = 'select @@IDENTITY'; // 'select SCOPE_IDENTITY'; # for mssql 2000
|
||||
var $uniqueOrderBy = true;
|
||||
var $_bindInputArray = true;
|
||||
|
||||
|
||||
function ADODB_mssql()
|
||||
{
|
||||
$this->_has_mssql_init = (strnatcmp(PHP_VERSION,'4.1.0')>=0);
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$stmt = $this->PrepareSP('sp_server_info');
|
||||
$val = 2;
|
||||
if ($this->fetchMode === false) {
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
} else
|
||||
$savem = $this->SetFetchMode(ADODB_FETCH_NUM);
|
||||
|
||||
|
||||
$this->Parameter($stmt,$val,'attribute_id');
|
||||
$row = $this->GetRow($stmt);
|
||||
|
||||
//$row = $this->GetRow("execute sp_server_info 2");
|
||||
|
||||
if ($this->fetchMode === false) {
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
} else
|
||||
$this->SetFetchMode($savem);
|
||||
|
||||
$arr['description'] = $row[2];
|
||||
$arr['version'] = ADOConnection::_findvers($arr['description']);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " ISNULL($field, $ifNull) "; // if MS SQL Server
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
// SCOPE_IDENTITY()
|
||||
// Returns the last IDENTITY value inserted into an IDENTITY column in
|
||||
// the same scope. A scope is a module -- a stored procedure, trigger,
|
||||
// function, or batch. Thus, two statements are in the same scope if
|
||||
// they are in the same stored procedure, function, or batch.
|
||||
return $this->GetOne($this->identitySQL);
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
return $this->GetOne('select @@rowcount');
|
||||
}
|
||||
|
||||
var $_dropSeqSQL = "drop table %s";
|
||||
|
||||
function CreateSequence($seq='adodbseq',$start=1)
|
||||
{
|
||||
$start -= 1;
|
||||
$this->Execute("create table $seq (id float(53))");
|
||||
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
|
||||
if (!$ok) {
|
||||
$this->Execute('ROLLBACK TRANSACTION adodbseq');
|
||||
return false;
|
||||
}
|
||||
$this->Execute('COMMIT TRANSACTION adodbseq');
|
||||
return true;
|
||||
}
|
||||
|
||||
function GenID($seq='adodbseq',$start=1)
|
||||
{
|
||||
//$this->debug=1;
|
||||
$this->Execute('BEGIN TRANSACTION adodbseq');
|
||||
$ok = $this->Execute("update $seq with (tablock,holdlock) set id = id + 1");
|
||||
if (!$ok) {
|
||||
$this->Execute("create table $seq (id float(53))");
|
||||
$ok = $this->Execute("insert into $seq with (tablock,holdlock) values($start)");
|
||||
if (!$ok) {
|
||||
$this->Execute('ROLLBACK TRANSACTION adodbseq');
|
||||
return false;
|
||||
}
|
||||
$this->Execute('COMMIT TRANSACTION adodbseq');
|
||||
return $start;
|
||||
}
|
||||
$num = $this->GetOne("select id from $seq");
|
||||
$this->Execute('COMMIT TRANSACTION adodbseq');
|
||||
return $num;
|
||||
|
||||
// in old implementation, pre 1.90, we returned GUID...
|
||||
//return $this->GetOne("SELECT CONVERT(varchar(255), NEWID()) AS 'Char'");
|
||||
}
|
||||
|
||||
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
|
||||
{
|
||||
if ($nrows > 0 && $offset <= 0) {
|
||||
$sql = preg_replace(
|
||||
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
|
||||
$rs =& $this->Execute($sql,$inputarr);
|
||||
} else
|
||||
$rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = '';
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($s) $s .= '+';
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= "datename(yyyy,$col)";
|
||||
break;
|
||||
case 'M':
|
||||
$s .= "convert(char(3),$col,0)";
|
||||
break;
|
||||
case 'm':
|
||||
$s .= "replace(str(month($col),2),' ','0')";
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "datename(quarter,$col)";
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= "replace(str(day($col),2),' ','0')";
|
||||
break;
|
||||
case 'h':
|
||||
$s .= "substring(convert(char(14),$col,0),13,2)";
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
|
||||
break;
|
||||
case 's':
|
||||
$s .= "replace(str(datepart(ss,$col),2),' ','0')";
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= "substring(convert(char(19),$col,0),18,2)";
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $this->qstr($ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('BEGIN TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('COMMIT TRAN');
|
||||
return true;
|
||||
}
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('ROLLBACK TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Usage:
|
||||
|
||||
$this->BeginTrans();
|
||||
$this->RowLock('table1,table2','table1.id=33 and table2.id=table1.id'); # lock row 33 for both tables
|
||||
|
||||
# some operation on both tables table1 and table2
|
||||
|
||||
$this->CommitTrans();
|
||||
|
||||
See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
|
||||
*/
|
||||
function RowLock($tables,$where)
|
||||
{
|
||||
if (!$this->transCnt) $this->BeginTrans();
|
||||
return $this->GetOne("select top 1 null as ignore from $tables with (ROWLOCK,HOLDLOCK) where $where");
|
||||
}
|
||||
|
||||
function MetaForeignKeys($table, $owner=false, $upper=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$table = $this->qstr(strtoupper($table));
|
||||
|
||||
$sql =
|
||||
"select object_name(constid) as constraint_name,
|
||||
col_name(fkeyid, fkey) as column_name,
|
||||
object_name(rkeyid) as referenced_table_name,
|
||||
col_name(rkeyid, rkey) as referenced_column_name
|
||||
from sysforeignkeys
|
||||
where upper(object_name(fkeyid)) = $table
|
||||
order by constraint_name, referenced_table_name, keyno";
|
||||
|
||||
$constraints =& $this->GetArray($sql);
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
$arr = false;
|
||||
foreach($constraints as $constr) {
|
||||
//print_r($constr);
|
||||
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
|
||||
}
|
||||
if (!$arr) return false;
|
||||
|
||||
$arr2 = false;
|
||||
|
||||
foreach($arr as $k => $v) {
|
||||
foreach($v as $a => $b) {
|
||||
if ($upper) $a = strtoupper($a);
|
||||
$arr2[$a] = $b;
|
||||
}
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
//From: Fernando Moreira <FMoreira@imediata.pt>
|
||||
function MetaDatabases()
|
||||
{
|
||||
if(@mssql_select_db("master")) {
|
||||
$qry=$this->metaDatabasesSQL;
|
||||
if($rs=@mssql_query($qry)){
|
||||
$tmpAr=$ar=array();
|
||||
while($tmpAr=@mssql_fetch_row($rs))
|
||||
$ar[]=$tmpAr[0];
|
||||
@mssql_select_db($this->databaseName);
|
||||
if(sizeof($ar))
|
||||
return($ar);
|
||||
else
|
||||
return(false);
|
||||
} else {
|
||||
@mssql_select_db($this->databaseName);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
// "Stein-Aksel Basma" <basma@accelero.no>
|
||||
// tested with MSSQL 2000
|
||||
function &MetaPrimaryKeys($table)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
if (!$schema) $schema = $this->database;
|
||||
if ($schema) $schema = "and k.table_catalog like '$schema%'";
|
||||
|
||||
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
|
||||
information_schema.table_constraints tc
|
||||
where tc.constraint_name = k.constraint_name and tc.constraint_type =
|
||||
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$a = $this->GetCol($sql);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if ($a && sizeof($a)>0) return $a;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function &MetaTables($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
if ($mask) {
|
||||
$save = $this->metaTablesSQL;
|
||||
$mask = $this->qstr(($mask));
|
||||
$this->metaTablesSQL .= " AND name like $mask";
|
||||
}
|
||||
$ret =& ADOConnection::MetaTables($ttype,$showSchema);
|
||||
|
||||
if ($mask) {
|
||||
$this->metaTablesSQL = $save;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function SelectDB($dbName)
|
||||
{
|
||||
$this->databaseName = $dbName;
|
||||
if ($this->_connectionID) {
|
||||
return @mssql_select_db($dbName);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if (empty($this->_errorMsg)){
|
||||
$this->_errorMsg = mssql_get_last_message();
|
||||
}
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if ($this->_logsql && $this->_errorCode !== false) return $this->_errorCode;
|
||||
if (empty($this->_errorMsg)) {
|
||||
$this->_errorMsg = mssql_get_last_message();
|
||||
}
|
||||
$id = @mssql_query("select @@ERROR",$this->_connectionID);
|
||||
if (!$id) return false;
|
||||
$arr = mssql_fetch_array($id);
|
||||
@mssql_free_result($id);
|
||||
if (is_array($arr)) return $arr[0];
|
||||
else return -1;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('mssql_pconnect')) return null;
|
||||
$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('mssql_pconnect')) return null;
|
||||
$this->_connectionID = mssql_pconnect($argHostname,$argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
|
||||
// persistent connections can forget to rollback on crash, so we do it here.
|
||||
if ($this->autoRollback) {
|
||||
$cnt = $this->GetOne('select @@TRANCOUNT');
|
||||
while (--$cnt >= 0) $this->Execute('ROLLBACK TRAN');
|
||||
}
|
||||
if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
|
||||
function Prepare($sql)
|
||||
{
|
||||
$sqlarr = explode('?',$sql);
|
||||
if (sizeof($sqlarr) <= 1) return $sql;
|
||||
$sql2 = $sqlarr[0];
|
||||
for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
|
||||
$sql2 .= '@P'.($i-1) . $sqlarr[$i];
|
||||
}
|
||||
return array($sql,$this->qstr($sql2),$max);
|
||||
}
|
||||
|
||||
function PrepareSP($sql)
|
||||
{
|
||||
if (!$this->_has_mssql_init) {
|
||||
ADOConnection::outp( "PrepareSP: mssql_init only available since PHP 4.1.0");
|
||||
return $sql;
|
||||
}
|
||||
$stmt = mssql_init($sql,$this->_connectionID);
|
||||
if (!$stmt) return $sql;
|
||||
return array($sql,$stmt);
|
||||
}
|
||||
|
||||
/*
|
||||
Usage:
|
||||
$stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
|
||||
|
||||
# note that the parameter does not have @ in front!
|
||||
$db->Parameter($stmt,$id,'myid');
|
||||
$db->Parameter($stmt,$group,'group',false,64);
|
||||
$db->Execute($stmt);
|
||||
|
||||
@param $stmt Statement returned by Prepare() or PrepareSP().
|
||||
@param $var PHP variable to bind to. Can set to null (for isNull support).
|
||||
@param $name Name of stored procedure variable name to bind to.
|
||||
@param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
|
||||
@param [$maxLen] Holds an maximum length of the variable.
|
||||
@param [$type] The data type of $var. Legal values depend on driver.
|
||||
|
||||
See mssql_bind documentation at php.net.
|
||||
*/
|
||||
function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=4000, $type=false)
|
||||
{
|
||||
if (!$this->_has_mssql_init) {
|
||||
ADOConnection::outp( "Parameter: mssql_bind only available since PHP 4.1.0");
|
||||
return $sql;
|
||||
}
|
||||
|
||||
$isNull = is_null($var); // php 4.0.4 and above...
|
||||
|
||||
if ($type === false)
|
||||
switch(gettype($var)) {
|
||||
default:
|
||||
case 'string': $type = SQLCHAR; break;
|
||||
case 'double': $type = SQLFLT8; break;
|
||||
case 'integer': $type = SQLINT4; break;
|
||||
case 'boolean': $type = SQLINT1; break; # SQLBIT not supported in 4.1.0
|
||||
}
|
||||
|
||||
if ($this->debug) {
|
||||
$prefix = ($isOutput) ? 'Out' : 'In';
|
||||
$ztype = (empty($type)) ? 'false' : $type;
|
||||
ADOConnection::outp( "{$prefix}Parameter(\$stmt, \$php_var='$var', \$name='$name', \$maxLen=$maxLen, \$type=$ztype);");
|
||||
}
|
||||
/*
|
||||
See http://phplens.com/lens/lensforum/msgs.php?id=7231
|
||||
|
||||
RETVAL is HARD CODED into php_mssql extension:
|
||||
The return value (a long integer value) is treated like a special OUTPUT parameter,
|
||||
called "RETVAL" (without the @). See the example at mssql_execute to
|
||||
see how it works. - type: one of this new supported PHP constants.
|
||||
SQLTEXT, SQLVARCHAR,SQLCHAR, SQLINT1,SQLINT2, SQLINT4, SQLBIT,SQLFLT8
|
||||
*/
|
||||
if ($name !== 'RETVAL') $name = '@'.$name;
|
||||
return mssql_bind($stmt[1], $name, $var, $type, $isOutput, $isNull, $maxLen);
|
||||
}
|
||||
|
||||
/*
|
||||
Unfortunately, it appears that mssql cannot handle varbinary > 255 chars
|
||||
So all your blobs must be of type "image".
|
||||
|
||||
Remember to set in php.ini the following...
|
||||
|
||||
; Valid range 0 - 2147483647. Default = 4096.
|
||||
mssql.textlimit = 0 ; zero to pass through
|
||||
|
||||
; Valid range 0 - 2147483647. Default = 4096.
|
||||
mssql.textsize = 0 ; zero to pass through
|
||||
*/
|
||||
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
|
||||
{
|
||||
|
||||
if (strtoupper($blobtype) == 'CLOB') {
|
||||
$sql = "UPDATE $table SET $column='" . $val . "' WHERE $where";
|
||||
return $this->Execute($sql) != false;
|
||||
}
|
||||
$sql = "UPDATE $table SET $column=0x".bin2hex($val)." WHERE $where";
|
||||
return $this->Execute($sql) != false;
|
||||
}
|
||||
|
||||
// returns query ID if successful, otherwise false
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
$this->_errorMsg = false;
|
||||
if (is_array($inputarr)) {
|
||||
|
||||
# bind input params with sp_executesql:
|
||||
# see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
|
||||
# works only with sql server 7 and newer
|
||||
if (!is_array($sql)) $sql = $this->Prepare($sql);
|
||||
$params = '';
|
||||
$decl = '';
|
||||
$i = 0;
|
||||
foreach($inputarr as $v) {
|
||||
if ($decl) {
|
||||
$decl .= ', ';
|
||||
$params .= ', ';
|
||||
}
|
||||
if (is_string($v)) {
|
||||
$len = strlen($v);
|
||||
if ($len == 0) $len = 1;
|
||||
|
||||
if ($len > 4000 ) {
|
||||
// NVARCHAR is max 4000 chars. Let's use NTEXT
|
||||
$decl .= "@P$i NTEXT";
|
||||
} else {
|
||||
$decl .= "@P$i NVARCHAR($len)";
|
||||
}
|
||||
|
||||
$params .= "@P$i=N". (strncmp($v,"'",1)==0? $v : $this->qstr($v));
|
||||
} else if (is_integer($v)) {
|
||||
$decl .= "@P$i INT";
|
||||
$params .= "@P$i=".$v;
|
||||
} else if (is_float($v)) {
|
||||
$decl .= "@P$i FLOAT";
|
||||
$params .= "@P$i=".$v;
|
||||
} else if (is_bool($v)) {
|
||||
$decl .= "@P$i INT"; # Used INT just in case BIT in not supported on the user's MSSQL version. It will cast appropriately.
|
||||
$params .= "@P$i=".(($v)?'1':'0'); # True == 1 in MSSQL BIT fields and acceptable for storing logical true in an int field
|
||||
} else {
|
||||
$decl .= "@P$i CHAR"; # Used char because a type is required even when the value is to be NULL.
|
||||
$params .= "@P$i=NULL";
|
||||
}
|
||||
$i += 1;
|
||||
}
|
||||
$decl = $this->qstr($decl);
|
||||
if ($this->debug) ADOConnection::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>");
|
||||
$rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params");
|
||||
|
||||
} else if (is_array($sql)) {
|
||||
# PrepareSP()
|
||||
$rez = mssql_execute($sql[1]);
|
||||
|
||||
} else {
|
||||
$rez = mssql_query($sql,$this->_connectionID);
|
||||
}
|
||||
return $rez;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
if ($this->transCnt) $this->RollbackTrans();
|
||||
$rez = @mssql_close($this->_connectionID);
|
||||
$this->_connectionID = false;
|
||||
return $rez;
|
||||
}
|
||||
|
||||
// mssql uses a default date like Dec 30 2000 12:00AM
|
||||
function UnixDate($v)
|
||||
{
|
||||
return ADORecordSet_array_mssql::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return ADORecordSet_array_mssql::UnixTimeStamp($v);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordset_mssql extends ADORecordSet {
|
||||
|
||||
var $databaseType = "mssql";
|
||||
var $canSeek = true;
|
||||
var $hasFetchAssoc; // see http://phplens.com/lens/lensforum/msgs.php?id=6083
|
||||
// _mths works only in non-localised system
|
||||
|
||||
function ADORecordset_mssql($id,$mode=false)
|
||||
{
|
||||
// freedts check...
|
||||
$this->hasFetchAssoc = function_exists('mssql_fetch_assoc');
|
||||
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
$this->fetchMode = $mode;
|
||||
return $this->ADORecordSet($id,$mode);
|
||||
}
|
||||
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
GLOBAL $ADODB_COUNTRECS;
|
||||
$this->_numOfRows = ($ADODB_COUNTRECS)? @mssql_num_rows($this->_queryID):-1;
|
||||
$this->_numOfFields = @mssql_num_fields($this->_queryID);
|
||||
}
|
||||
|
||||
|
||||
//Contributed by "Sven Axelsson" <sven.axelsson@bokochwebb.se>
|
||||
// get next resultset - requires PHP 4.0.5 or later
|
||||
function NextRecordSet()
|
||||
{
|
||||
if (!mssql_next_result($this->_queryID)) return false;
|
||||
$this->_inited = false;
|
||||
$this->bind = false;
|
||||
$this->_currentRow = -1;
|
||||
$this->Init();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode != ADODB_FETCH_NUM) return $this->fields[$colname];
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
/* Returns: an object containing field information.
|
||||
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
|
||||
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
|
||||
fetchField() is retrieved. */
|
||||
|
||||
function FetchField($fieldOffset = -1)
|
||||
{
|
||||
if ($fieldOffset != -1) {
|
||||
return @mssql_fetch_field($this->_queryID, $fieldOffset);
|
||||
}
|
||||
else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
|
||||
return @mssql_fetch_field($this->_queryID);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return @mssql_data_seek($this->_queryID, $row);
|
||||
}
|
||||
|
||||
// speedup
|
||||
function MoveNext()
|
||||
{
|
||||
if ($this->EOF) return false;
|
||||
|
||||
$this->_currentRow++;
|
||||
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
if ($this->fetchMode & ADODB_FETCH_NUM) {
|
||||
//ADODB_FETCH_BOTH mode
|
||||
$this->fields = @mssql_fetch_array($this->_queryID);
|
||||
}
|
||||
else {
|
||||
if ($this->hasFetchAssoc) {// only for PHP 4.2.0 or later
|
||||
$this->fields = @mssql_fetch_assoc($this->_queryID);
|
||||
} else {
|
||||
$flds = @mssql_fetch_array($this->_queryID);
|
||||
if (is_array($flds)) {
|
||||
$fassoc = array();
|
||||
foreach($flds as $k => $v) {
|
||||
if (is_numeric($k)) continue;
|
||||
$fassoc[$k] = $v;
|
||||
}
|
||||
$this->fields = $fassoc;
|
||||
} else
|
||||
$this->fields = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($this->fields)) {
|
||||
if (ADODB_ASSOC_CASE == 0) {
|
||||
foreach($this->fields as $k=>$v) {
|
||||
$this->fields[strtolower($k)] = $v;
|
||||
}
|
||||
} else if (ADODB_ASSOC_CASE == 1) {
|
||||
foreach($this->fields as $k=>$v) {
|
||||
$this->fields[strtoupper($k)] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->fields = @mssql_fetch_row($this->_queryID);
|
||||
}
|
||||
if ($this->fields) return true;
|
||||
$this->EOF = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// INSERT UPDATE DELETE returns false even if no error occurs in 4.0.4
|
||||
// also the date format has been changed from YYYY-mm-dd to dd MMM YYYY in 4.0.4. Idiot!
|
||||
function _fetch($ignore_fields=false)
|
||||
{
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
if ($this->fetchMode & ADODB_FETCH_NUM) {
|
||||
//ADODB_FETCH_BOTH mode
|
||||
$this->fields = @mssql_fetch_array($this->_queryID);
|
||||
} else {
|
||||
if ($this->hasFetchAssoc) // only for PHP 4.2.0 or later
|
||||
$this->fields = @mssql_fetch_assoc($this->_queryID);
|
||||
else {
|
||||
$this->fields = @mssql_fetch_array($this->_queryID);
|
||||
if (@is_array($$this->fields)) {
|
||||
$fassoc = array();
|
||||
foreach($$this->fields as $k => $v) {
|
||||
if (is_integer($k)) continue;
|
||||
$fassoc[$k] = $v;
|
||||
}
|
||||
$this->fields = $fassoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->fields) {
|
||||
} else if (ADODB_ASSOC_CASE == 0) {
|
||||
foreach($this->fields as $k=>$v) {
|
||||
$this->fields[strtolower($k)] = $v;
|
||||
}
|
||||
} else if (ADODB_ASSOC_CASE == 1) {
|
||||
foreach($this->fields as $k=>$v) {
|
||||
$this->fields[strtoupper($k)] = $v;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->fields = @mssql_fetch_row($this->_queryID);
|
||||
}
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
/* close() only needs to be called if you are worried about using too much memory while your script
|
||||
is running. All associated result memory for the specified result identifier will automatically be freed. */
|
||||
|
||||
function _close()
|
||||
{
|
||||
$rez = mssql_free_result($this->_queryID);
|
||||
$this->_queryID = false;
|
||||
return $rez;
|
||||
}
|
||||
// mssql uses a default date like Dec 30 2000 12:00AM
|
||||
function UnixDate($v)
|
||||
{
|
||||
return ADORecordSet_array_mssql::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return ADORecordSet_array_mssql::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ADORecordSet_array_mssql extends ADORecordSet_array {
|
||||
function ADORecordSet_array_mssql($id=-1,$mode=false)
|
||||
{
|
||||
$this->ADORecordSet_array($id,$mode);
|
||||
}
|
||||
|
||||
// mssql uses a default date like Dec 30 2000 12:00AM
|
||||
function UnixDate($v)
|
||||
{
|
||||
|
||||
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
|
||||
|
||||
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
|
||||
|
||||
//Dec 30 2000 12:00AM
|
||||
if ($ADODB_mssql_date_order == 'dmy') {
|
||||
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
|
||||
return parent::UnixDate($v);
|
||||
}
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
|
||||
|
||||
$theday = $rr[1];
|
||||
$themth = substr(strtoupper($rr[2]),0,3);
|
||||
} else {
|
||||
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})|" ,$v, $rr)) {
|
||||
return parent::UnixDate($v);
|
||||
}
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
|
||||
|
||||
$theday = $rr[2];
|
||||
$themth = substr(strtoupper($rr[1]),0,3);
|
||||
}
|
||||
$themth = $ADODB_mssql_mths[$themth];
|
||||
if ($themth <= 0) return false;
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime(0,0,0,$themth,$theday,$rr[3]);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
|
||||
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
|
||||
|
||||
global $ADODB_mssql_mths,$ADODB_mssql_date_order;
|
||||
|
||||
//Dec 30 2000 12:00AM
|
||||
if ($ADODB_mssql_date_order == 'dmy') {
|
||||
if (!preg_match( "|^([0-9]{1,2})[-/\. ]+([A-Za-z]{3})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
|
||||
,$v, $rr)) return parent::UnixTimeStamp($v);
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
|
||||
|
||||
$theday = $rr[1];
|
||||
$themth = substr(strtoupper($rr[2]),0,3);
|
||||
} else {
|
||||
if (!preg_match( "|^([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})|"
|
||||
,$v, $rr)) return parent::UnixTimeStamp($v);
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
|
||||
|
||||
$theday = $rr[2];
|
||||
$themth = substr(strtoupper($rr[1]),0,3);
|
||||
}
|
||||
|
||||
$themth = $ADODB_mssql_mths[$themth];
|
||||
if ($themth <= 0) return false;
|
||||
|
||||
switch (strtoupper($rr[6])) {
|
||||
case 'P':
|
||||
if ($rr[4]<12) $rr[4] += 12;
|
||||
break;
|
||||
case 'A':
|
||||
if ($rr[4]==12) $rr[4] = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime($rr[4],$rr[5],0,$themth,$theday,$rr[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Code Example 1:
|
||||
|
||||
select object_name(constid) as constraint_name,
|
||||
object_name(fkeyid) as table_name,
|
||||
col_name(fkeyid, fkey) as column_name,
|
||||
object_name(rkeyid) as referenced_table_name,
|
||||
col_name(rkeyid, rkey) as referenced_column_name
|
||||
from sysforeignkeys
|
||||
where object_name(fkeyid) = x
|
||||
order by constraint_name, table_name, referenced_table_name, keyno
|
||||
|
||||
Code Example 2:
|
||||
select constraint_name,
|
||||
column_name,
|
||||
ordinal_position
|
||||
from information_schema.key_column_usage
|
||||
where constraint_catalog = db_name()
|
||||
and table_name = x
|
||||
order by constraint_name, ordinal_position
|
||||
|
||||
http://www.databasejournal.com/scripts/article.php/1440551
|
||||
*/
|
||||
|
||||
?>
|
707
phpgwapi/inc/adodb/drivers/adodb-mysql.inc.php
Normal file
707
phpgwapi/inc/adodb/drivers/adodb-mysql.inc.php
Normal file
@ -0,0 +1,707 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
|
||||
MySQL code that does not support transactions. Use mysqlt if you need transactions.
|
||||
Requires mysql client. Works on Windows and Unix.
|
||||
|
||||
28 Feb 2001: MetaColumns bug fix - suggested by Freek Dijkstra (phpeverywhere@macfreek.com)
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (! defined("_ADODB_MYSQL_LAYER")) {
|
||||
define("_ADODB_MYSQL_LAYER", 1 );
|
||||
|
||||
class ADODB_mysql extends ADOConnection {
|
||||
var $databaseType = 'mysql';
|
||||
var $dataProvider = 'mysql';
|
||||
var $hasInsertID = true;
|
||||
var $hasAffectedRows = true;
|
||||
var $metaTablesSQL = "SHOW TABLES";
|
||||
var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $hasLimit = true;
|
||||
var $hasMoveFirst = true;
|
||||
var $hasGenID = true;
|
||||
var $isoDates = true; // accepts dates in ISO format
|
||||
var $sysDate = 'CURDATE()';
|
||||
var $sysTimeStamp = 'NOW()';
|
||||
var $hasTransactions = false;
|
||||
var $forceNewConnect = false;
|
||||
var $poorAffectedRows = true;
|
||||
var $clientFlags = 0;
|
||||
var $substr = "substring";
|
||||
var $nameQuote = '`'; /// string to use to quote identifiers and names
|
||||
|
||||
function ADODB_mysql()
|
||||
{
|
||||
if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
$arr['description'] = ADOConnection::GetOne("select version()");
|
||||
$arr['version'] = ADOConnection::_findvers($arr['description']);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " IFNULL($field, $ifNull) "; // if MySQL
|
||||
}
|
||||
|
||||
function &MetaTables($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
$save = $this->metaTablesSQL;
|
||||
if ($showSchema && is_string($showSchema)) {
|
||||
$this->metaTablesSQL .= " from $showSchema";
|
||||
}
|
||||
|
||||
if ($mask) {
|
||||
$mask = $this->qstr($mask);
|
||||
$this->metaTablesSQL .= " like $mask";
|
||||
}
|
||||
$ret =& ADOConnection::MetaTables($ttype,$showSchema);
|
||||
|
||||
$this->metaTablesSQL = $save;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function &MetaIndexes ($table, $primary = FALSE, $owner=false)
|
||||
{
|
||||
// save old fetch mode
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== FALSE) {
|
||||
$savem = $this->SetFetchMode(FALSE);
|
||||
}
|
||||
|
||||
// get index details
|
||||
$rs = $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
|
||||
|
||||
// restore fetchmode
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$indexes = array ();
|
||||
|
||||
// parse index data into array
|
||||
while ($row = $rs->FetchRow()) {
|
||||
if ($primary == FALSE AND $row[2] == 'PRIMARY') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($indexes[$row[2]])) {
|
||||
$indexes[$row[2]] = array(
|
||||
'unique' => ($row[1] == 0),
|
||||
'columns' => array()
|
||||
);
|
||||
}
|
||||
|
||||
$indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
|
||||
}
|
||||
|
||||
// sort columns by order in the index
|
||||
foreach ( array_keys ($indexes) as $index )
|
||||
{
|
||||
ksort ($indexes[$index]['columns']);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
|
||||
// if magic quotes disabled, use mysql_real_escape_string()
|
||||
function qstr($s,$magic_quotes=false)
|
||||
{
|
||||
if (!$magic_quotes) {
|
||||
|
||||
if (ADODB_PHPVER >= 0x4300) {
|
||||
if (is_resource($this->_connectionID))
|
||||
return "'".mysql_real_escape_string($s,$this->_connectionID)."'";
|
||||
}
|
||||
if ($this->replaceQuote[0] == '\\'){
|
||||
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
|
||||
}
|
||||
return "'".str_replace("'",$this->replaceQuote,$s)."'";
|
||||
}
|
||||
|
||||
// undo magic quotes for "
|
||||
$s = str_replace('\\"','"',$s);
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
return mysql_insert_id($this->_connectionID);
|
||||
}
|
||||
|
||||
function GetOne($sql,$inputarr=false)
|
||||
{
|
||||
if (strncasecmp($sql,'sele',4) == 0) {
|
||||
$rs =& $this->SelectLimit($sql,1,-1,$inputarr);
|
||||
if ($rs) {
|
||||
$rs->Close();
|
||||
if ($rs->EOF) return false;
|
||||
return reset($rs->fields);
|
||||
}
|
||||
} else {
|
||||
return ADOConnection::GetOne($sql,$inputarr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->debug) ADOConnection::outp("Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver");
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
return mysql_affected_rows($this->_connectionID);
|
||||
}
|
||||
|
||||
// See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
|
||||
// Reference on Last_Insert_ID on the recommended way to simulate sequences
|
||||
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
|
||||
var $_genSeqSQL = "create table %s (id int not null)";
|
||||
var $_genSeq2SQL = "insert into %s values (%s)";
|
||||
var $_dropSeqSQL = "drop table %s";
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
if (empty($this->_genSeqSQL)) return false;
|
||||
$u = strtoupper($seqname);
|
||||
|
||||
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
|
||||
if (!$ok) return false;
|
||||
return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
|
||||
}
|
||||
|
||||
|
||||
function GenID($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
// post-nuke sets hasGenID to false
|
||||
if (!$this->hasGenID) return false;
|
||||
|
||||
$savelog = $this->_logsql;
|
||||
$this->_logsql = false;
|
||||
$getnext = sprintf($this->_genIDSQL,$seqname);
|
||||
$holdtransOK = $this->_transOK; // save the current status
|
||||
$rs = @$this->Execute($getnext);
|
||||
if (!$rs) {
|
||||
if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
|
||||
$u = strtoupper($seqname);
|
||||
$this->Execute(sprintf($this->_genSeqSQL,$seqname));
|
||||
$this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
|
||||
$rs = $this->Execute($getnext);
|
||||
}
|
||||
$this->genID = mysql_insert_id($this->_connectionID);
|
||||
|
||||
if ($rs) $rs->Close();
|
||||
|
||||
$this->_logsql = $savelog;
|
||||
return $this->genID;
|
||||
}
|
||||
|
||||
function &MetaDatabases()
|
||||
{
|
||||
$qid = mysql_list_dbs($this->_connectionID);
|
||||
$arr = array();
|
||||
$i = 0;
|
||||
$max = mysql_num_rows($qid);
|
||||
while ($i < $max) {
|
||||
$db = mysql_tablename($qid,$i);
|
||||
if ($db != 'mysql') $arr[] = $db;
|
||||
$i += 1;
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = 'DATE_FORMAT('.$col.",'";
|
||||
$concat = false;
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
/** FALL THROUGH */
|
||||
case '-':
|
||||
case '/':
|
||||
$s .= $ch;
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= '%Y';
|
||||
break;
|
||||
case 'M':
|
||||
$s .= '%b';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
$s .= '%m';
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= '%d';
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "'),Quarter($col)";
|
||||
|
||||
if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
|
||||
else $s .= ",('";
|
||||
$concat = true;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= '%H';
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
$s .= '%I';
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= '%i';
|
||||
break;
|
||||
|
||||
case 's':
|
||||
$s .= '%s';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= '%p';
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
$s.="')";
|
||||
if ($concat) $s = "CONCAT($s)";
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
// returns concatenated string
|
||||
// much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
|
||||
function Concat()
|
||||
{
|
||||
$s = "";
|
||||
$arr = func_get_args();
|
||||
|
||||
// suggestion by andrew005@mnogo.ru
|
||||
$s = implode(',',$arr);
|
||||
if (strlen($s) > 0) return "CONCAT($s)";
|
||||
else return '';
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction,$date=false)
|
||||
{
|
||||
if (!$date) $date = $this->sysDate;
|
||||
return "from_unixtime(unix_timestamp($date)+($dayFraction)*24*3600)";
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (ADODB_PHPVER >= 0x4300)
|
||||
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
|
||||
$this->forceNewConnect,$this->clientFlags);
|
||||
else if (ADODB_PHPVER >= 0x4200)
|
||||
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword,
|
||||
$this->forceNewConnect);
|
||||
else
|
||||
$this->_connectionID = mysql_connect($argHostname,$argUsername,$argPassword);
|
||||
|
||||
if ($this->_connectionID === false) return false;
|
||||
if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (ADODB_PHPVER >= 0x4300)
|
||||
$this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword,$this->clientFlags);
|
||||
else
|
||||
$this->_connectionID = mysql_pconnect($argHostname,$argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
if ($this->autoRollback) $this->RollbackTrans();
|
||||
if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
|
||||
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
$this->forceNewConnect = true;
|
||||
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
|
||||
}
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
|
||||
if ($this->metaColumnsSQL) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
|
||||
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rs === false) return false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF){
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$type = $rs->fields[1];
|
||||
|
||||
|
||||
// split type into type(length):
|
||||
$fld->scale = null;
|
||||
if (strpos($type,',') && preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
|
||||
$fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
|
||||
} elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
|
||||
} else {
|
||||
$fld->max_length = -1;
|
||||
$fld->type = $type;
|
||||
}
|
||||
/*
|
||||
// split type into type(length):
|
||||
if (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
|
||||
} else {
|
||||
$fld->max_length = -1;
|
||||
$fld->type = $type;
|
||||
}*/
|
||||
$fld->not_null = ($rs->fields[2] != 'YES');
|
||||
$fld->primary_key = ($rs->fields[3] == 'PRI');
|
||||
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
|
||||
$fld->binary = (strpos($fld->type,'blob') !== false);
|
||||
|
||||
if (!$fld->binary) {
|
||||
$d = $rs->fields[4];
|
||||
if ($d != "" && $d != "NULL") {
|
||||
$fld->has_default = true;
|
||||
$fld->default_value = $d;
|
||||
} else {
|
||||
$fld->has_default = false;
|
||||
}
|
||||
}
|
||||
if ($save == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function SelectDB($dbName)
|
||||
{
|
||||
$this->databaseName = $dbName;
|
||||
if ($this->_connectionID) {
|
||||
return @mysql_select_db($dbName,$this->_connectionID);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
// parameters use PostgreSQL convention, not MySQL
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
|
||||
{
|
||||
$offsetStr =($offset>=0) ? "$offset," : '';
|
||||
// jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
|
||||
if ($nrows < 0) $nrows = '18446744073709551615';
|
||||
|
||||
if ($secs)
|
||||
$rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
|
||||
else
|
||||
$rs =& $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
|
||||
return $rs;
|
||||
}
|
||||
|
||||
// returns queryID or false
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
//global $ADODB_COUNTRECS;
|
||||
//if($ADODB_COUNTRECS)
|
||||
return mysql_query($sql,$this->_connectionID);
|
||||
//else return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
|
||||
}
|
||||
|
||||
/* Returns: the last error message from previous database operation */
|
||||
function ErrorMsg()
|
||||
{
|
||||
|
||||
if ($this->_logsql) return $this->_errorMsg;
|
||||
if (empty($this->_connectionID)) $this->_errorMsg = @mysql_error();
|
||||
else $this->_errorMsg = @mysql_error($this->_connectionID);
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
/* Returns: the last error number from previous database operation */
|
||||
function ErrorNo()
|
||||
{
|
||||
if ($this->_logsql) return $this->_errorCode;
|
||||
if (empty($this->_connectionID)) return @mysql_errno();
|
||||
else return @mysql_errno($this->_connectionID);
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
@mysql_close($this->_connectionID);
|
||||
$this->_connectionID = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Maximum size of C field
|
||||
*/
|
||||
function CharMax()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maximum size of X field
|
||||
*/
|
||||
function TextMax()
|
||||
{
|
||||
return 4294967295;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
class ADORecordSet_mysql extends ADORecordSet{
|
||||
|
||||
var $databaseType = "mysql";
|
||||
var $canSeek = true;
|
||||
|
||||
function ADORecordSet_mysql($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$this->fetchMode = MYSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
//GLOBAL $ADODB_COUNTRECS;
|
||||
// $this->_numOfRows = ($ADODB_COUNTRECS) ? @mysql_num_rows($this->_queryID):-1;
|
||||
$this->_numOfRows = @mysql_num_rows($this->_queryID);
|
||||
$this->_numOfFields = @mysql_num_fields($this->_queryID);
|
||||
}
|
||||
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
if ($fieldOffset != -1) {
|
||||
$o = @mysql_fetch_field($this->_queryID, $fieldOffset);
|
||||
$f = @mysql_field_flags($this->_queryID,$fieldOffset);
|
||||
$o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich@att.com)
|
||||
//$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
|
||||
$o->binary = (strpos($f,'binary')!== false);
|
||||
}
|
||||
else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
|
||||
$o = @mysql_fetch_field($this->_queryID);
|
||||
$o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich@att.com)
|
||||
//$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
|
||||
}
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
function &GetRowAssoc($upper=true)
|
||||
{
|
||||
if ($this->fetchMode == MYSQL_ASSOC && !$upper) return $this->fields;
|
||||
$row =& ADORecordSet::GetRowAssoc($upper);
|
||||
return $row;
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
// added @ by "Michael William Miller" <mille562@pilot.msu.edu>
|
||||
if ($this->fetchMode != MYSQL_NUM) return @$this->fields[$colname];
|
||||
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
if ($this->_numOfRows == 0) return false;
|
||||
return @mysql_data_seek($this->_queryID,$row);
|
||||
}
|
||||
|
||||
function MoveNext()
|
||||
{
|
||||
//return adodb_movenext($this);
|
||||
//if (defined('ADODB_EXTENSION')) return adodb_movenext($this);
|
||||
if (@$this->fields =& mysql_fetch_array($this->_queryID,$this->fetchMode)) {
|
||||
$this->_currentRow += 1;
|
||||
return true;
|
||||
}
|
||||
if (!$this->EOF) {
|
||||
$this->_currentRow += 1;
|
||||
$this->EOF = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = @mysql_fetch_array($this->_queryID,$this->fetchMode);
|
||||
return is_array($this->fields);
|
||||
}
|
||||
|
||||
function _close() {
|
||||
@mysql_free_result($this->_queryID);
|
||||
$this->_queryID = false;
|
||||
}
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
$len = -1; // mysql max_length is not accurate
|
||||
switch (strtoupper($t)) {
|
||||
case 'STRING':
|
||||
case 'CHAR':
|
||||
case 'VARCHAR':
|
||||
case 'TINYBLOB':
|
||||
case 'TINYTEXT':
|
||||
case 'ENUM':
|
||||
case 'SET':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
case 'LONGTEXT':
|
||||
case 'MEDIUMTEXT':
|
||||
return 'X';
|
||||
|
||||
// php_mysql extension always returns 'blob' even if 'text'
|
||||
// so we have to check whether binary...
|
||||
case 'IMAGE':
|
||||
case 'LONGBLOB':
|
||||
case 'BLOB':
|
||||
case 'MEDIUMBLOB':
|
||||
return !empty($fieldobj->binary) ? 'B' : 'X';
|
||||
|
||||
case 'YEAR':
|
||||
case 'DATE': return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP': return 'T';
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER':
|
||||
case 'BIGINT':
|
||||
case 'TINYINT':
|
||||
case 'MEDIUMINT':
|
||||
case 'SMALLINT':
|
||||
|
||||
if (!empty($fieldobj->primary_key)) return 'R';
|
||||
else return 'I';
|
||||
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ADORecordSet_ext_mysql extends ADORecordSet_mysql {
|
||||
function ADORecordSet_ext_mysql($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$this->fetchMode = MYSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function MoveNext()
|
||||
{
|
||||
return adodb_movenext($this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
799
phpgwapi/inc/adodb/drivers/adodb-mysqli.inc.php
Normal file
799
phpgwapi/inc/adodb/drivers/adodb-mysqli.inc.php
Normal file
@ -0,0 +1,799 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
|
||||
MySQL code that does not support transactions. Use mysqlt if you need transactions.
|
||||
Requires mysql client. Works on Windows and Unix.
|
||||
|
||||
21 October 2003: MySQLi extension implementation by Arjen de Rijke (a.de.rijke@xs4all.nl)
|
||||
Based on adodb 3.40
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
//if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (! defined("_ADODB_MYSQLI_LAYER")) {
|
||||
define("_ADODB_MYSQLI_LAYER", 1 );
|
||||
|
||||
class ADODB_mysqli extends ADOConnection {
|
||||
var $databaseType = 'mysqli';
|
||||
var $dataProvider = 'native';
|
||||
var $hasInsertID = true;
|
||||
var $hasAffectedRows = true;
|
||||
var $metaTablesSQL = "SHOW TABLES";
|
||||
var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $hasLimit = true;
|
||||
var $hasMoveFirst = true;
|
||||
var $hasGenID = true;
|
||||
var $isoDates = true; // accepts dates in ISO format
|
||||
var $sysDate = 'CURDATE()';
|
||||
var $sysTimeStamp = 'NOW()';
|
||||
var $hasTransactions = false;
|
||||
var $forceNewConnect = false;
|
||||
var $poorAffectedRows = true;
|
||||
var $clientFlags = 0;
|
||||
var $substr = "substring";
|
||||
var $port = false;
|
||||
var $socket = false;
|
||||
var $_bindInputArray = false;
|
||||
var $nameQuote = '`'; /// string to use to quote identifiers and names
|
||||
|
||||
function ADODB_mysqli()
|
||||
{
|
||||
if(!extension_loaded("mysqli"))
|
||||
trigger_error("You must have the MySQLi extension.", E_USER_ERROR);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
// To add: parameter int $port,
|
||||
// parameter string $socket
|
||||
function _connect($argHostname = NULL,
|
||||
$argUsername = NULL,
|
||||
$argPassword = NULL,
|
||||
$argDatabasename = NULL, $persist=false)
|
||||
{
|
||||
$this->_connectionID = @mysqli_init();
|
||||
|
||||
if (is_null($this->_connectionID)) {
|
||||
// mysqli_init only fails if insufficient memory
|
||||
if ($this->debug)
|
||||
ADOConnection::outp("mysqli_init() failed : " . $this->ErrorMsg());
|
||||
return false;
|
||||
}
|
||||
// Set connection options
|
||||
// Not implemented now
|
||||
// mysqli_options($this->_connection,,);
|
||||
if (mysqli_real_connect($this->_connectionID,
|
||||
$argHostname,
|
||||
$argUsername,
|
||||
$argPassword,
|
||||
$argDatabasename,
|
||||
$this->port,
|
||||
$this->socket,
|
||||
$this->clientFlags))
|
||||
{
|
||||
if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if ($this->debug)
|
||||
ADOConnection::outp("Could't connect : " . $this->ErrorMsg());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
// How to force a persistent connection
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
|
||||
|
||||
}
|
||||
|
||||
// When is this used? Close old connection first?
|
||||
// In _connect(), check $this->forceNewConnect?
|
||||
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
$this->forceNewConnect = true;
|
||||
$this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " IFNULL($field, $ifNull) "; // if MySQL
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
$arr['description'] = $this->GetOne("select version()");
|
||||
$arr['version'] = ADOConnection::_findvers($arr['description']);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('SET AUTOCOMMIT=0');
|
||||
$this->Execute('BEGIN');
|
||||
return true;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('COMMIT');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('ROLLBACK');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
// if magic quotes disabled, use mysql_real_escape_string()
|
||||
// From readme.htm:
|
||||
// Quotes a string to be sent to the database. The $magic_quotes_enabled
|
||||
// parameter may look funny, but the idea is if you are quoting a
|
||||
// string extracted from a POST/GET variable, then
|
||||
// pass get_magic_quotes_gpc() as the second parameter. This will
|
||||
// ensure that the variable is not quoted twice, once by qstr and once
|
||||
// by the magic_quotes_gpc.
|
||||
//
|
||||
//Eg. $s = $db->qstr(HTTP_GET_VARS['name'],get_magic_quotes_gpc());
|
||||
function qstr($s, $magic_quotes = false)
|
||||
{
|
||||
if (!$magic_quotes) {
|
||||
if (PHP_VERSION >= 5)
|
||||
return "'" . mysqli_real_escape_string($this->_connectionID, $s) . "'";
|
||||
|
||||
if ($this->replaceQuote[0] == '\\')
|
||||
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
|
||||
return "'".str_replace("'",$this->replaceQuote,$s)."'";
|
||||
}
|
||||
// undo magic quotes for "
|
||||
$s = str_replace('\\"','"',$s);
|
||||
return "'$s'";
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
|
||||
$result = @mysqli_insert_id($this->_connectionID);
|
||||
if ($result == -1){
|
||||
if ($this->debug) ADOConnection::outp("mysqli_insert_id() failed : " . $this->ErrorMsg());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Only works for INSERT, UPDATE and DELETE query's
|
||||
function _affectedrows()
|
||||
{
|
||||
// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
|
||||
$result = @mysqli_affected_rows($this->_connectionID);
|
||||
if ($result == -1) {
|
||||
if ($this->debug) ADOConnection::outp("mysqli_affected_rows() failed : " . $this->ErrorMsg());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
|
||||
// Reference on Last_Insert_ID on the recommended way to simulate sequences
|
||||
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
|
||||
var $_genSeqSQL = "create table %s (id int not null)";
|
||||
var $_genSeq2SQL = "insert into %s values (%s)";
|
||||
var $_dropSeqSQL = "drop table %s";
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
if (empty($this->_genSeqSQL)) return false;
|
||||
$u = strtoupper($seqname);
|
||||
|
||||
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
|
||||
if (!$ok) return false;
|
||||
return $this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
|
||||
}
|
||||
|
||||
function GenID($seqname='adodbseq',$startID=1)
|
||||
{
|
||||
// post-nuke sets hasGenID to false
|
||||
if (!$this->hasGenID) return false;
|
||||
|
||||
$getnext = sprintf($this->_genIDSQL,$seqname);
|
||||
$holdtransOK = $this->_transOK; // save the current status
|
||||
$rs = @$this->Execute($getnext);
|
||||
if (!$rs) {
|
||||
if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset
|
||||
$u = strtoupper($seqname);
|
||||
$this->Execute(sprintf($this->_genSeqSQL,$seqname));
|
||||
$this->Execute(sprintf($this->_genSeq2SQL,$seqname,$startID-1));
|
||||
$rs = $this->Execute($getnext);
|
||||
}
|
||||
$this->genID = mysqli_insert_id($this->_connectionID);
|
||||
|
||||
if ($rs) $rs->Close();
|
||||
|
||||
return $this->genID;
|
||||
}
|
||||
|
||||
function &MetaDatabases()
|
||||
{
|
||||
$query = "SHOW DATABASES";
|
||||
$ret =& $this->Execute($query);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function &MetaIndexes ($table, $primary = FALSE)
|
||||
{
|
||||
// save old fetch mode
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== FALSE) {
|
||||
$savem = $this->SetFetchMode(FALSE);
|
||||
}
|
||||
|
||||
// get index details
|
||||
$rs = $this->Execute(sprintf('SHOW INDEXES FROM %s',$table));
|
||||
|
||||
// restore fetchmode
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$indexes = array ();
|
||||
|
||||
// parse index data into array
|
||||
while ($row = $rs->FetchRow()) {
|
||||
if ($primary == FALSE AND $row[2] == 'PRIMARY') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($indexes[$row[2]])) {
|
||||
$indexes[$row[2]] = array(
|
||||
'unique' => ($row[1] == 0),
|
||||
'columns' => array()
|
||||
);
|
||||
}
|
||||
|
||||
$indexes[$row[2]]['columns'][$row[3] - 1] = $row[4];
|
||||
}
|
||||
|
||||
// sort columns by order in the index
|
||||
foreach ( array_keys ($indexes) as $index )
|
||||
{
|
||||
ksort ($indexes[$index]['columns']);
|
||||
}
|
||||
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = 'DATE_FORMAT('.$col.",'";
|
||||
$concat = false;
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= '%Y';
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "'),Quarter($col)";
|
||||
|
||||
if ($len > $i+1) $s .= ",DATE_FORMAT($col,'";
|
||||
else $s .= ",('";
|
||||
$concat = true;
|
||||
break;
|
||||
case 'M':
|
||||
$s .= '%b';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
$s .= '%m';
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= '%d';
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= '%H';
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
$s .= '%I';
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= '%i';
|
||||
break;
|
||||
|
||||
case 's':
|
||||
$s .= '%s';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= '%p';
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$s.="')";
|
||||
if ($concat) $s = "CONCAT($s)";
|
||||
return $s;
|
||||
}
|
||||
|
||||
// returns concatenated string
|
||||
// much easier to run "mysqld --ansi" or "mysqld --sql-mode=PIPES_AS_CONCAT" and use || operator
|
||||
function Concat()
|
||||
{
|
||||
$s = "";
|
||||
$arr = func_get_args();
|
||||
|
||||
// suggestion by andrew005@mnogo.ru
|
||||
$s = implode(',',$arr);
|
||||
if (strlen($s) > 0) return "CONCAT($s)";
|
||||
else return '';
|
||||
}
|
||||
|
||||
// dayFraction is a day in floating point
|
||||
function OffsetDate($dayFraction,$date=false)
|
||||
{
|
||||
if (!$date)
|
||||
$date = $this->sysDate;
|
||||
return "from_unixtime(unix_timestamp($date)+($dayFraction)*24*3600)";
|
||||
}
|
||||
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
if ($this->metaColumnsSQL) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$rs = false;
|
||||
switch($ADODB_FETCH_MODE)
|
||||
{
|
||||
case ADODB_FETCH_NUM:
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,
|
||||
$table));
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false) break;
|
||||
$retarr = array();
|
||||
while (!$rs->EOF){
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
// split type into type(length):
|
||||
if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array))
|
||||
{
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = $query_array[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
$fld->max_length = -1;
|
||||
}
|
||||
$fld->not_null = ($rs->fields[2] != 'YES');
|
||||
$fld->primary_key = ($rs->fields[3] == 'PRI');
|
||||
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
|
||||
$fld->binary = (strpos($fld->type,'blob') !== false);
|
||||
if (!$fld->binary)
|
||||
{
|
||||
$d = $rs->fields[4];
|
||||
$d = $rs->fields['Default'];
|
||||
if ($d != "" && $d != "NULL")
|
||||
{
|
||||
$fld->has_default = true;
|
||||
$fld->default_value = $d;
|
||||
}
|
||||
else
|
||||
{
|
||||
$fld->has_default = false;
|
||||
}
|
||||
}
|
||||
$retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
break;
|
||||
case ADODB_FETCH_ASSOC:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,
|
||||
$table));
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs === false) break;
|
||||
$retarr = array();
|
||||
while (!$rs->EOF){
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields['Field'];
|
||||
$fld->type = $rs->fields['Type'];
|
||||
|
||||
// split type into type(length):
|
||||
if (preg_match("/^(.+)\((\d+)\)$/", $fld->type, $query_array))
|
||||
{
|
||||
$fld->type = $query_array[1];
|
||||
$fld->max_length = $query_array[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
$fld->max_length = -1;
|
||||
}
|
||||
$fld->not_null = ($rs->fields['Null'] != 'YES');
|
||||
$fld->primary_key = ($rs->fields['Key'] == 'PRI');
|
||||
$fld->auto_increment = (strpos($rs->fields['Extra'], 'auto_increment') !== false);
|
||||
$fld->binary = (strpos($fld->type,'blob') !== false);
|
||||
if (!$fld->binary)
|
||||
{
|
||||
$d = $rs->fields['Default'];
|
||||
if ($d != "" && $d != "NULL")
|
||||
{
|
||||
$fld->has_default = true;
|
||||
$fld->default_value = $d;
|
||||
}
|
||||
else
|
||||
{
|
||||
$fld->has_default = false;
|
||||
}
|
||||
}
|
||||
$retarr[strtoupper($fld->name)] = $fld;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
if ($rs === false) return false;
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function SelectDB($dbName)
|
||||
{
|
||||
// $this->_connectionID = $this->mysqli_resolve_link($this->_connectionID);
|
||||
$this->databaseName = $dbName;
|
||||
if ($this->_connectionID) {
|
||||
$result = @mysqli_select_db($this->_connectionID, $dbName);
|
||||
if (!$result) {
|
||||
ADOConnection::outp("Select of database " . $dbName . " failed. " . $this->ErrorMsg());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// parameters use PostgreSQL convention, not MySQL
|
||||
function &SelectLimit($sql,
|
||||
$nrows = -1,
|
||||
$offset = -1,
|
||||
$inputarr = false,
|
||||
$arg3 = false,
|
||||
$secs = 0)
|
||||
{
|
||||
$offsetStr = ($offset >= 0) ? "$offset," : '';
|
||||
|
||||
if ($secs)
|
||||
$rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
|
||||
else
|
||||
$rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr , $arg3);
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
|
||||
function Prepare($sql)
|
||||
{
|
||||
return $sql;
|
||||
|
||||
$stmt = $this->_connectionID->prepare($sql);
|
||||
if (!$stmt) {
|
||||
echo $this->ErrorMsg();
|
||||
return $sql;
|
||||
}
|
||||
return array($sql,$stmt);
|
||||
}
|
||||
|
||||
|
||||
// returns queryID or false
|
||||
function _query($sql, $inputarr)
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
|
||||
if (is_array($sql)) {
|
||||
$stmt = $sql[1];
|
||||
$a = '';
|
||||
foreach($inputarr as $k => $v) {
|
||||
if (is_string($v)) $a .= 's';
|
||||
else if (is_integer($v)) $a .= 'i';
|
||||
else $a .= 'd';
|
||||
}
|
||||
|
||||
$fnarr =& array_merge( array($stmt,$a) , $inputarr);
|
||||
$ret = call_user_func_array('mysqli_stmt_bind_param',$fnarr);
|
||||
|
||||
$ret = mysqli_stmt_execute($stmt);
|
||||
return $ret;
|
||||
}
|
||||
if (!$mysql_res = mysqli_query($this->_connectionID, $sql, ($ADODB_COUNTRECS) ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT)) {
|
||||
if ($this->debug) ADOConnection::outp("Query: " . $sql . " failed. " . $this->ErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
return $mysql_res;
|
||||
}
|
||||
|
||||
/* Returns: the last error message from previous database operation */
|
||||
function ErrorMsg()
|
||||
{
|
||||
if (empty($this->_connectionID))
|
||||
$this->_errorMsg = @mysqli_error();
|
||||
else
|
||||
$this->_errorMsg = @mysqli_error($this->_connectionID);
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
/* Returns: the last error number from previous database operation */
|
||||
function ErrorNo()
|
||||
{
|
||||
if (empty($this->_connectionID))
|
||||
return @mysqli_errno();
|
||||
else
|
||||
return @mysqli_errno($this->_connectionID);
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
@mysqli_close($this->_connectionID);
|
||||
$this->_connectionID = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maximum size of C field
|
||||
*/
|
||||
function CharMax()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maximum size of X field
|
||||
*/
|
||||
function TextMax()
|
||||
{
|
||||
return 4294967295;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_mysqli extends ADORecordSet{
|
||||
|
||||
var $databaseType = "mysqli";
|
||||
var $canSeek = true;
|
||||
|
||||
function ADORecordSet_mysqli($queryID, $mode = false)
|
||||
{
|
||||
if ($mode === false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM:
|
||||
$this->fetchMode = MYSQLI_NUM;
|
||||
break;
|
||||
case ADODB_FETCH_ASSOC:
|
||||
$this->fetchMode = MYSQLI_ASSOC;
|
||||
break;
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:
|
||||
default:
|
||||
$this->fetchMode = MYSQLI_BOTH;
|
||||
break;
|
||||
}
|
||||
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
|
||||
$this->_numOfRows = $ADODB_COUNTRECS ? @mysqli_num_rows($this->_queryID) : -1;
|
||||
$this->_numOfFields = @mysqli_num_fields($this->_queryID);
|
||||
}
|
||||
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
$fieldnr = $fieldOffset;
|
||||
if ($fieldOffset != -1) {
|
||||
$fieldOffset = mysqli_field_seek($this->_queryID, $fieldnr);
|
||||
}
|
||||
$o = mysqli_fetch_field($this->_queryID);
|
||||
return $o;
|
||||
}
|
||||
|
||||
function &GetRowAssoc($upper = true)
|
||||
{
|
||||
if ($this->fetchMode == MYSQLI_ASSOC && !$upper)
|
||||
return $this->fields;
|
||||
$row =& ADORecordSet::GetRowAssoc($upper);
|
||||
return $row;
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode != MYSQLI_NUM)
|
||||
return @$this->fields[$colname];
|
||||
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i = 0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
if ($this->_numOfRows == 0)
|
||||
return false;
|
||||
|
||||
if ($row < 0)
|
||||
return false;
|
||||
|
||||
mysqli_data_seek($this->_queryID, $row);
|
||||
$this->EOF = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 10% speedup to move MoveNext to child class
|
||||
// This is the only implementation that works now (23-10-2003).
|
||||
// Other functions return no or the wrong results.
|
||||
function MoveNext()
|
||||
{
|
||||
if ($this->EOF) return false;
|
||||
$this->_currentRow++;
|
||||
$this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);
|
||||
|
||||
if (is_array($this->fields)) return true;
|
||||
$this->EOF = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = mysqli_fetch_array($this->_queryID,$this->fetchMode);
|
||||
return is_array($this->fields);
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
mysqli_free_result($this->_queryID);
|
||||
$this->_queryID = false;
|
||||
}
|
||||
|
||||
function MetaType($t, $len = -1, $fieldobj = false)
|
||||
{
|
||||
if (is_object($t))
|
||||
{
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
$len = -1; // mysql max_length is not accurate
|
||||
switch (strtoupper($t)) {
|
||||
case 'STRING':
|
||||
case 'CHAR':
|
||||
case 'VARCHAR':
|
||||
case 'TINYBLOB':
|
||||
case 'TINYTEXT':
|
||||
case 'ENUM':
|
||||
case 'SET':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
case 'LONGTEXT':
|
||||
case 'MEDIUMTEXT':
|
||||
return 'X';
|
||||
|
||||
// php_mysql extension always returns 'blob' even if 'text'
|
||||
// so we have to check whether binary...
|
||||
case 'IMAGE':
|
||||
case 'LONGBLOB':
|
||||
case 'BLOB':
|
||||
case 'MEDIUMBLOB':
|
||||
return !empty($fieldobj->binary) ? 'B' : 'X';
|
||||
case 'YEAR':
|
||||
case 'DATE':
|
||||
return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP': return 'T';
|
||||
|
||||
case 'INT':
|
||||
case 'INTEGER':
|
||||
case 'BIGINT':
|
||||
case 'TINYINT':
|
||||
case 'MEDIUMINT':
|
||||
case 'SMALLINT':
|
||||
|
||||
if (!empty($fieldobj->primary_key)) return 'R';
|
||||
else return 'I';
|
||||
// Added floating-point types
|
||||
// Maybe not necessery.
|
||||
case 'FLOAT':
|
||||
case 'DOUBLE':
|
||||
// case 'DOUBLE PRECISION':
|
||||
case 'DECIMAL':
|
||||
case 'DEC':
|
||||
case 'FIXED':
|
||||
default:
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
125
phpgwapi/inc/adodb/drivers/adodb-mysqlt.inc.php
Normal file
125
phpgwapi/inc/adodb/drivers/adodb-mysqlt.inc.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
|
||||
MySQL code that supports transactions. For MySQL 3.23 or later.
|
||||
Code from James Poon <jpoon88@yahoo.com>
|
||||
|
||||
Requires mysql client. Works on Windows and Unix.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include_once(ADODB_DIR."/drivers/adodb-mysql.inc.php");
|
||||
|
||||
|
||||
class ADODB_mysqlt extends ADODB_mysql {
|
||||
var $databaseType = 'mysqlt';
|
||||
var $ansiOuter = true; // for Version 3.23.17 or later
|
||||
var $hasTransactions = true;
|
||||
var $autoRollback = true; // apparently mysql does not autorollback properly
|
||||
|
||||
function ADODB_mysqlt()
|
||||
{
|
||||
global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 'ext_';
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->Execute('SET AUTOCOMMIT=0');
|
||||
$this->Execute('BEGIN');
|
||||
return true;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('COMMIT');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->Execute('ROLLBACK');
|
||||
$this->Execute('SET AUTOCOMMIT=1');
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ADORecordSet_mysqlt extends ADORecordSet_mysql{
|
||||
var $databaseType = "mysqlt";
|
||||
|
||||
function ADORecordSet_mysqlt($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$this->fetchMode = MYSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function MoveNext()
|
||||
{
|
||||
if (@$this->fields =& mysql_fetch_array($this->_queryID,$this->fetchMode)) {
|
||||
$this->_currentRow += 1;
|
||||
return true;
|
||||
}
|
||||
if (!$this->EOF) {
|
||||
$this->_currentRow += 1;
|
||||
$this->EOF = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
|
||||
|
||||
function ADORecordSet_ext_mysqli($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$this->fetchMode = MYSQL_BOTH; break;
|
||||
}
|
||||
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function MoveNext()
|
||||
{
|
||||
return adodb_movenext($this);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
168
phpgwapi/inc/adodb/drivers/adodb-netezza.inc.php
Normal file
168
phpgwapi/inc/adodb/drivers/adodb-netezza.inc.php
Normal file
@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my). All rights reserved.
|
||||
|
||||
First cut at the Netezza Driver by Josh Eldridge joshuae74#hotmail.com
|
||||
Based on the previous postgres drivers.
|
||||
http://www.netezza.com/
|
||||
Major Additions/Changes:
|
||||
MetaDatabasesSQL, MetaTablesSQL, MetaColumnsSQL
|
||||
Note: You have to have admin privileges to access the system tables
|
||||
Removed non-working keys code (Netezza has no concept of keys)
|
||||
Fixed the way data types and lengths are returned in MetaColumns()
|
||||
as well as added the default lengths for certain types
|
||||
Updated public variables for Netezza
|
||||
Still need to remove blob functions, as Netezza doesn't suppport blob
|
||||
*/
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include_once(ADODB_DIR.'/drivers/adodb-postgres64.inc.php');
|
||||
|
||||
class ADODB_netezza extends ADODB_postgres64 {
|
||||
var $databaseType = 'netezza';
|
||||
var $dataProvider = 'netezza';
|
||||
var $hasInsertID = false;
|
||||
var $_resultid = false;
|
||||
var $concat_operator='||';
|
||||
var $random = 'random';
|
||||
var $metaDatabasesSQL = "select objname from _v_object_data where objtype='database' order by 1";
|
||||
var $metaTablesSQL = "select objname from _v_object_data where objtype='table' order by 1";
|
||||
var $isoDates = true; // accepts dates in ISO format
|
||||
var $sysDate = "CURRENT_DATE";
|
||||
var $sysTimeStamp = "CURRENT_TIMESTAMP";
|
||||
var $blobEncodeType = 'C';
|
||||
var $metaColumnsSQL = "SELECT attname, atttype FROM _v_relation_column_def WHERE name = '%s' AND attnum > 0 ORDER BY attnum";
|
||||
var $metaColumnsSQL1 = "SELECT attname, atttype FROM _v_relation_column_def WHERE name = '%s' AND attnum > 0 ORDER BY attnum";
|
||||
// netezza doesn't have keys. it does have distributions, so maybe this is
|
||||
// something that can be pulled from the system tables
|
||||
var $metaKeySQL = "";
|
||||
var $hasAffectedRows = true;
|
||||
var $hasLimit = true;
|
||||
var $true = 't'; // string that represents TRUE for a database
|
||||
var $false = 'f'; // string that represents FALSE for a database
|
||||
var $fmtDate = "'Y-m-d'"; // used by DBDate() as the default date format used by the database
|
||||
var $fmtTimeStamp = "'Y-m-d G:i:s'"; // used by DBTimeStamp as the default timestamp fmt.
|
||||
var $ansiOuter = true;
|
||||
var $autoRollback = true; // apparently pgsql does not autorollback properly before 4.3.4
|
||||
// http://bugs.php.net/bug.php?id=25404
|
||||
|
||||
|
||||
function ADODB_netezza()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function &MetaColumns($table,$upper=true)
|
||||
{
|
||||
|
||||
// Changed this function to support Netezza which has no concept of keys
|
||||
// could posisbly work on other things from the system table later.
|
||||
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$table = strtolower($table);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
$rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rs === false) return false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) {
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
|
||||
// since we're returning type and length as one string,
|
||||
// split them out here.
|
||||
|
||||
if ($first = strstr($rs->fields[1], "(")) {
|
||||
$fld->max_length = trim($first, "()");
|
||||
} else {
|
||||
$fld->max_length = -1;
|
||||
}
|
||||
|
||||
if ($first = strpos($rs->fields[1], "(")) {
|
||||
$fld->type = substr($rs->fields[1], 0, $first);
|
||||
} else {
|
||||
$fld->type = $rs->fields[1];
|
||||
}
|
||||
|
||||
switch ($fld->type) {
|
||||
case "byteint":
|
||||
case "boolean":
|
||||
$fld->max_length = 1;
|
||||
break;
|
||||
case "smallint":
|
||||
$fld->max_length = 2;
|
||||
break;
|
||||
case "integer":
|
||||
case "numeric":
|
||||
case "date":
|
||||
$fld->max_length = 4;
|
||||
break;
|
||||
case "bigint":
|
||||
case "time":
|
||||
case "timestamp":
|
||||
$fld->max_length = 8;
|
||||
break;
|
||||
case "timetz":
|
||||
case "time with time zone":
|
||||
$fld->max_length = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[($upper) ? strtoupper($fld->name) : $fld->name] = $fld;
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_netezza extends ADORecordSet_postgres64
|
||||
{
|
||||
var $databaseType = "netezza";
|
||||
var $canSeek = true;
|
||||
|
||||
function ADORecordSet_netezza($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $this->fetchMode = PGSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$this->fetchMode = PGSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$this->fetchMode = PGSQL_BOTH; break;
|
||||
}
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
// _initrs modified to disable blob handling
|
||||
function _initrs()
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
$this->_numOfRows = ($ADODB_COUNTRECS)? @pg_numrows($this->_queryID):-1;
|
||||
$this->_numOfFields = @pg_numfields($this->_queryID);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
1290
phpgwapi/inc/adodb/drivers/adodb-oci8.inc.php
Normal file
1290
phpgwapi/inc/adodb/drivers/adodb-oci8.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
209
phpgwapi/inc/adodb/drivers/adodb-oci8po.inc.php
Normal file
209
phpgwapi/inc/adodb/drivers/adodb-oci8po.inc.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim. All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Portable version of oci8 driver, to make it more similar to other database drivers.
|
||||
The main differences are
|
||||
|
||||
1. that the OCI_ASSOC names are in lowercase instead of uppercase.
|
||||
2. bind variables are mapped using ? instead of :<bindvar>
|
||||
|
||||
Should some emulation of RecordCount() be implemented?
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include_once(ADODB_DIR.'/drivers/adodb-oci8.inc.php');
|
||||
|
||||
class ADODB_oci8po extends ADODB_oci8 {
|
||||
var $databaseType = 'oci8po';
|
||||
var $dataProvider = 'oci8';
|
||||
var $metaColumnsSQL = "select lower(cname),coltype,width, SCALE, PRECISION, NULLS, DEFAULTVAL from col where tname='%s' order by colno"; //changed by smondino@users.sourceforge. net
|
||||
var $metaTablesSQL = "select lower(table_name),table_type from cat where table_type in ('TABLE','VIEW')";
|
||||
|
||||
function ADODB_oci8po()
|
||||
{
|
||||
$this->_hasOCIFetchStatement = ADODB_PHPVER >= 0x4200;
|
||||
# oci8po does not support adodb extension: adodb_movenext()
|
||||
}
|
||||
|
||||
function Param($name)
|
||||
{
|
||||
return '?';
|
||||
}
|
||||
|
||||
function Prepare($sql,$cursor=false)
|
||||
{
|
||||
$sqlarr = explode('?',$sql);
|
||||
$sql = $sqlarr[0];
|
||||
for ($i = 1, $max = sizeof($sqlarr); $i < $max; $i++) {
|
||||
$sql .= ':'.($i-1) . $sqlarr[$i];
|
||||
}
|
||||
return ADODB_oci8::Prepare($sql,$cursor);
|
||||
}
|
||||
|
||||
// emulate handling of parameters ? ?, replacing with :bind0 :bind1
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
if (is_array($inputarr)) {
|
||||
$i = 0;
|
||||
if (is_array($sql)) {
|
||||
foreach($inputarr as $v) {
|
||||
$arr['bind'.$i++] = $v;
|
||||
}
|
||||
} else {
|
||||
$sqlarr = explode('?',$sql);
|
||||
$sql = $sqlarr[0];
|
||||
foreach($inputarr as $k => $v) {
|
||||
$sql .= ":$k" . $sqlarr[++$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return ADODB_oci8::_query($sql,$inputarr);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordset_oci8po extends ADORecordset_oci8 {
|
||||
|
||||
var $databaseType = 'oci8po';
|
||||
|
||||
function ADORecordset_oci8po($queryID,$mode=false)
|
||||
{
|
||||
$this->ADORecordset_oci8($queryID,$mode);
|
||||
}
|
||||
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode & OCI_ASSOC) return $this->fields[$colname];
|
||||
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
// lowercase field names...
|
||||
function &_FetchField($fieldOffset = -1)
|
||||
{
|
||||
$fld = new ADOFieldObject;
|
||||
$fieldOffset += 1;
|
||||
$fld->name = strtolower(OCIcolumnname($this->_queryID, $fieldOffset));
|
||||
$fld->type = OCIcolumntype($this->_queryID, $fieldOffset);
|
||||
$fld->max_length = OCIcolumnsize($this->_queryID, $fieldOffset);
|
||||
if ($fld->type == 'NUMBER') {
|
||||
//$p = OCIColumnPrecision($this->_queryID, $fieldOffset);
|
||||
$sc = OCIColumnScale($this->_queryID, $fieldOffset);
|
||||
if ($sc == 0) $fld->type = 'INT';
|
||||
}
|
||||
return $fld;
|
||||
}
|
||||
/*
|
||||
function MoveNext()
|
||||
{
|
||||
if (@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
|
||||
$this->_currentRow += 1;
|
||||
return true;
|
||||
}
|
||||
if (!$this->EOF) {
|
||||
$this->_currentRow += 1;
|
||||
$this->EOF = true;
|
||||
}
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// 10% speedup to move MoveNext to child class
|
||||
function MoveNext()
|
||||
{
|
||||
if(@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) {
|
||||
global $ADODB_ANSI_PADDING_OFF;
|
||||
$this->_currentRow++;
|
||||
|
||||
if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
|
||||
if (!empty($ADODB_ANSI_PADDING_OFF)) {
|
||||
foreach($this->fields as $k => $v) {
|
||||
if (is_string($v)) $this->fields[$k] = rtrim($v);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!$this->EOF) {
|
||||
$this->EOF = true;
|
||||
$this->_currentRow++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
|
||||
function &GetArrayLimit($nrows,$offset=-1)
|
||||
{
|
||||
if ($offset <= 0) return $this->GetArray($nrows);
|
||||
for ($i=1; $i < $offset; $i++)
|
||||
if (!@OCIFetch($this->_queryID)) return array();
|
||||
|
||||
if (!@OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode)) return array();
|
||||
if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
|
||||
$results = array();
|
||||
$cnt = 0;
|
||||
while (!$this->EOF && $nrows != $cnt) {
|
||||
$results[$cnt++] = $this->fields;
|
||||
$this->MoveNext();
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
// Create associative array
|
||||
function _updatefields()
|
||||
{
|
||||
if (ADODB_ASSOC_CASE == 2) return; // native
|
||||
|
||||
$arr = array();
|
||||
$lowercase = (ADODB_ASSOC_CASE == 0);
|
||||
|
||||
foreach($this->fields as $k => $v) {
|
||||
if (is_integer($k)) $arr[$k] = $v;
|
||||
else {
|
||||
if ($lowercase)
|
||||
$arr[strtolower($k)] = $v;
|
||||
else
|
||||
$arr[strtoupper($k)] = $v;
|
||||
}
|
||||
}
|
||||
$this->fields = $arr;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$ret = @OCIfetchinto($this->_queryID,$this->fields,$this->fetchMode);
|
||||
if ($ret) {
|
||||
global $ADODB_ANSI_PADDING_OFF;
|
||||
|
||||
if ($this->fetchMode & OCI_ASSOC) $this->_updatefields();
|
||||
if (!empty($ADODB_ANSI_PADDING_OFF)) {
|
||||
foreach($this->fields as $k => $v) {
|
||||
if (is_string($v)) $this->fields[$k] = rtrim($v);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
726
phpgwapi/inc/adodb/drivers/adodb-odbc.inc.php
Normal file
726
phpgwapi/inc/adodb/drivers/adodb-odbc.inc.php
Normal file
@ -0,0 +1,726 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Requires ODBC. Works on Windows and Unix.
|
||||
*/
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
define("_ADODB_ODBC_LAYER", 2 );
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
class ADODB_odbc extends ADOConnection {
|
||||
var $databaseType = "odbc";
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $dataProvider = "odbc";
|
||||
var $hasAffectedRows = true;
|
||||
var $binmode = ODBC_BINMODE_RETURN;
|
||||
var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive
|
||||
// breaking backward-compat
|
||||
//var $longreadlen = 8000; // default number of chars to return for a Blob/Long field
|
||||
var $_bindInputArray = false;
|
||||
var $curmode = SQL_CUR_USE_DRIVER; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
|
||||
var $_genSeqSQL = "create table %s (id integer)";
|
||||
var $_autocommit = true;
|
||||
var $_haserrorfunctions = true;
|
||||
var $_has_stupid_odbc_fetch_api_change = true;
|
||||
var $_lastAffectedRows = 0;
|
||||
var $uCaseTables = true; // for meta* functions, uppercase table names
|
||||
|
||||
function ADODB_odbc()
|
||||
{
|
||||
$this->_haserrorfunctions = ADODB_PHPVER >= 0x4050;
|
||||
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
|
||||
if (!empty($this->host) && ADODB_PHPVER >= 0x4300) {
|
||||
$dsn = strtoupper($this->host);
|
||||
$first = true;
|
||||
$found = false;
|
||||
|
||||
if (!function_exists('odbc_data_source')) return false;
|
||||
|
||||
while(true) {
|
||||
|
||||
$rez = @odbc_data_source($this->_connectionID,
|
||||
$first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT);
|
||||
$first = false;
|
||||
if (!is_array($rez)) break;
|
||||
if (strtoupper($rez['server']) == $dsn) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) return ADOConnection::ServerInfo();
|
||||
if (!isset($rez['version'])) $rez['version'] = '';
|
||||
return $rez;
|
||||
} else {
|
||||
return ADOConnection::ServerInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$start=1)
|
||||
{
|
||||
if (empty($this->_genSeqSQL)) return false;
|
||||
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
|
||||
if (!$ok) return false;
|
||||
$start -= 1;
|
||||
return $this->Execute("insert into $seqname values($start)");
|
||||
}
|
||||
|
||||
var $_dropSeqSQL = 'drop table %s';
|
||||
function DropSequence($seqname)
|
||||
{
|
||||
if (empty($this->_dropSeqSQL)) return false;
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
|
||||
}
|
||||
|
||||
/*
|
||||
This algorithm is not very efficient, but works even if table locking
|
||||
is not available.
|
||||
|
||||
Will return false if unable to generate an ID after $MAXLOOPS attempts.
|
||||
*/
|
||||
function GenID($seq='adodbseq',$start=1)
|
||||
{
|
||||
// if you have to modify the parameter below, your database is overloaded,
|
||||
// or you need to implement generation of id's yourself!
|
||||
$MAXLOOPS = 100;
|
||||
//$this->debug=1;
|
||||
while (--$MAXLOOPS>=0) {
|
||||
$num = $this->GetOne("select id from $seq");
|
||||
if ($num === false) {
|
||||
$this->Execute(sprintf($this->_genSeqSQL ,$seq));
|
||||
$start -= 1;
|
||||
$num = '0';
|
||||
$ok = $this->Execute("insert into $seq values($start)");
|
||||
if (!$ok) return false;
|
||||
}
|
||||
$this->Execute("update $seq set id=id+1 where id=$num");
|
||||
|
||||
if ($this->affected_rows() > 0) {
|
||||
$num += 1;
|
||||
$this->genID = $num;
|
||||
return $num;
|
||||
}
|
||||
}
|
||||
if ($fn = $this->raiseErrorFn) {
|
||||
$fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->_haserrorfunctions) {
|
||||
if ($this->_errorMsg !== false) return $this->_errorMsg;
|
||||
if (empty($this->_connectionID)) return @odbc_errormsg();
|
||||
return @odbc_errormsg($this->_connectionID);
|
||||
} else return ADOConnection::ErrorMsg();
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
|
||||
if ($this->_haserrorfunctions) {
|
||||
if ($this->_errorCode !== false) {
|
||||
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
|
||||
return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode;
|
||||
}
|
||||
|
||||
if (empty($this->_connectionID)) $e = @odbc_error();
|
||||
else $e = @odbc_error($this->_connectionID);
|
||||
|
||||
// bug in 4.0.6, error number can be corrupted string (should be 6 digits)
|
||||
// so we check and patch
|
||||
if (strlen($e)<=2) return 0;
|
||||
return $e;
|
||||
} else return ADOConnection::ErrorNo();
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
global $php_errormsg;
|
||||
|
||||
if (!function_exists('odbc_connect')) return null;
|
||||
|
||||
if ($this->debug && $argDatabasename && $this->databaseType != 'vfp') {
|
||||
ADOConnection::outp("For odbc Connect(), $argDatabasename is not used. Place dsn in 1st parameter.");
|
||||
}
|
||||
if (isset($php_errormsg)) $php_errormsg = '';
|
||||
if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword);
|
||||
else $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword,$this->curmode);
|
||||
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
|
||||
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
|
||||
|
||||
//if ($this->_connectionID) odbc_autocommit($this->_connectionID,true);
|
||||
return $this->_connectionID != false;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
global $php_errormsg;
|
||||
|
||||
if (!function_exists('odbc_connect')) return null;
|
||||
|
||||
if (isset($php_errormsg)) $php_errormsg = '';
|
||||
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
|
||||
if ($this->debug && $argDatabasename) {
|
||||
ADOConnection::outp("For odbc PConnect(), $argDatabasename is not used. Place dsn in 1st parameter.");
|
||||
}
|
||||
// print "dsn=$argDSN u=$argUsername p=$argPassword<br>"; flush();
|
||||
if ($this->curmode === false) $this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword);
|
||||
else $this->_connectionID = odbc_pconnect($argDSN,$argUsername,$argPassword,$this->curmode);
|
||||
|
||||
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
|
||||
if ($this->_connectionID && $this->autoRollback) @odbc_rollback($this->_connectionID);
|
||||
if (isset($this->connectStmt)) $this->Execute($this->connectStmt);
|
||||
|
||||
return $this->_connectionID != false;
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if (!$this->hasTransactions) return false;
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->_autocommit = false;
|
||||
return odbc_autocommit($this->_connectionID,false);
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->_autocommit = true;
|
||||
$ret = odbc_commit($this->_connectionID);
|
||||
odbc_autocommit($this->_connectionID,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->_autocommit = true;
|
||||
$ret = odbc_rollback($this->_connectionID);
|
||||
odbc_autocommit($this->_connectionID,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function MetaPrimaryKeys($table)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->uCaseTables) $table = strtoupper($table);
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$qid = @odbc_primarykeys($this->_connectionID,'',$schema,$table);
|
||||
|
||||
if (!$qid) {
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
return false;
|
||||
}
|
||||
$rs = new ADORecordSet_odbc($qid);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if (!$rs) return false;
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
|
||||
$arr =& $rs->GetArray();
|
||||
$rs->Close();
|
||||
//print_r($arr);
|
||||
$arr2 = array();
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if ($arr[$i][3]) $arr2[] = $arr[$i][3];
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function &MetaTables($ttype=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$qid = odbc_tables($this->_connectionID);
|
||||
|
||||
$rs = new ADORecordSet_odbc($qid);
|
||||
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
if (!$rs) return false;
|
||||
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
|
||||
$arr =& $rs->GetArray();
|
||||
//print_r($arr);
|
||||
|
||||
$rs->Close();
|
||||
$arr2 = array();
|
||||
|
||||
if ($ttype) {
|
||||
$isview = strncmp($ttype,'V',1) === 0;
|
||||
}
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if (!$arr[$i][2]) continue;
|
||||
$type = $arr[$i][3];
|
||||
if ($ttype) {
|
||||
if ($isview) {
|
||||
if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
|
||||
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
|
||||
} else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $arr[$i][2];
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
/*
|
||||
/ SQL data type codes /
|
||||
#define SQL_UNKNOWN_TYPE 0
|
||||
#define SQL_CHAR 1
|
||||
#define SQL_NUMERIC 2
|
||||
#define SQL_DECIMAL 3
|
||||
#define SQL_INTEGER 4
|
||||
#define SQL_SMALLINT 5
|
||||
#define SQL_FLOAT 6
|
||||
#define SQL_REAL 7
|
||||
#define SQL_DOUBLE 8
|
||||
#if (ODBCVER >= 0x0300)
|
||||
#define SQL_DATETIME 9
|
||||
#endif
|
||||
#define SQL_VARCHAR 12
|
||||
|
||||
/ One-parameter shortcuts for date/time data types /
|
||||
#if (ODBCVER >= 0x0300)
|
||||
#define SQL_TYPE_DATE 91
|
||||
#define SQL_TYPE_TIME 92
|
||||
#define SQL_TYPE_TIMESTAMP 93
|
||||
|
||||
#define SQL_UNICODE (-95)
|
||||
#define SQL_UNICODE_VARCHAR (-96)
|
||||
#define SQL_UNICODE_LONGVARCHAR (-97)
|
||||
*/
|
||||
function ODBCTypes($t)
|
||||
{
|
||||
switch ((integer)$t) {
|
||||
case 1:
|
||||
case 12:
|
||||
case 0:
|
||||
case -95:
|
||||
case -96:
|
||||
return 'C';
|
||||
case -97:
|
||||
case -1: //text
|
||||
return 'X';
|
||||
case -4: //image
|
||||
return 'B';
|
||||
|
||||
case 91:
|
||||
case 11:
|
||||
return 'D';
|
||||
|
||||
case 92:
|
||||
case 93:
|
||||
case 9: return 'T';
|
||||
case 4:
|
||||
case 5:
|
||||
case -6:
|
||||
return 'I';
|
||||
|
||||
case -11: // uniqidentifier
|
||||
return 'R';
|
||||
case -7: //bit
|
||||
return 'L';
|
||||
|
||||
default:
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
if ($this->uCaseTables) $table = strtoupper($table);
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
/*if (false) { // after testing, confirmed that the following does not work becoz of a bug
|
||||
$qid2 = odbc_tables($this->_connectionID);
|
||||
$rs = new ADORecordSet_odbc($qid2);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
if (!$rs) return false;
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
$rs->_fetch();
|
||||
|
||||
while (!$rs->EOF) {
|
||||
if ($table == strtoupper($rs->fields[2])) {
|
||||
$q = $rs->fields[0];
|
||||
$o = $rs->fields[1];
|
||||
break;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
$qid = odbc_columns($this->_connectionID,$q,$o,strtoupper($table),'%');
|
||||
} */
|
||||
|
||||
switch ($this->databaseType) {
|
||||
case 'access':
|
||||
case 'vfp':
|
||||
$qid = odbc_columns($this->_connectionID);#,'%','',strtoupper($table),'%');
|
||||
break;
|
||||
|
||||
|
||||
case 'db2':
|
||||
$colname = "%";
|
||||
$qid = odbc_columns($this->_connectionID, "", $schema, $table, $colname);
|
||||
break;
|
||||
|
||||
default:
|
||||
$qid = @odbc_columns($this->_connectionID,'%','%',strtoupper($table),'%');
|
||||
if (empty($qid)) $qid = odbc_columns($this->_connectionID);
|
||||
break;
|
||||
}
|
||||
if (empty($qid)) return false;
|
||||
|
||||
$rs = new ADORecordSet_odbc($qid);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if (!$rs) return false;
|
||||
|
||||
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
|
||||
$rs->_fetch();
|
||||
$retarr = array();
|
||||
|
||||
/*
|
||||
$rs->fields indices
|
||||
0 TABLE_QUALIFIER
|
||||
1 TABLE_SCHEM
|
||||
2 TABLE_NAME
|
||||
3 COLUMN_NAME
|
||||
4 DATA_TYPE
|
||||
5 TYPE_NAME
|
||||
6 PRECISION
|
||||
7 LENGTH
|
||||
8 SCALE
|
||||
9 RADIX
|
||||
10 NULLABLE
|
||||
11 REMARKS
|
||||
*/
|
||||
while (!$rs->EOF) {
|
||||
//adodb_pr($rs->fields);
|
||||
if (strtoupper($rs->fields[2]) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) {
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[3];
|
||||
$fld->type = $this->ODBCTypes($rs->fields[4]);
|
||||
|
||||
// ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp
|
||||
// access uses precision to store length for char/varchar
|
||||
if ($fld->type == 'C' or $fld->type == 'X') {
|
||||
if ($this->databaseType == 'access')
|
||||
$fld->max_length = $rs->fields[6];
|
||||
else if ($rs->fields[4] <= -95) // UNICODE
|
||||
$fld->max_length = $rs->fields[7]/2;
|
||||
else
|
||||
$fld->max_length = $rs->fields[7];
|
||||
} else
|
||||
$fld->max_length = $rs->fields[7];
|
||||
$fld->not_null = !empty($rs->fields[10]);
|
||||
$fld->scale = $rs->fields[8];
|
||||
$retarr[strtoupper($fld->name)] = $fld;
|
||||
} else if (sizeof($retarr)>0)
|
||||
break;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close(); //-- crashes 4.03pl1 -- why?
|
||||
|
||||
return $retarr;
|
||||
}
|
||||
|
||||
function Prepare($sql)
|
||||
{
|
||||
if (! $this->_bindInputArray) return $sql; // no binding
|
||||
$stmt = odbc_prepare($this->_connectionID,$sql);
|
||||
if (!$stmt) {
|
||||
// we don't know whether odbc driver is parsing prepared stmts, so just return sql
|
||||
return $sql;
|
||||
}
|
||||
return array($sql,$stmt,false);
|
||||
}
|
||||
|
||||
/* returns queryID or false */
|
||||
function _query($sql,$inputarr=false)
|
||||
{
|
||||
GLOBAL $php_errormsg;
|
||||
if (isset($php_errormsg)) $php_errormsg = '';
|
||||
$this->_error = '';
|
||||
|
||||
if ($inputarr) {
|
||||
if (is_array($sql)) {
|
||||
$stmtid = $sql[1];
|
||||
} else {
|
||||
$stmtid = odbc_prepare($this->_connectionID,$sql);
|
||||
|
||||
if ($stmtid == false) {
|
||||
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (! odbc_execute($stmtid,$inputarr)) {
|
||||
//@odbc_free_result($stmtid);
|
||||
if ($this->_haserrorfunctions) {
|
||||
$this->_errorMsg = odbc_errormsg();
|
||||
$this->_errorCode = odbc_error();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (is_array($sql)) {
|
||||
$stmtid = $sql[1];
|
||||
if (!odbc_execute($stmtid)) {
|
||||
//@odbc_free_result($stmtid);
|
||||
if ($this->_haserrorfunctions) {
|
||||
$this->_errorMsg = odbc_errormsg();
|
||||
$this->_errorCode = odbc_error();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
$stmtid = odbc_exec($this->_connectionID,$sql);
|
||||
|
||||
$this->_lastAffectedRows = 0;
|
||||
if ($stmtid) {
|
||||
if (@odbc_num_fields($stmtid) == 0) {
|
||||
$this->_lastAffectedRows = odbc_num_rows($stmtid);
|
||||
$stmtid = true;
|
||||
} else {
|
||||
$this->_lastAffectedRows = 0;
|
||||
odbc_binmode($stmtid,$this->binmode);
|
||||
odbc_longreadlen($stmtid,$this->maxblobsize);
|
||||
}
|
||||
|
||||
if ($this->_haserrorfunctions) {
|
||||
$this->_errorMsg = '';
|
||||
$this->_errorCode = 0;
|
||||
} else
|
||||
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
|
||||
} else {
|
||||
if ($this->_haserrorfunctions) {
|
||||
$this->_errorMsg = odbc_errormsg();
|
||||
$this->_errorCode = odbc_error();
|
||||
} else
|
||||
$this->_errorMsg = isset($php_errormsg) ? $php_errormsg : '';
|
||||
}
|
||||
return $stmtid;
|
||||
}
|
||||
|
||||
/*
|
||||
Insert a null into the blob field of the table first.
|
||||
Then use UpdateBlob to store the blob.
|
||||
|
||||
Usage:
|
||||
|
||||
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
|
||||
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
|
||||
*/
|
||||
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
|
||||
{
|
||||
return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
$ret = @odbc_close($this->_connectionID);
|
||||
$this->_connectionID = false;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
return $this->_lastAffectedRows;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_odbc extends ADORecordSet {
|
||||
|
||||
var $bind = false;
|
||||
var $databaseType = "odbc";
|
||||
var $dataProvider = "odbc";
|
||||
var $useFetchArray;
|
||||
var $_has_stupid_odbc_fetch_api_change;
|
||||
|
||||
function ADORecordSet_odbc($id,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
$this->fetchMode = $mode;
|
||||
|
||||
$this->_queryID = $id;
|
||||
|
||||
// the following is required for mysql odbc driver in 4.3.1 -- why?
|
||||
$this->EOF = false;
|
||||
$this->_currentRow = -1;
|
||||
//$this->ADORecordSet($id);
|
||||
}
|
||||
|
||||
|
||||
// returns the field object
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
|
||||
$off=$fieldOffset+1; // offsets begin at 1
|
||||
|
||||
$o= new ADOFieldObject();
|
||||
$o->name = @odbc_field_name($this->_queryID,$off);
|
||||
$o->type = @odbc_field_type($this->_queryID,$off);
|
||||
$o->max_length = @odbc_field_len($this->_queryID,$off);
|
||||
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
|
||||
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
|
||||
return $o;
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
$this->_numOfRows = ($ADODB_COUNTRECS) ? @odbc_num_rows($this->_queryID) : -1;
|
||||
$this->_numOfFields = @odbc_num_fields($this->_queryID);
|
||||
// some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0
|
||||
if ($this->_numOfRows == 0) $this->_numOfRows = -1;
|
||||
//$this->useFetchArray = $this->connection->useFetchArray;
|
||||
$this->_has_stupid_odbc_fetch_api_change = ADODB_PHPVER >= 0x4200;
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
|
||||
function &GetArrayLimit($nrows,$offset=-1)
|
||||
{
|
||||
if ($offset <= 0) {
|
||||
$rs =& $this->GetArray($nrows);
|
||||
return $rs;
|
||||
}
|
||||
$savem = $this->fetchMode;
|
||||
$this->fetchMode = ADODB_FETCH_NUM;
|
||||
$this->Move($offset);
|
||||
$this->fetchMode = $savem;
|
||||
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
}
|
||||
|
||||
$results = array();
|
||||
$cnt = 0;
|
||||
while (!$this->EOF && $nrows != $cnt) {
|
||||
$results[$cnt++] = $this->fields;
|
||||
$this->MoveNext();
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
function MoveNext()
|
||||
{
|
||||
if ($this->_numOfRows != 0 && !$this->EOF) {
|
||||
$this->_currentRow++;
|
||||
$row = 0;
|
||||
if ($this->_has_stupid_odbc_fetch_api_change)
|
||||
$rez = @odbc_fetch_into($this->_queryID,$this->fields);
|
||||
else
|
||||
$rez = @odbc_fetch_into($this->_queryID,$row,$this->fields);
|
||||
if ($rez) {
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->fields = false;
|
||||
$this->EOF = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$row = 0;
|
||||
if ($this->_has_stupid_odbc_fetch_api_change)
|
||||
$rez = @odbc_fetch_into($this->_queryID,$this->fields,$row);
|
||||
else
|
||||
$rez = @odbc_fetch_into($this->_queryID,$row,$this->fields);
|
||||
|
||||
if ($rez) {
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
|
||||
$this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
$this->fields = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
return @odbc_free_result($this->_queryID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
252
phpgwapi/inc/adodb/drivers/adodb-odbc_mssql.inc.php
Normal file
252
phpgwapi/inc/adodb/drivers/adodb-odbc_mssql.inc.php
Normal file
@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
MSSQL support via ODBC. Requires ODBC. Works on Windows and Unix.
|
||||
For Unix configuration, see http://phpbuilder.com/columns/alberto20000919.php3
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('_ADODB_ODBC_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
|
||||
}
|
||||
|
||||
|
||||
class ADODB_odbc_mssql extends ADODB_odbc {
|
||||
var $databaseType = 'odbc_mssql';
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d h:i:sA'";
|
||||
var $_bindInputArray = true;
|
||||
var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE'))";
|
||||
var $metaColumnsSQL = "select c.name,t.name,c.length from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
|
||||
var $hasTop = 'top'; // support mssql/interbase SELECT TOP 10 * FROM TABLE
|
||||
var $sysDate = 'GetDate()';
|
||||
var $sysTimeStamp = 'GetDate()';
|
||||
var $leftOuter = '*=';
|
||||
var $rightOuter = '=*';
|
||||
var $substr = 'substring';
|
||||
var $length = 'len';
|
||||
var $ansiOuter = true; // for mssql7 or later
|
||||
var $identitySQL = 'select @@IDENTITY'; // 'select SCOPE_IDENTITY'; # for mssql 2000
|
||||
var $hasInsertID = true;
|
||||
var $connectStmt = 'SET CONCAT_NULL_YIELDS_NULL OFF'; # When SET CONCAT_NULL_YIELDS_NULL is ON,
|
||||
# concatenating a null value with a string yields a NULL result
|
||||
|
||||
function ADODB_odbc_mssql()
|
||||
{
|
||||
$this->ADODB_odbc();
|
||||
$this->curmode = SQL_CUR_USE_ODBC;
|
||||
}
|
||||
|
||||
// crashes php...
|
||||
function ServerInfo()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$row = $this->GetRow("execute sp_server_info 2");
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if (!is_array($row)) return false;
|
||||
$arr['description'] = $row[2];
|
||||
$arr['version'] = ADOConnection::_findvers($arr['description']);
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " ISNULL($field, $ifNull) "; // if MS SQL Server
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
// SCOPE_IDENTITY()
|
||||
// Returns the last IDENTITY value inserted into an IDENTITY column in
|
||||
// the same scope. A scope is a module -- a stored procedure, trigger,
|
||||
// function, or batch. Thus, two statements are in the same scope if
|
||||
// they are in the same stored procedure, function, or batch.
|
||||
return $this->GetOne($this->identitySQL);
|
||||
}
|
||||
|
||||
|
||||
function MetaForeignKeys($table, $owner=false, $upper=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$table = $this->qstr(strtoupper($table));
|
||||
|
||||
$sql =
|
||||
"select object_name(constid) as constraint_name,
|
||||
col_name(fkeyid, fkey) as column_name,
|
||||
object_name(rkeyid) as referenced_table_name,
|
||||
col_name(rkeyid, rkey) as referenced_column_name
|
||||
from sysforeignkeys
|
||||
where upper(object_name(fkeyid)) = $table
|
||||
order by constraint_name, referenced_table_name, keyno";
|
||||
|
||||
$constraints =& $this->GetArray($sql);
|
||||
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
$arr = false;
|
||||
foreach($constraints as $constr) {
|
||||
//print_r($constr);
|
||||
$arr[$constr[0]][$constr[2]][] = $constr[1].'='.$constr[3];
|
||||
}
|
||||
if (!$arr) return false;
|
||||
|
||||
$arr2 = false;
|
||||
|
||||
foreach($arr as $k => $v) {
|
||||
foreach($v as $a => $b) {
|
||||
if ($upper) $a = strtoupper($a);
|
||||
$arr2[$a] = $b;
|
||||
}
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
function &MetaTables($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
if ($mask) {$this->debug=1;
|
||||
$save = $this->metaTablesSQL;
|
||||
$mask = $this->qstr($mask);
|
||||
$this->metaTablesSQL .= " AND name like $mask";
|
||||
}
|
||||
$ret =& ADOConnection::MetaTables($ttype,$showSchema);
|
||||
|
||||
if ($mask) {
|
||||
$this->metaTablesSQL = $save;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
return ADOConnection::MetaColumns($table);
|
||||
}
|
||||
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
if (is_string($sql)) $sql = str_replace('||','+',$sql);
|
||||
return ADODB_odbc::_query($sql,$inputarr);
|
||||
}
|
||||
|
||||
// "Stein-Aksel Basma" <basma@accelero.no>
|
||||
// tested with MSSQL 2000
|
||||
function &MetaPrimaryKeys($table)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = '';
|
||||
$this->_findschema($table,$schema);
|
||||
//if (!$schema) $schema = $this->database;
|
||||
if ($schema) $schema = "and k.table_catalog like '$schema%'";
|
||||
|
||||
$sql = "select distinct k.column_name,ordinal_position from information_schema.key_column_usage k,
|
||||
information_schema.table_constraints tc
|
||||
where tc.constraint_name = k.constraint_name and tc.constraint_type =
|
||||
'PRIMARY KEY' and k.table_name = '$table' $schema order by ordinal_position ";
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
$a = $this->GetCol($sql);
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if ($a && sizeof($a)>0) return $a;
|
||||
return false;
|
||||
}
|
||||
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
|
||||
{
|
||||
if ($nrows > 0 && $offset <= 0) {
|
||||
$sql = preg_replace(
|
||||
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
|
||||
$rs =& $this->Execute($sql,$inputarr);
|
||||
} else
|
||||
$rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = '';
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($s) $s .= '+';
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= "datename(yyyy,$col)";
|
||||
break;
|
||||
case 'M':
|
||||
$s .= "convert(char(3),$col,0)";
|
||||
break;
|
||||
case 'm':
|
||||
$s .= "replace(str(month($col),2),' ','0')";
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "datename(quarter,$col)";
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= "replace(str(day($col),2),' ','0')";
|
||||
break;
|
||||
case 'h':
|
||||
$s .= "substring(convert(char(14),$col,0),13,2)";
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
|
||||
break;
|
||||
case 's':
|
||||
$s .= "replace(str(datepart(ss,$col),2),' ','0')";
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= "substring(convert(char(19),$col,0),18,2)";
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $this->qstr($ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ADORecordSet_odbc_mssql extends ADORecordSet_odbc {
|
||||
|
||||
var $databaseType = 'odbc_mssql';
|
||||
|
||||
function ADORecordSet_odbc_mssql($id,$mode=false)
|
||||
{
|
||||
return $this->ADORecordSet_odbc($id,$mode);
|
||||
}
|
||||
}
|
||||
?>
|
117
phpgwapi/inc/adodb/drivers/adodb-odbc_oracle.inc.php
Normal file
117
phpgwapi/inc/adodb/drivers/adodb-odbc_oracle.inc.php
Normal file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Oracle support via ODBC. Requires ODBC. Works on Windows.
|
||||
*/
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('_ADODB_ODBC_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
|
||||
}
|
||||
|
||||
|
||||
class ADODB_odbc_oracle extends ADODB_odbc {
|
||||
var $databaseType = 'odbc_oracle';
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $concat_operator='||';
|
||||
var $fmtDate = "'Y-m-d 00:00:00'";
|
||||
var $fmtTimeStamp = "'Y-m-d h:i:sA'";
|
||||
var $metaTablesSQL = 'select table_name from cat';
|
||||
var $metaColumnsSQL = "select cname,coltype,width from col where tname='%s' order by colno";
|
||||
var $sysDate = "TRUNC(SYSDATE)";
|
||||
var $sysTimeStamp = 'SYSDATE';
|
||||
|
||||
//var $_bindInputArray = false;
|
||||
|
||||
function ADODB_odbc_oracle()
|
||||
{
|
||||
$this->ADODB_odbc();
|
||||
}
|
||||
|
||||
function &MetaTables()
|
||||
{
|
||||
if ($this->metaTablesSQL) {
|
||||
$rs = $this->Execute($this->metaTablesSQL);
|
||||
if ($rs === false) return false;
|
||||
$arr = $rs->GetArray();
|
||||
$arr2 = array();
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
$arr2[] = $arr[$i][0];
|
||||
}
|
||||
$rs->Close();
|
||||
return $arr2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function &MetaColumns($table)
|
||||
{
|
||||
if (!empty($this->metaColumnsSQL)) {
|
||||
|
||||
$rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));
|
||||
if ($rs === false) return false;
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) { //print_r($rs->fields);
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
$fld->max_length = $rs->fields[2];
|
||||
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[strtoupper($fld->name)] = $fld;
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
global $php_errormsg;
|
||||
|
||||
$php_errormsg = '';
|
||||
$this->_connectionID = odbc_connect($argDSN,$argUsername,$argPassword,SQL_CUR_USE_ODBC );
|
||||
$this->_errorMsg = $php_errormsg;
|
||||
|
||||
$this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
|
||||
//if ($this->_connectionID) odbc_autocommit($this->_connectionID,true);
|
||||
return $this->_connectionID != false;
|
||||
}
|
||||
// returns true or false
|
||||
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
global $php_errormsg;
|
||||
$php_errormsg = '';
|
||||
$this->_connectionID = odbc_pconnect($argDSN,$argUsername,$argPassword,SQL_CUR_USE_ODBC );
|
||||
$this->_errorMsg = $php_errormsg;
|
||||
|
||||
$this->Execute("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
|
||||
//if ($this->_connectionID) odbc_autocommit($this->_connectionID,true);
|
||||
return $this->_connectionID != false;
|
||||
}
|
||||
}
|
||||
|
||||
class ADORecordSet_odbc_oracle extends ADORecordSet_odbc {
|
||||
|
||||
var $databaseType = 'odbc_oracle';
|
||||
|
||||
function ADORecordSet_odbc_oracle($id,$mode=false)
|
||||
{
|
||||
return $this->ADORecordSet_odbc($id,$mode);
|
||||
}
|
||||
}
|
||||
?>
|
628
phpgwapi/inc/adodb/drivers/adodb-odbtp.inc.php
Normal file
628
phpgwapi/inc/adodb/drivers/adodb-odbtp.inc.php
Normal file
@ -0,0 +1,628 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
// Code contributed by "stefan bogdan" <sbogdan#rsb.ro>
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
define("_ADODB_ODBTP_LAYER", 2 );
|
||||
|
||||
class ADODB_odbtp extends ADOConnection{
|
||||
var $databaseType = "odbtp";
|
||||
var $dataProvider = "odbtp";
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $odbc_driver = 0;
|
||||
var $hasAffectedRows = true;
|
||||
var $hasInsertID = false;
|
||||
var $hasGenID = true;
|
||||
var $hasMoveFirst = true;
|
||||
|
||||
var $_genSeqSQL = "create table %s (seq_name char(30) not null unique , seq_value integer not null)";
|
||||
var $_dropSeqSQL = "delete from adodb_seq where seq_name = '%s'";
|
||||
var $_autocommit = true;
|
||||
var $_bindInputArray = false;
|
||||
var $_useUnicodeSQL = false;
|
||||
var $_canPrepareSP = false;
|
||||
|
||||
function ADODB_odbtp()
|
||||
{
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
return array('description' => @odbtp_get_attr( ODB_ATTR_DBMSNAME, $this->_connectionID),
|
||||
'version' => @odbtp_get_attr( ODB_ATTR_DBMSVER, $this->_connectionID));
|
||||
}
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if (empty($this->_connectionID)) return @odbtp_last_error();
|
||||
return @odbtp_last_error($this->_connectionID);
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if (empty($this->_connectionID)) return @odbtp_last_error_state();
|
||||
return @odbtp_last_error_state($this->_connectionID);
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
// SCOPE_IDENTITY()
|
||||
// Returns the last IDENTITY value inserted into an IDENTITY column in
|
||||
// the same scope. A scope is a module -- a stored procedure, trigger,
|
||||
// function, or batch. Thus, two statements are in the same scope if
|
||||
// they are in the same stored procedure, function, or batch.
|
||||
return $this->GetOne($this->identitySQL);
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
if ($this->_queryID) {
|
||||
return @odbtp_affected_rows ($this->_queryID);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$start=1)
|
||||
{
|
||||
//verify existence
|
||||
$num = $this->GetOne("select seq_value from adodb_seq");
|
||||
$seqtab='adodb_seq';
|
||||
if( $this->odbc_driver == ODB_DRIVER_FOXPRO ) {
|
||||
$path = @odbtp_get_attr( ODB_ATTR_DATABASENAME, $this->_connectionID );
|
||||
//if using vfp dbc file
|
||||
if( !strcasecmp(strrchr($path, '.'), '.dbc') )
|
||||
$path = substr($path,0,strrpos($path,'\/'));
|
||||
$seqtab = $path . '/' . $seqtab;
|
||||
}
|
||||
if($num == false) {
|
||||
if (empty($this->_genSeqSQL)) return false;
|
||||
$ok = $this->Execute(sprintf($this->_genSeqSQL ,$seqtab));
|
||||
}
|
||||
$num = $this->GetOne("select seq_value from adodb_seq where seq_name='$seqname'");
|
||||
if ($num) {
|
||||
return false;
|
||||
}
|
||||
$start -= 1;
|
||||
return $this->Execute("insert into adodb_seq values('$seqname',$start)");
|
||||
}
|
||||
|
||||
function DropSequence($seqname)
|
||||
{
|
||||
if (empty($this->_dropSeqSQL)) return false;
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
|
||||
}
|
||||
|
||||
function GenID($seq='adodbseq',$start=1)
|
||||
{
|
||||
$seqtab='adodb_seq';
|
||||
if( $this->odbc_driver == ODB_DRIVER_FOXPRO ) {
|
||||
$path = @odbtp_get_attr( ODB_ATTR_DATABASENAME, $this->_connectionID );
|
||||
//if using vfp dbc file
|
||||
if( !strcasecmp(strrchr($path, '.'), '.dbc') )
|
||||
$path = substr($path,0,strrpos($path,'\/'));
|
||||
$seqtab = $path . '/' . $seqtab;
|
||||
}
|
||||
$MAXLOOPS = 100;
|
||||
while (--$MAXLOOPS>=0) {
|
||||
$num = $this->GetOne("select seq_value from adodb_seq where seq_name='$seq'");
|
||||
if ($num === false) {
|
||||
//verify if abodb_seq table exist
|
||||
$ok = $this->GetOne("select seq_value from adodb_seq ");
|
||||
if(!$ok) {
|
||||
//creating the sequence table adodb_seq
|
||||
$this->Execute(sprintf($this->_genSeqSQL ,$seqtab));
|
||||
}
|
||||
$start -= 1;
|
||||
$num = '0';
|
||||
$ok = $this->Execute("insert into adodb_seq values('$seq',$start)");
|
||||
if (!$ok) return false;
|
||||
}
|
||||
$ok = $this->Execute("update adodb_seq set seq_value=seq_value+1 where seq_name='$seq'");
|
||||
if($ok) {
|
||||
$num += 1;
|
||||
$this->genID = $num;
|
||||
return $num;
|
||||
}
|
||||
}
|
||||
if ($fn = $this->raiseErrorFn) {
|
||||
$fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//example for $UserOrDSN
|
||||
//for visual fox : DRIVER={Microsoft Visual FoxPro Driver};SOURCETYPE=DBF;SOURCEDB=c:\YourDbfFileDir;EXCLUSIVE=NO;
|
||||
//for visual fox dbc: DRIVER={Microsoft Visual FoxPro Driver};SOURCETYPE=DBC;SOURCEDB=c:\YourDbcFileDir\mydb.dbc;EXCLUSIVE=NO;
|
||||
//for access : DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\path_to_access_db\base_test.mdb;UID=root;PWD=;
|
||||
//for mssql : DRIVER={SQL Server};SERVER=myserver;UID=myuid;PWD=mypwd;DATABASE=OdbtpTest;
|
||||
//if uid & pwd can be separate
|
||||
function _connect($HostOrInterface, $UserOrDSN='', $argPassword='', $argDatabase='')
|
||||
{
|
||||
$this->_connectionID = @odbtp_connect($HostOrInterface,$UserOrDSN,$argPassword,$argDatabase);
|
||||
if ($this->_connectionID === false)
|
||||
{
|
||||
$this->_errorMsg = $this->ErrorMsg() ;
|
||||
return false;
|
||||
}
|
||||
$this->odbc_driver = @odbtp_get_attr(ODB_ATTR_DRIVER, $this->_connectionID);
|
||||
|
||||
// Set driver specific attributes
|
||||
switch( $this->odbc_driver ) {
|
||||
case ODB_DRIVER_MSSQL:
|
||||
$this->fmtDate = "'Y-m-d'";
|
||||
$this->fmtTimeStamp = "'Y-m-d h:i:sA'";
|
||||
$this->sysDate = 'convert(datetime,convert(char,GetDate(),102),102)';
|
||||
$this->sysTimeStamp = 'GetDate()';
|
||||
$this->ansiOuter = true;
|
||||
$this->leftOuter = '*=';
|
||||
$this->rightOuter = '=*';
|
||||
$this->hasTop = 'top';
|
||||
$this->hasInsertID = true;
|
||||
$this->hasTransactions = true;
|
||||
$this->_bindInputArray = true;
|
||||
$this->_canSelectDb = true;
|
||||
$this->substr = "substring";
|
||||
$this->length = 'len';
|
||||
$this->identitySQL = 'select @@IDENTITY';
|
||||
$this->metaDatabasesSQL = "select name from master..sysdatabases where name <> 'master'";
|
||||
break;
|
||||
case ODB_DRIVER_JET:
|
||||
$this->fmtDate = "#Y-m-d#";
|
||||
$this->fmtTimeStamp = "#Y-m-d h:i:sA#";
|
||||
$this->sysDate = "FORMAT(NOW,'yyyy-mm-dd')";
|
||||
$this->sysTimeStamp = 'NOW';
|
||||
$this->hasTop = 'top';
|
||||
$this->hasTransactions = false;
|
||||
$this->_canPrepareSP = true; // For MS Access only.
|
||||
|
||||
// Can't rebind ODB_CHAR to ODB_WCHAR if row cache enabled.
|
||||
if ($this->_useUnicodeSQL)
|
||||
odbtp_use_row_cache($this->_connectionID, FALSE, 0);
|
||||
break;
|
||||
case ODB_DRIVER_FOXPRO:
|
||||
$this->fmtDate = "{^Y-m-d}";
|
||||
$this->fmtTimeStamp = "{^Y-m-d, h:i:sA}";
|
||||
$this->sysDate = 'date()';
|
||||
$this->sysTimeStamp = 'datetime()';
|
||||
$this->ansiOuter = true;
|
||||
$this->hasTop = 'top';
|
||||
$this->hasTransactions = false;
|
||||
$this->replaceQuote = "'+chr(39)+'";
|
||||
$this->true = '.T.';
|
||||
$this->false = '.F.';
|
||||
break;
|
||||
case ODB_DRIVER_ORACLE:
|
||||
$this->fmtDate = "'Y-m-d 00:00:00'";
|
||||
$this->fmtTimeStamp = "'Y-m-d h:i:sA'";
|
||||
$this->sysDate = 'TRUNC(SYSDATE)';
|
||||
$this->sysTimeStamp = 'SYSDATE';
|
||||
$this->hasTransactions = true;
|
||||
$this->_bindInputArray = true;
|
||||
$this->concat_operator = '||';
|
||||
break;
|
||||
case ODB_DRIVER_SYBASE:
|
||||
$this->fmtDate = "'Y-m-d'";
|
||||
$this->fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
$this->sysDate = 'GetDate()';
|
||||
$this->sysTimeStamp = 'GetDate()';
|
||||
$this->leftOuter = '*=';
|
||||
$this->rightOuter = '=*';
|
||||
$this->hasInsertID = true;
|
||||
$this->hasTransactions = true;
|
||||
$this->identitySQL = 'select @@IDENTITY';
|
||||
break;
|
||||
default:
|
||||
if( @odbtp_get_attr(ODB_ATTR_TXNCAPABLE, $this->_connectionID) )
|
||||
$this->hasTransactions = true;
|
||||
else
|
||||
$this->hasTransactions = false;
|
||||
}
|
||||
@odbtp_set_attr(ODB_ATTR_FULLCOLINFO, TRUE, $this->_connectionID );
|
||||
if ($this->_useUnicodeSQL )
|
||||
@odbtp_set_attr(ODB_ATTR_UNICODESQL, TRUE, $this->_connectionID);
|
||||
return true;
|
||||
}
|
||||
|
||||
function _pconnect($HostOrInterface, $UserOrDSN='', $argPassword='', $argDatabase='')
|
||||
{
|
||||
return $this->_connect($HostOrInterface, $UserOrDSN, $argPassword, $argDatabase);
|
||||
}
|
||||
|
||||
function SelectDB($dbName)
|
||||
{
|
||||
if (!@odbtp_select_db($dbName, $this->_connectionID)) {
|
||||
return false;
|
||||
}
|
||||
$this->databaseName = $dbName;
|
||||
return true;
|
||||
}
|
||||
|
||||
function &MetaTables($ttype='',$showSchema=false,$mask=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$arr =& $this->GetArray("||SQLTables||||$ttype");
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
$arr2 = array();
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if ($arr[$i][3] == 'SYSTEM TABLE' ) continue;
|
||||
if ($arr[$i][2])
|
||||
$arr2[] = $showSchema ? $arr[$i][1].'.'.$arr[$i][2] : $arr[$i][2];
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
function &MetaColumns($table,$upper=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
if ($upper) $table = strtoupper($table);
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$rs = $this->Execute( "||SQLColumns||$schema|$table" );
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
if (!$rs) return false;
|
||||
|
||||
while (!$rs->EOF) {
|
||||
//print_r($rs->fields);
|
||||
if (strtoupper($rs->fields[2]) == $table) {
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[3];
|
||||
$fld->type = $rs->fields[5];
|
||||
$fld->max_length = $rs->fields[6];
|
||||
$fld->not_null = !empty($rs->fields[9]);
|
||||
$fld->scale = $rs->fields[7];
|
||||
if (!is_null($rs->fields[12])) {
|
||||
$fld->has_default = true;
|
||||
$fld->default_value = $rs->fields[12];
|
||||
}
|
||||
$retarr[strtoupper($fld->name)] = $fld;
|
||||
} else if (sizeof($retarr)>0)
|
||||
break;
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
return $retarr;
|
||||
}
|
||||
|
||||
function &MetaPrimaryKeys($table, $owner='')
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$arr =& $this->GetArray("||SQLPrimaryKeys||$owner|$table");
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
//print_r($arr);
|
||||
$arr2 = array();
|
||||
for ($i=0; $i < sizeof($arr); $i++) {
|
||||
if ($arr[$i][3]) $arr2[] = $arr[$i][3];
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
function &MetaForeignKeys($table, $owner='', $upper=false)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$savem = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$constraints =& $this->GetArray("||SQLForeignKeys|||||$owner|$table");
|
||||
$ADODB_FETCH_MODE = $savem;
|
||||
|
||||
$arr = false;
|
||||
foreach($constraints as $constr) {
|
||||
//print_r($constr);
|
||||
$arr[$constr[11]][$constr[2]][] = $constr[7].'='.$constr[3];
|
||||
}
|
||||
if (!$arr) return false;
|
||||
|
||||
$arr2 = array();
|
||||
|
||||
foreach($arr as $k => $v) {
|
||||
foreach($v as $a => $b) {
|
||||
if ($upper) $a = strtoupper($a);
|
||||
$arr2[$a] = $b;
|
||||
}
|
||||
}
|
||||
return $arr2;
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if (!$this->hasTransactions) return false;
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->_autocommit = false;
|
||||
$rs = @odbtp_set_attr(ODB_ATTR_TRANSACTIONS,ODB_TXN_READUNCOMMITTED,$this->_connectionID);
|
||||
if(!$rs) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->_autocommit = true;
|
||||
if( ($ret = odbtp_commit($this->_connectionID)) )
|
||||
$ret = @odbtp_set_attr(ODB_ATTR_TRANSACTIONS, ODB_TXN_NONE, $this->_connectionID);//set transaction off
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->_autocommit = true;
|
||||
if( ($ret = odbtp_rollback($this->_connectionID)) )
|
||||
$ret = @odbtp_set_attr(ODB_ATTR_TRANSACTIONS, ODB_TXN_NONE, $this->_connectionID);//set transaction off
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
|
||||
{
|
||||
// TOP requires ORDER BY for Visual FoxPro
|
||||
if( $this->odbc_driver == ODB_DRIVER_FOXPRO ) {
|
||||
if (!preg_match('/ORDER[ \t\r\n]+BY/is',$sql)) $sql .= ' ORDER BY 1';
|
||||
}
|
||||
return ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
|
||||
}
|
||||
|
||||
function Prepare($sql)
|
||||
{
|
||||
if (! $this->_bindInputArray) return $sql; // no binding
|
||||
$stmt = odbtp_prepare($sql,$this->_connectionID);
|
||||
if (!$stmt) {
|
||||
// print "Prepare Error for ($sql) ".$this->ErrorMsg()."<br>";
|
||||
return $sql;
|
||||
}
|
||||
return array($sql,$stmt,false);
|
||||
}
|
||||
|
||||
function PrepareSP($sql)
|
||||
{
|
||||
if (!$this->_canPrepareSP) return $sql; // Can't prepare procedures
|
||||
|
||||
$stmt = odbtp_prepare_proc($sql,$this->_connectionID);
|
||||
if (!$stmt) return false;
|
||||
return array($sql,$stmt);
|
||||
}
|
||||
|
||||
/*
|
||||
Usage:
|
||||
$stmt = $db->PrepareSP('SP_RUNSOMETHING'); -- takes 2 params, @myid and @group
|
||||
|
||||
# note that the parameter does not have @ in front!
|
||||
$db->Parameter($stmt,$id,'myid');
|
||||
$db->Parameter($stmt,$group,'group',false,64);
|
||||
$db->Parameter($stmt,$group,'photo',false,100000,ODB_BINARY);
|
||||
$db->Execute($stmt);
|
||||
|
||||
@param $stmt Statement returned by Prepare() or PrepareSP().
|
||||
@param $var PHP variable to bind to. Can set to null (for isNull support).
|
||||
@param $name Name of stored procedure variable name to bind to.
|
||||
@param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in odbtp.
|
||||
@param [$maxLen] Holds an maximum length of the variable.
|
||||
@param [$type] The data type of $var. Legal values depend on driver.
|
||||
|
||||
See odbtp_attach_param documentation at http://odbtp.sourceforge.net.
|
||||
*/
|
||||
function Parameter(&$stmt, &$var, $name, $isOutput=false, $maxLen=0, $type=0)
|
||||
{
|
||||
if ( $this->odbc_driver == ODB_DRIVER_JET ) {
|
||||
$name = '['.$name.']';
|
||||
if( !$type && $this->_useUnicodeSQL
|
||||
&& @odbtp_param_bindtype($stmt[1], $name) == ODB_CHAR )
|
||||
{
|
||||
$type = ODB_WCHAR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$name = '@'.$name;
|
||||
}
|
||||
return odbtp_attach_param($stmt[1], $name, $var, $type, $maxLen);
|
||||
}
|
||||
|
||||
/*
|
||||
Insert a null into the blob field of the table first.
|
||||
Then use UpdateBlob to store the blob.
|
||||
|
||||
Usage:
|
||||
|
||||
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
|
||||
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
|
||||
*/
|
||||
|
||||
function UpdateBlob($table,$column,$val,$where,$blobtype='image')
|
||||
{
|
||||
$sql = "UPDATE $table SET $column = ? WHERE $where";
|
||||
if( !($stmt = odbtp_prepare($sql, $this->_connectionID)) )
|
||||
return false;
|
||||
if( !odbtp_input( $stmt, 1, ODB_BINARY, 1000000, $blobtype ) )
|
||||
return false;
|
||||
if( !odbtp_set( $stmt, 1, $val ) )
|
||||
return false;
|
||||
return odbtp_execute( $stmt ) != false;
|
||||
}
|
||||
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
switch( $this->odbc_driver ) {
|
||||
case ODB_DRIVER_MSSQL:
|
||||
return " ISNULL($field, $ifNull) ";
|
||||
case ODB_DRIVER_JET:
|
||||
return " IIF(IsNull($field), $ifNull, $field) ";
|
||||
}
|
||||
return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
|
||||
}
|
||||
|
||||
function _query($sql,$inputarr=false)
|
||||
{
|
||||
if ($inputarr) {
|
||||
if (is_array($sql)) {
|
||||
$stmtid = $sql[1];
|
||||
} else {
|
||||
$stmtid = odbtp_prepare($sql,$this->_connectionID);
|
||||
if ($stmtid == false) {
|
||||
$this->_errorMsg = $php_errormsg;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$num_params = odbtp_num_params( $stmtid );
|
||||
for( $param = 1; $param <= $num_params; $param++ ) {
|
||||
@odbtp_input( $stmtid, $param );
|
||||
@odbtp_set( $stmtid, $param, $inputarr[$param-1] );
|
||||
}
|
||||
if (! odbtp_execute($stmtid) ) {
|
||||
return false;
|
||||
}
|
||||
} else if (is_array($sql)) {
|
||||
$stmtid = $sql[1];
|
||||
if (!odbtp_execute($stmtid)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$stmtid = @odbtp_query($sql,$this->_connectionID);
|
||||
}
|
||||
$this->_lastAffectedRows = 0;
|
||||
if ($stmtid) {
|
||||
$this->_lastAffectedRows = @odbtp_affected_rows($stmtid);
|
||||
}
|
||||
return $stmtid;
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
$ret = @odbtp_close($this->_connectionID);
|
||||
$this->_connectionID = false;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
class ADORecordSet_odbtp extends ADORecordSet {
|
||||
|
||||
var $databaseType = 'odbtp';
|
||||
var $canSeek = true;
|
||||
|
||||
function ADORecordSet_odbtp($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
$this->fetchMode = $mode;
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
$this->_numOfFields = @odbtp_num_fields($this->_queryID);
|
||||
if (!($this->_numOfRows = @odbtp_num_rows($this->_queryID)))
|
||||
$this->_numOfRows = -1;
|
||||
}
|
||||
|
||||
function &FetchField($fieldOffset = 0)
|
||||
{
|
||||
$off=$fieldOffset; // offsets begin at 0
|
||||
$o= new ADOFieldObject();
|
||||
$o->name = @odbtp_field_name($this->_queryID,$off);
|
||||
$o->type = @odbtp_field_type($this->_queryID,$off);
|
||||
$o->max_length = @odbtp_field_length($this->_queryID,$off);
|
||||
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
|
||||
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
|
||||
return $o;
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return @odbtp_data_seek($this->_queryID, $row);
|
||||
}
|
||||
|
||||
function fields($colname)
|
||||
{
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
|
||||
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$name = @odbtp_field_name( $this->_queryID, $i );
|
||||
$this->bind[strtoupper($name)] = $i;
|
||||
}
|
||||
}
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
function _fetch_odbtp($type=0)
|
||||
{
|
||||
switch ($this->fetchMode) {
|
||||
case ADODB_FETCH_NUM:
|
||||
$this->fields = @odbtp_fetch_row($this->_queryID, $type);
|
||||
break;
|
||||
case ADODB_FETCH_ASSOC:
|
||||
$this->fields = @odbtp_fetch_assoc($this->_queryID, $type);
|
||||
break;
|
||||
default:
|
||||
$this->fields = @odbtp_fetch_array($this->_queryID, $type);
|
||||
}
|
||||
return is_array($this->fields);
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
return $this->_fetch_odbtp();
|
||||
}
|
||||
|
||||
function MoveFirst()
|
||||
{
|
||||
if (!$this->_fetch_odbtp(ODB_FETCH_FIRST)) return false;
|
||||
$this->EOF = false;
|
||||
$this->_currentRow = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
function MoveLast()
|
||||
{
|
||||
if (!$this->_fetch_odbtp(ODB_FETCH_LAST)) return false;
|
||||
$this->EOF = false;
|
||||
$this->_currentRow = $this->_numOfRows - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function NextRecordSet()
|
||||
{
|
||||
if (!@odbtp_next_result($this->_queryID)) return false;
|
||||
$this->_inited = false;
|
||||
$this->bind = false;
|
||||
$this->_currentRow = -1;
|
||||
$this->Init();
|
||||
return true;
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
return @odbtp_free_query($this->_queryID);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
62
phpgwapi/inc/adodb/drivers/adodb-odbtp_unicode.inc.php
Normal file
62
phpgwapi/inc/adodb/drivers/adodb-odbtp_unicode.inc.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
|
||||
// Code contributed by "Robert Twitty" <rtwitty#neutron.ushmm.org>
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
/*
|
||||
Because the ODBTP server sends and reads UNICODE text data using UTF-8
|
||||
encoding, the following HTML meta tag must be included within the HTML
|
||||
head section of every HTML form and script page:
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
|
||||
Also, all SQL query strings must be submitted as UTF-8 encoded text.
|
||||
*/
|
||||
|
||||
if (!defined('_ADODB_ODBTP_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-odbtp.inc.php");
|
||||
}
|
||||
|
||||
class ADODB_odbtp_unicode extends ADODB_odbtp {
|
||||
var $databaseType = "odbtp_unicode";
|
||||
var $_useUnicodeSQL = true;
|
||||
|
||||
function ADODB_odbtp_unicode()
|
||||
{
|
||||
$this->ADODB_odbtp();
|
||||
}
|
||||
}
|
||||
|
||||
class ADORecordSet_odbtp_unicode extends ADORecordSet_odbtp {
|
||||
var $databaseType = 'odbtp_unicode';
|
||||
|
||||
function ADORecordSet_odbtp_unicode($queryID,$mode=false)
|
||||
{
|
||||
$this->ADORecordSet_odbtp($queryID, $mode);
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
$this->_numOfFields = @odbtp_num_fields($this->_queryID);
|
||||
if (!($this->_numOfRows = @odbtp_num_rows($this->_queryID)))
|
||||
$this->_numOfRows = -1;
|
||||
|
||||
if ($this->connection->odbc_driver == ODB_DRIVER_JET) {
|
||||
for ($f = 0; $f < $this->_numOfFields; $f++) {
|
||||
if (odbtp_field_bindtype($this->_queryID, $f) == ODB_CHAR)
|
||||
odbtp_bind_field($this->_queryID, $f, ODB_WCHAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
320
phpgwapi/inc/adodb/drivers/adodb-oracle.inc.php
Normal file
320
phpgwapi/inc/adodb/drivers/adodb-oracle.inc.php
Normal file
@ -0,0 +1,320 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Oracle data driver. Requires Oracle client. Works on Windows and Unix and Oracle 7.
|
||||
|
||||
If you are using Oracle 8 or later, use the oci8 driver which is much better and more reliable.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB_oracle extends ADOConnection {
|
||||
var $databaseType = "oracle";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $concat_operator='||';
|
||||
var $_curs;
|
||||
var $_initdate = true; // init date to YYYY-MM-DD
|
||||
var $metaTablesSQL = 'select table_name from cat';
|
||||
var $metaColumnsSQL = "select cname,coltype,width from col where tname='%s' order by colno";
|
||||
var $sysDate = "TO_DATE(TO_CHAR(SYSDATE,'YYYY-MM-DD'),'YYYY-MM-DD')";
|
||||
var $sysTimeStamp = 'SYSDATE';
|
||||
var $connectSID = true;
|
||||
|
||||
function ADODB_oracle()
|
||||
{
|
||||
}
|
||||
|
||||
// format and return date string in database date format
|
||||
function DBDate($d)
|
||||
{
|
||||
if (is_string($d)) $d = ADORecordSet::UnixDate($d);
|
||||
return 'TO_DATE('.adodb_date($this->fmtDate,$d).",'YYYY-MM-DD')";
|
||||
}
|
||||
|
||||
// format and return date string in database timestamp format
|
||||
function DBTimeStamp($ts)
|
||||
{
|
||||
|
||||
if (is_string($ts)) $d = ADORecordSet::UnixTimeStamp($ts);
|
||||
return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'RRRR-MM-DD, HH:MI:SS AM')";
|
||||
}
|
||||
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
$this->autoCommit = false;
|
||||
ora_commitoff($this->_connectionID);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
$ret = ora_commit($this->_connectionID);
|
||||
ora_commiton($this->_connectionID);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
$ret = ora_rollback($this->_connectionID);
|
||||
ora_commiton($this->_connectionID);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/* there seems to be a bug in the oracle extension -- always returns ORA-00000 - no error */
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->_errorMsg !== false) return $this->_errorMsg;
|
||||
|
||||
if (is_resource($this->_curs)) $this->_errorMsg = @ora_error($this->_curs);
|
||||
if (empty($this->_errorMsg)) $this->_errorMsg = @ora_error($this->_connectionID);
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if ($this->_errorCode !== false) return $this->_errorCode;
|
||||
|
||||
if (is_resource($this->_curs)) $this->_errorCode = @ora_errorcode($this->_curs);
|
||||
if (empty($this->_errorCode)) $this->_errorCode = @ora_errorcode($this->_connectionID);
|
||||
return $this->_errorCode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename, $mode=0)
|
||||
{
|
||||
if (!function_exists('ora_plogon')) return null;
|
||||
|
||||
// <G. Giunta 2003/03/03/> Reset error messages before connecting
|
||||
$this->_errorMsg = false;
|
||||
$this->_errorCode = false;
|
||||
|
||||
// G. Giunta 2003/08/13 - This looks danegrously suspicious: why should we want to set
|
||||
// the oracle home to the host name of remote DB?
|
||||
// if ($argHostname) putenv("ORACLE_HOME=$argHostname");
|
||||
|
||||
if($argHostname) { // code copied from version submitted for oci8 by Jorma Tuomainen <jorma.tuomainen@ppoy.fi>
|
||||
if (empty($argDatabasename)) $argDatabasename = $argHostname;
|
||||
else {
|
||||
if(strpos($argHostname,":")) {
|
||||
$argHostinfo=explode(":",$argHostname);
|
||||
$argHostname=$argHostinfo[0];
|
||||
$argHostport=$argHostinfo[1];
|
||||
} else {
|
||||
$argHostport="1521";
|
||||
}
|
||||
|
||||
|
||||
if ($this->connectSID) {
|
||||
$argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
|
||||
.")(PORT=$argHostport))(CONNECT_DATA=(SID=$argDatabasename)))";
|
||||
} else
|
||||
$argDatabasename="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=".$argHostname
|
||||
.")(PORT=$argHostport))(CONNECT_DATA=(SERVICE_NAME=$argDatabasename)))";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($argDatabasename) $argUsername .= "@$argDatabasename";
|
||||
|
||||
//if ($argHostname) print "<p>Connect: 1st argument should be left blank for $this->databaseType</p>";
|
||||
if ($mode = 1)
|
||||
$this->_connectionID = ora_plogon($argUsername,$argPassword);
|
||||
else
|
||||
$this->_connectionID = ora_logon($argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
if ($this->autoCommit) ora_commiton($this->_connectionID);
|
||||
if ($this->_initdate) {
|
||||
$rs = $this->_query("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD'");
|
||||
if ($rs) ora_close($rs);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, 1);
|
||||
}
|
||||
|
||||
|
||||
// returns query ID if successful, otherwise false
|
||||
function _query($sql,$inputarr=false)
|
||||
{
|
||||
// <G. Giunta 2003/03/03/> Reset error messages before executing
|
||||
$this->_errorMsg = false;
|
||||
$this->_errorCode = false;
|
||||
|
||||
$curs = ora_open($this->_connectionID);
|
||||
|
||||
if ($curs === false) return false;
|
||||
$this->_curs = $curs;
|
||||
if (!ora_parse($curs,$sql)) return false;
|
||||
if (ora_exec($curs)) return $curs;
|
||||
// <G. Giunta 2004/03/03> before we close the cursor, we have to store the error message
|
||||
// that we can obtain ONLY from the cursor (and not from the connection)
|
||||
$this->_errorCode = @ora_errorcode($curs);
|
||||
$this->_errorMsg = @ora_error($curs);
|
||||
// </G. Giunta 2004/03/03>
|
||||
@ora_close($curs);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
return @ora_logoff($this->_connectionID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordset_oracle extends ADORecordSet {
|
||||
|
||||
var $databaseType = "oracle";
|
||||
var $bind = false;
|
||||
|
||||
function ADORecordset_oracle($queryID,$mode=false)
|
||||
{
|
||||
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
$this->fetchMode = $mode;
|
||||
|
||||
$this->_queryID = $queryID;
|
||||
|
||||
$this->_inited = true;
|
||||
$this->fields = array();
|
||||
if ($queryID) {
|
||||
$this->_currentRow = 0;
|
||||
$this->EOF = !$this->_fetch();
|
||||
@$this->_initrs();
|
||||
} else {
|
||||
$this->_numOfRows = 0;
|
||||
$this->_numOfFields = 0;
|
||||
$this->EOF = true;
|
||||
}
|
||||
|
||||
return $this->_queryID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Returns: an object containing field information.
|
||||
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
|
||||
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
|
||||
fetchField() is retrieved. */
|
||||
|
||||
function FetchField($fieldOffset = -1)
|
||||
{
|
||||
$fld = new ADOFieldObject;
|
||||
$fld->name = ora_columnname($this->_queryID, $fieldOffset);
|
||||
$fld->type = ora_columntype($this->_queryID, $fieldOffset);
|
||||
$fld->max_length = ora_columnsize($this->_queryID, $fieldOffset);
|
||||
return $fld;
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
$this->_numOfRows = -1;
|
||||
$this->_numOfFields = @ora_numcols($this->_queryID);
|
||||
}
|
||||
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function _fetch($ignore_fields=false) {
|
||||
// should remove call by reference, but ora_fetch_into requires it in 4.0.3pl1
|
||||
if ($this->fetchMode & ADODB_FETCH_ASSOC)
|
||||
return @ora_fetch_into($this->_queryID,&$this->fields,ORA_FETCHINTO_NULLS|ORA_FETCHINTO_ASSOC);
|
||||
else
|
||||
return @ora_fetch_into($this->_queryID,&$this->fields,ORA_FETCHINTO_NULLS);
|
||||
}
|
||||
|
||||
/* close() only needs to be called if you are worried about using too much memory while your script
|
||||
is running. All associated result memory for the specified result identifier will automatically be freed. */
|
||||
|
||||
function _close()
|
||||
{
|
||||
return @ora_close($this->_queryID);
|
||||
}
|
||||
|
||||
function MetaType($t,$len=-1)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
|
||||
switch (strtoupper($t)) {
|
||||
case 'VARCHAR':
|
||||
case 'VARCHAR2':
|
||||
case 'CHAR':
|
||||
case 'VARBINARY':
|
||||
case 'BINARY':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
case 'LONG':
|
||||
case 'LONG VARCHAR':
|
||||
case 'CLOB':
|
||||
return 'X';
|
||||
case 'LONG RAW':
|
||||
case 'LONG VARBINARY':
|
||||
case 'BLOB':
|
||||
return 'B';
|
||||
|
||||
case 'DATE': return 'D';
|
||||
|
||||
//case 'T': return 'T';
|
||||
|
||||
case 'BIT': return 'L';
|
||||
case 'INT':
|
||||
case 'SMALLINT':
|
||||
case 'INTEGER': return 'I';
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
319
phpgwapi/inc/adodb/drivers/adodb-pdo.inc.php
Normal file
319
phpgwapi/inc/adodb/drivers/adodb-pdo.inc.php
Normal file
@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Requires ODBC. Works on Windows and Unix.
|
||||
*/
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
class ADODB_pdo extends ADOConnection {
|
||||
var $databaseType = "pdo";
|
||||
var $dataProvider = "pdo";
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $hasAffectedRows = true;
|
||||
var $_bindInputArray = true;
|
||||
var $_genSeqSQL = "create table %s (id integer)";
|
||||
var $_autocommit = true;
|
||||
var $_haserrorfunctions = true;
|
||||
var $_lastAffectedRows = 0;
|
||||
|
||||
var $stmt = false;
|
||||
|
||||
function ADODB_pdo()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persist=false)
|
||||
{
|
||||
$this->_connectionID = new PDO($argDSN, $argUsername, $argPassword);
|
||||
if ($this->_connectionID) {
|
||||
switch(ADODB_ASSOC_CASE){
|
||||
case 0: $m = PDO_CASE_LOWER; break;
|
||||
case 1: $m = PDO_CASE_UPPER; break;
|
||||
default:
|
||||
case 2: $m = PDO_CASE_NATURAL; break;
|
||||
}
|
||||
|
||||
//$this->_connectionID->setAttribute(PDO_ATTR_ERRMODE,PDO_ERRMODE_SILENT );
|
||||
$this->_connectionID->setAttribute(PDO_ATTR_CASE,$m);
|
||||
|
||||
//$this->_connectionID->setAttribute(PDO_ATTR_AUTOCOMMIT,true);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
return $this->_connect($argDSN, $argUsername, $argPassword, $argDatabasename, true);
|
||||
}
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->_stmt) $arr = $this->_stmt->errorInfo();
|
||||
else $arr = $this->_connectionID->errorInfo();
|
||||
|
||||
if ($arr) {
|
||||
if ($arr[0]) return $arr[2];
|
||||
else return '';
|
||||
} else return '-1';
|
||||
}
|
||||
|
||||
function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
|
||||
{
|
||||
$obj = $stmt[1];
|
||||
if ($type) $obj->bindParam($name,$var,$type,$maxLen);
|
||||
else $obj->bindParam($name, $var);
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
|
||||
if ($this->_stmt) return $this->_stmt->errorCode();
|
||||
else return $this->_connectionID->errorInfo();
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if (!$this->hasTransactions) return false;
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
$this->_autocommit = false;
|
||||
$this->_connectionID->setAttribute(PDO_ATTR_AUTOCOMMIT,false);
|
||||
return $this->_connectionID->beginTransaction();
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->_autocommit = true;
|
||||
|
||||
$ret = $this->_connectionID->commit();
|
||||
$this->_connectionID->setAttribute(PDO_ATTR_AUTOCOMMIT,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if ($this->transCnt) $this->transCnt -= 1;
|
||||
$this->_autocommit = true;
|
||||
|
||||
$ret = $this->_connectionID->rollback();
|
||||
$this->_connectionID->setAttribute(PDO_ATTR_AUTOCOMMIT,true);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function Prepare($sql)
|
||||
{
|
||||
$this->_stmt = $this->_connectionID->prepare($sql);
|
||||
if ($this->_stmt) return array($sql,$this->_stmt);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function PrepareStmt($sql)
|
||||
{
|
||||
$stmt = $this->_connectionID->prepare($sql);
|
||||
if (!$stmt) return false;
|
||||
$obj = new ADOPDOStatement($stmt,$this);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/* returns queryID or false */
|
||||
function _query($sql,$inputarr=false)
|
||||
{
|
||||
if (is_array($sql)) {
|
||||
$stmt = $sql[1];
|
||||
} else {
|
||||
$stmt = $this->_connectionID->prepare($sql);
|
||||
}
|
||||
if ($stmt) {
|
||||
if ($inputarr) $stmt->execute($inputarr);
|
||||
else $stmt->execute();
|
||||
}
|
||||
$this->_stmt = $stmt;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
$this->_stmt = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
return ($this->_connectionID) ? $this->_connectionID->lastInsertId() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
class ADOPDOStatement {
|
||||
|
||||
var $databaseType = "pdo";
|
||||
var $dataProvider = "pdo";
|
||||
var $_stmt;
|
||||
var $_connectionID;
|
||||
|
||||
function ADOPDOStatement($stmt,$connection)
|
||||
{
|
||||
$this->_stmt = $stmt;
|
||||
$this->_connectionID = $connection;
|
||||
}
|
||||
|
||||
function Execute($inputArr=false)
|
||||
{
|
||||
$savestmt = $this->_connectionID->_stmt;
|
||||
$rs = $this->_connectionID->Execute(array(false,$this->_stmt),$inputArr);
|
||||
$this->_connectionID->_stmt = $savestmt;
|
||||
return $rs;
|
||||
}
|
||||
|
||||
function InParameter(&$var,$name,$maxLen=4000,$type=false)
|
||||
{
|
||||
|
||||
if ($type) $this->_stmt->bindParam($name,$var,$type,$maxLen);
|
||||
else $this->_stmt->bindParam($name, $var);
|
||||
}
|
||||
|
||||
function Affected_Rows()
|
||||
{
|
||||
return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
|
||||
}
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->_stmt) $arr = $this->_stmt->errorInfo();
|
||||
else $arr = $this->_connectionID->errorInfo();
|
||||
print_r($arr);
|
||||
if ($arr) {
|
||||
if ($arr[0]) return $arr[2];
|
||||
else return '';
|
||||
} else return '-1';
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
if ($this->_stmt) return $this->_stmt->errorCode();
|
||||
else return $this->_connectionID->errorInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_pdo extends ADORecordSet {
|
||||
|
||||
var $bind = false;
|
||||
var $databaseType = "pdo";
|
||||
var $dataProvider = "pdo";
|
||||
|
||||
function ADORecordSet_pdo($id,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch($mode) {
|
||||
default:
|
||||
case ADODB_FETCH_BOTH: $mode = PDO_FETCH_BOTH; break;
|
||||
case ADODB_FETCH_NUM: $mode = PDO_FETCH_NUM; break;
|
||||
case ADODB_FETCH_ASSOC: $mode = PDO_FETCH_ASSOC; break;
|
||||
}
|
||||
$this->fetchMode = $mode;
|
||||
|
||||
$this->_queryID = $id;
|
||||
$this->ADORecordSet($id);
|
||||
}
|
||||
|
||||
|
||||
// returns the field object
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
|
||||
$off=$fieldOffset+1; // offsets begin at 1
|
||||
|
||||
$o= new ADOFieldObject();
|
||||
$o->name = @odbc_field_name($this->_queryID,$off);
|
||||
$o->type = @odbc_field_type($this->_queryID,$off);
|
||||
$o->max_length = @odbc_field_len($this->_queryID,$off);
|
||||
if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
|
||||
else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
|
||||
return $o;
|
||||
}
|
||||
|
||||
function Init()
|
||||
{
|
||||
if ($this->_inited) return;
|
||||
$this->_inited = true;
|
||||
if ($this->_queryID) @$this->_initrs();
|
||||
else {
|
||||
$this->_numOfRows = 0;
|
||||
$this->_numOfFields = 0;
|
||||
}
|
||||
if ($this->_numOfRows != 0 && $this->_currentRow == -1) {
|
||||
$this->_currentRow = 0;
|
||||
if ($this->EOF = ($this->_fetch() === false)) {
|
||||
$this->_numOfRows = 0; // _numOfRows could be -1
|
||||
}
|
||||
$this->_numOfFields = sizeof($this->fields);
|
||||
} else {
|
||||
$this->EOF = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
|
||||
$this->_numOfRows = ($ADODB_COUNTRECS) ? @$this->_queryID->rowCount() : -1;
|
||||
if (!$this->_numOfRows) $this->_numOfRows = -1;
|
||||
$this->_numOfFields =0;
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
$this->fields = $this->_queryID->fetch($this->fetchMode);
|
||||
return !empty($this->fields);
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
$this->_queryID = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
14
phpgwapi/inc/adodb/drivers/adodb-postgres.inc.php
Normal file
14
phpgwapi/inc/adodb/drivers/adodb-postgres.inc.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4.
|
||||
|
||||
NOTE: Since 3.31, this file is no longer used, and the "postgres" driver is
|
||||
remapped to "postgres7". Maintaining multiple postgres drivers is no easy
|
||||
job, so hopefully this will ensure greater consistency and fewer bugs.
|
||||
*/
|
||||
|
||||
?>
|
958
phpgwapi/inc/adodb/drivers/adodb-postgres64.inc.php
Normal file
958
phpgwapi/inc/adodb/drivers/adodb-postgres64.inc.php
Normal file
@ -0,0 +1,958 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
|
||||
Original version derived from Alberto Cerezal (acerezalp@dbnet.es) - DBNet Informatica & Comunicaciones.
|
||||
08 Nov 2000 jlim - Minor corrections, removing mysql stuff
|
||||
09 Nov 2000 jlim - added insertid support suggested by "Christopher Kings-Lynne" <chriskl@familyhealth.com.au>
|
||||
jlim - changed concat operator to || and data types to MetaType to match documented pgsql types
|
||||
see http://www.postgresql.org/devel-corner/docs/postgres/datatype.htm
|
||||
22 Nov 2000 jlim - added changes to FetchField() and MetaTables() contributed by "raser" <raser@mail.zen.com.tw>
|
||||
27 Nov 2000 jlim - added changes to _connect/_pconnect from ideas by "Lennie" <leen@wirehub.nl>
|
||||
15 Dec 2000 jlim - added changes suggested by Additional code changes by "Eric G. Werk" egw@netguide.dk.
|
||||
31 Jan 2002 jlim - finally installed postgresql. testing
|
||||
01 Mar 2001 jlim - Freek Dijkstra changes, also support for text type
|
||||
|
||||
See http://www.varlena.com/varlena/GeneralBits/47.php
|
||||
|
||||
-- What indexes are on my table?
|
||||
select * from pg_indexes where tablename = 'tablename';
|
||||
|
||||
-- What triggers are on my table?
|
||||
select c.relname as "Table", t.tgname as "Trigger Name",
|
||||
t.tgconstrname as "Constraint Name", t.tgenabled as "Enabled",
|
||||
t.tgisconstraint as "Is Constraint", cc.relname as "Referenced Table",
|
||||
p.proname as "Function Name"
|
||||
from pg_trigger t, pg_class c, pg_class cc, pg_proc p
|
||||
where t.tgfoid = p.oid and t.tgrelid = c.oid
|
||||
and t.tgconstrrelid = cc.oid
|
||||
and c.relname = 'tablename';
|
||||
|
||||
-- What constraints are on my table?
|
||||
select r.relname as "Table", c.conname as "Constraint Name",
|
||||
contype as "Constraint Type", conkey as "Key Columns",
|
||||
confkey as "Foreign Columns", consrc as "Source"
|
||||
from pg_class r, pg_constraint c
|
||||
where r.oid = c.conrelid
|
||||
and relname = 'tablename';
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
function adodb_addslashes($s)
|
||||
{
|
||||
$len = strlen($s);
|
||||
if ($len == 0) return "''";
|
||||
if (strncmp($s,"'",1) === 0 && substr(s,$len-1) == "'") return $s; // already quoted
|
||||
|
||||
return "'".addslashes($s)."'";
|
||||
}
|
||||
|
||||
class ADODB_postgres64 extends ADOConnection{
|
||||
var $databaseType = 'postgres64';
|
||||
var $dataProvider = 'postgres';
|
||||
var $hasInsertID = true;
|
||||
var $_resultid = false;
|
||||
var $concat_operator='||';
|
||||
var $metaDatabasesSQL = "select datname from pg_database where datname not in ('template0','template1') order by 1";
|
||||
var $metaTablesSQL = "select tablename,'T' from pg_tables where tablename not like 'pg\_%'
|
||||
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
|
||||
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
|
||||
union
|
||||
select viewname,'V' from pg_views where viewname not like 'pg\_%'";
|
||||
//"select tablename from pg_tables where tablename not like 'pg_%' order by 1";
|
||||
var $isoDates = true; // accepts dates in ISO format
|
||||
var $sysDate = "CURRENT_DATE";
|
||||
var $sysTimeStamp = "CURRENT_TIMESTAMP";
|
||||
var $blobEncodeType = 'C';
|
||||
var $metaColumnsSQL = "SELECT a.attname,t.typname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,a.attnum
|
||||
FROM pg_class c, pg_attribute a,pg_type t
|
||||
WHERE relkind = 'r' AND (c.relname='%s' or c.relname = lower('%s')) and a.attname not like '....%%'
|
||||
AND a.attnum > 0 AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
|
||||
|
||||
var $metaColumnsSQL1 = "SELECT a.attname, t.typname, a.attlen, a.atttypmod, a.attnotnull, a.atthasdef, a.attnum
|
||||
FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
|
||||
WHERE relkind = 'r' AND (c.relname='%s' or c.relname = lower('%s'))
|
||||
and c.relnamespace=n.oid and n.nspname='%s'
|
||||
and a.attname not like '....%%' AND a.attnum > 0
|
||||
AND a.atttypid = t.oid AND a.attrelid = c.oid ORDER BY a.attnum";
|
||||
|
||||
// get primary key etc -- from Freek Dijkstra
|
||||
var $metaKeySQL = "SELECT ic.relname AS index_name, a.attname AS column_name,i.indisunique AS unique_key, i.indisprimary AS primary_key
|
||||
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a WHERE bc.oid = i.indrelid AND ic.oid = i.indexrelid AND (i.indkey[0] = a.attnum OR i.indkey[1] = a.attnum OR i.indkey[2] = a.attnum OR i.indkey[3] = a.attnum OR i.indkey[4] = a.attnum OR i.indkey[5] = a.attnum OR i.indkey[6] = a.attnum OR i.indkey[7] = a.attnum) AND a.attrelid = bc.oid AND bc.relname = '%s'";
|
||||
|
||||
var $hasAffectedRows = true;
|
||||
var $hasLimit = false; // set to true for pgsql 7 only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
|
||||
// below suggested by Freek Dijkstra
|
||||
var $true = 't'; // string that represents TRUE for a database
|
||||
var $false = 'f'; // string that represents FALSE for a database
|
||||
var $fmtDate = "'Y-m-d'"; // used by DBDate() as the default date format used by the database
|
||||
var $fmtTimeStamp = "'Y-m-d G:i:s'"; // used by DBTimeStamp as the default timestamp fmt.
|
||||
var $hasMoveFirst = true;
|
||||
var $hasGenID = true;
|
||||
var $_genIDSQL = "SELECT NEXTVAL('%s')";
|
||||
var $_genSeqSQL = "CREATE SEQUENCE %s START %s";
|
||||
var $_dropSeqSQL = "DROP SEQUENCE %s";
|
||||
var $metaDefaultsSQL = "SELECT d.adnum as num, d.adsrc as def from pg_attrdef d, pg_class c where d.adrelid=c.oid and c.relname='%s' order by d.adnum";
|
||||
var $random = 'random()'; /// random function
|
||||
var $autoRollback = true; // apparently pgsql does not autorollback properly before 4.3.4
|
||||
// http://bugs.php.net/bug.php?id=25404
|
||||
|
||||
var $_bindInputArray = false; // requires postgresql 7.3+ and ability to modify database
|
||||
|
||||
// The last (fmtTimeStamp is not entirely correct:
|
||||
// PostgreSQL also has support for time zones,
|
||||
// and writes these time in this format: "2001-03-01 18:59:26+02".
|
||||
// There is no code for the "+02" time zone information, so I just left that out.
|
||||
// I'm not familiar enough with both ADODB as well as Postgres
|
||||
// to know what the concequences are. The other values are correct (wheren't in 0.94)
|
||||
// -- Freek Dijkstra
|
||||
|
||||
function ADODB_postgres64()
|
||||
{
|
||||
// changes the metaColumnsSQL, adds columns: attnum[6]
|
||||
}
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
if (isset($this->version)) return $this->version;
|
||||
|
||||
$arr['description'] = $this->GetOne("select version()");
|
||||
$arr['version'] = ADOConnection::_findvers($arr['description']);
|
||||
$this->version = $arr;
|
||||
return $arr;
|
||||
}
|
||||
/*
|
||||
function IfNull( $field, $ifNull )
|
||||
{
|
||||
return " NULLIF($field, $ifNull) "; // if PGSQL
|
||||
}
|
||||
*/
|
||||
// get the last id - never tested
|
||||
function pg_insert_id($tablename,$fieldname)
|
||||
{
|
||||
$result=pg_exec($this->_connectionID, "SELECT last_value FROM ${tablename}_${fieldname}_seq");
|
||||
if ($result) {
|
||||
$arr = @pg_fetch_row($result,0);
|
||||
pg_freeresult($result);
|
||||
if (isset($arr[0])) return $arr[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Warning from http://www.php.net/manual/function.pg-getlastoid.php:
|
||||
Using a OID as a unique identifier is not generally wise.
|
||||
Unless you are very careful, you might end up with a tuple having
|
||||
a different OID if a database must be reloaded. */
|
||||
function _insertid()
|
||||
{
|
||||
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
|
||||
return pg_getlastoid($this->_resultid);
|
||||
}
|
||||
|
||||
// I get this error with PHP before 4.0.6 - jlim
|
||||
// Warning: This compilation does not support pg_cmdtuples() in d:/inetpub/wwwroot/php/adodb/adodb-postgres.inc.php on line 44
|
||||
function _affectedrows()
|
||||
{
|
||||
if (!is_resource($this->_resultid) || get_resource_type($this->_resultid) !== 'pgsql result') return false;
|
||||
return pg_cmdtuples($this->_resultid);
|
||||
}
|
||||
|
||||
|
||||
// returns true/false
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
return @pg_Exec($this->_connectionID, "begin");
|
||||
}
|
||||
|
||||
function RowLock($tables,$where)
|
||||
{
|
||||
if (!$this->transCnt) $this->BeginTrans();
|
||||
return $this->GetOne("select 1 as ignore from $tables where $where for update");
|
||||
}
|
||||
|
||||
// returns true/false.
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
|
||||
$this->transCnt -= 1;
|
||||
return @pg_Exec($this->_connectionID, "commit");
|
||||
}
|
||||
|
||||
// returns true/false
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt -= 1;
|
||||
return @pg_Exec($this->_connectionID, "rollback");
|
||||
}
|
||||
|
||||
function &MetaTables($ttype=false,$showSchema=false,$mask=false)
|
||||
{
|
||||
if ($mask) {
|
||||
$save = $this->metaTablesSQL;
|
||||
$mask = $this->qstr(strtolower($mask));
|
||||
$this->metaTablesSQL = "
|
||||
select tablename,'T' from pg_tables where tablename like $mask union
|
||||
select viewname,'V' from pg_views where viewname like $mask";
|
||||
}
|
||||
$ret =& ADOConnection::MetaTables($ttype,$showSchema);
|
||||
|
||||
if ($mask) {
|
||||
$this->metaTablesSQL = $save;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/*
|
||||
// if magic quotes disabled, use pg_escape_string()
|
||||
function qstr($s,$magic_quotes=false)
|
||||
{
|
||||
if (!$magic_quotes) {
|
||||
if (ADODB_PHPVER >= 0x4200) {
|
||||
return "'".pg_escape_string($s)."'";
|
||||
}
|
||||
if ($this->replaceQuote[0] == '\\'){
|
||||
$s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
|
||||
}
|
||||
return "'".str_replace("'",$this->replaceQuote,$s)."'";
|
||||
}
|
||||
|
||||
// undo magic quotes for "
|
||||
$s = str_replace('\\"','"',$s);
|
||||
return "'$s'";
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = 'TO_CHAR('.$col.",'";
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= 'YYYY';
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= 'Q';
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
$s .= 'Mon';
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
$s .= 'MM';
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= 'DD';
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s.= 'HH24';
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
$s .= 'HH';
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= 'MI';
|
||||
break;
|
||||
|
||||
case 's':
|
||||
$s .= 'SS';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= 'AM';
|
||||
break;
|
||||
|
||||
default:
|
||||
// handle escape characters...
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
if (strpos('-/.:;, ',$ch) !== false) $s .= $ch;
|
||||
else $s .= '"'.$ch.'"';
|
||||
|
||||
}
|
||||
}
|
||||
return $s. "')";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Load a Large Object from a file
|
||||
* - the procedure stores the object id in the table and imports the object using
|
||||
* postgres proprietary blob handling routines
|
||||
*
|
||||
* contributed by Mattia Rossi mattia@technologist.com
|
||||
* modified for safe mode by juraj chlebec
|
||||
*/
|
||||
function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB')
|
||||
{
|
||||
pg_exec ($this->_connectionID, "begin");
|
||||
|
||||
$fd = fopen($path,'r');
|
||||
$contents = fread($fd,filesize($path));
|
||||
fclose($fd);
|
||||
|
||||
$oid = pg_lo_create($this->_connectionID);
|
||||
$handle = pg_lo_open($this->_connectionID, $oid, 'w');
|
||||
pg_lo_write($handle, $contents);
|
||||
pg_lo_close($handle);
|
||||
|
||||
// $oid = pg_lo_import ($path);
|
||||
pg_exec($this->_connectionID, "commit");
|
||||
$rs = ADOConnection::UpdateBlob($table,$column,$oid,$where,$blobtype);
|
||||
$rez = !empty($rs);
|
||||
return $rez;
|
||||
}
|
||||
|
||||
/*
|
||||
* If an OID is detected, then we use pg_lo_* to open the oid file and read the
|
||||
* real blob from the db using the oid supplied as a parameter. If you are storing
|
||||
* blobs using bytea, we autodetect and process it so this function is not needed.
|
||||
*
|
||||
* contributed by Mattia Rossi mattia@technologist.com
|
||||
*
|
||||
* see http://www.postgresql.org/idocs/index.php?largeobjects.html
|
||||
*/
|
||||
function BlobDecode( $blob)
|
||||
{
|
||||
if (strlen($blob) > 24) return $blob;
|
||||
|
||||
@pg_exec($this->_connectionID,"begin");
|
||||
$fd = @pg_lo_open($this->_connectionID,$blob,"r");
|
||||
if ($fd === false) {
|
||||
@pg_exec($this->_connectionID,"commit");
|
||||
return $blob;
|
||||
}
|
||||
$realblob = @pg_loreadall($fd);
|
||||
@pg_loclose($fd);
|
||||
@pg_exec($this->_connectionID,"commit");
|
||||
return $realblob;
|
||||
}
|
||||
|
||||
/*
|
||||
See http://www.postgresql.org/idocs/index.php?datatype-binary.html
|
||||
|
||||
NOTE: SQL string literals (input strings) must be preceded with two backslashes
|
||||
due to the fact that they must pass through two parsers in the PostgreSQL
|
||||
backend.
|
||||
*/
|
||||
function BlobEncode($blob)
|
||||
{
|
||||
if (ADODB_PHPVER >= 0x4200) return pg_escape_bytea($blob);
|
||||
|
||||
/*92=backslash, 0=null, 39=single-quote*/
|
||||
$badch = array(chr(92),chr(0),chr(39)); # \ null '
|
||||
$fixch = array('\\\\134','\\\\000','\\\\047');
|
||||
return adodb_str_replace($badch,$fixch,$blob);
|
||||
|
||||
// note that there is a pg_escape_bytea function only for php 4.2.0 or later
|
||||
}
|
||||
|
||||
function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB')
|
||||
{
|
||||
// do not use bind params which uses qstr(), as blobencode() already quotes data
|
||||
return $this->Execute("UPDATE $table SET $column='".$this->BlobEncode($val)."'::bytea WHERE $where");
|
||||
}
|
||||
|
||||
function OffsetDate($dayFraction,$date=false)
|
||||
{
|
||||
if (!$date) $date = $this->sysDate;
|
||||
return "($date+interval'$dayFraction days')";
|
||||
}
|
||||
|
||||
|
||||
// for schema support, pass in the $table param "$schema.$tabname".
|
||||
// converts field names to lowercase, $upper is ignored
|
||||
function &MetaColumns($table,$normalize=true)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
if ($normalize) $table = strtolower($table);
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
|
||||
|
||||
if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
|
||||
else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rs === false) return false;
|
||||
|
||||
if (!empty($this->metaKeySQL)) {
|
||||
// If we want the primary keys, we have to issue a separate query
|
||||
// Of course, a modified version of the metaColumnsSQL query using a
|
||||
// LEFT JOIN would have been much more elegant, but postgres does
|
||||
// not support OUTER JOINS. So here is the clumsy way.
|
||||
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
|
||||
$rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
|
||||
// fetch all result in once for performance.
|
||||
$keys =& $rskey->GetArray();
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
$rskey->Close();
|
||||
unset($rskey);
|
||||
}
|
||||
|
||||
$rsdefa = array();
|
||||
if (!empty($this->metaDefaultsSQL)) {
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
$sql = sprintf($this->metaDefaultsSQL, ($table));
|
||||
$rsdef = $this->Execute($sql);
|
||||
if (isset($savem)) $this->SetFetchMode($savem);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if ($rsdef) {
|
||||
while (!$rsdef->EOF) {
|
||||
$num = $rsdef->fields['num'];
|
||||
$s = $rsdef->fields['def'];
|
||||
if (strpos($s,'::')===false && substr($s, 0, 1) == "'") { /* quoted strings hack... for now... fixme */
|
||||
$s = substr($s, 1);
|
||||
$s = substr($s, 0, strlen($s) - 1);
|
||||
}
|
||||
|
||||
$rsdefa[$num] = $s;
|
||||
$rsdef->MoveNext();
|
||||
}
|
||||
} else {
|
||||
ADOConnection::outp( "==> SQL => " . $sql);
|
||||
}
|
||||
unset($rsdef);
|
||||
}
|
||||
|
||||
$retarr = array();
|
||||
while (!$rs->EOF) {
|
||||
$fld = new ADOFieldObject();
|
||||
$fld->name = $rs->fields[0];
|
||||
$fld->type = $rs->fields[1];
|
||||
$fld->max_length = $rs->fields[2];
|
||||
if ($fld->max_length <= 0) $fld->max_length = $rs->fields[3]-4;
|
||||
if ($fld->max_length <= 0) $fld->max_length = -1;
|
||||
|
||||
// dannym
|
||||
// 5 hasdefault; 6 num-of-column
|
||||
$fld->has_default = ($rs->fields[5] == 't');
|
||||
if ($fld->has_default) {
|
||||
$fld->default_value = $rsdefa[$rs->fields[6]];
|
||||
}
|
||||
|
||||
//Freek
|
||||
if ($rs->fields[4] == $this->true) {
|
||||
$fld->not_null = true;
|
||||
}
|
||||
|
||||
// Freek
|
||||
if (is_array($keys)) {
|
||||
foreach($keys as $key) {
|
||||
if ($fld->name == $key['column_name'] AND $key['primary_key'] == $this->true)
|
||||
$fld->primary_key = true;
|
||||
if ($fld->name == $key['column_name'] AND $key['unique_key'] == $this->true)
|
||||
$fld->unique = true; // What name is more compatible?
|
||||
}
|
||||
}
|
||||
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;
|
||||
else $retarr[($normalize) ? strtoupper($fld->name) : $fld->name] = $fld;
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
return $retarr;
|
||||
|
||||
}
|
||||
|
||||
function &MetaIndexes ($table, $primary = FALSE)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$schema = false;
|
||||
$this->_findschema($table,$schema);
|
||||
|
||||
if ($schema) { // requires pgsql 7.3+ - pg_namespace used.
|
||||
$sql = '
|
||||
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
|
||||
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
|
||||
,pg_namespace n
|
||||
WHERE (c2.relname=\'%s\' or c2.relname=lower(\'%s\')) and c.relnamespace=c2.relnamespace and c.relnamespace=n.oid and n.nspname=\'%s\' AND i.indisprimary=false';
|
||||
} else {
|
||||
$sql = '
|
||||
SELECT c.relname as "Name", i.indisunique as "Unique", i.indkey as "Columns"
|
||||
FROM pg_catalog.pg_class c
|
||||
JOIN pg_catalog.pg_index i ON i.indexrelid=c.oid
|
||||
JOIN pg_catalog.pg_class c2 ON c2.oid=i.indrelid
|
||||
WHERE c2.relname=\'%s\' or c2.relname=lower(\'%s\')';
|
||||
}
|
||||
|
||||
if ($primary == FALSE) {
|
||||
$sql .= ' AND i.indisprimary=false;';
|
||||
}
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
if ($this->fetchMode !== FALSE) {
|
||||
$savem = $this->SetFetchMode(FALSE);
|
||||
}
|
||||
|
||||
$rs = $this->Execute(sprintf($sql,$table,$table,$schema));
|
||||
if (isset($savem)) {
|
||||
$this->SetFetchMode($savem);
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!is_object($rs)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$col_names = $this->MetaColumnNames($table,true);
|
||||
$indexes = array();
|
||||
while ($row = $rs->FetchRow()) {
|
||||
$columns = array();
|
||||
foreach (explode(' ', $row[2]) as $col) {
|
||||
$columns[] = $col_names[$col - 1];
|
||||
}
|
||||
|
||||
$indexes[$row[0]] = array(
|
||||
'unique' => ($row[1] == 't'),
|
||||
'columns' => $columns
|
||||
);
|
||||
}
|
||||
return $indexes;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
//
|
||||
// examples:
|
||||
// $db->Connect("host=host1 user=user1 password=secret port=4341");
|
||||
// $db->Connect('host1','user1','secret');
|
||||
function _connect($str,$user='',$pwd='',$db='',$ctype=0)
|
||||
{
|
||||
|
||||
if (!function_exists('pg_pconnect')) return null;
|
||||
|
||||
$this->_errorMsg = false;
|
||||
|
||||
if ($user || $pwd || $db) {
|
||||
$user = adodb_addslashes($user);
|
||||
$pwd = adodb_addslashes($pwd);
|
||||
if (strlen($db) == 0) $db = 'template1';
|
||||
$db = adodb_addslashes($db);
|
||||
if ($str) {
|
||||
$host = split(":", $str);
|
||||
if ($host[0]) $str = "host=".adodb_addslashes($host[0]);
|
||||
else $str = 'host=localhost';
|
||||
if (isset($host[1])) $str .= " port=$host[1]";
|
||||
}
|
||||
if ($user) $str .= " user=".$user;
|
||||
if ($pwd) $str .= " password=".$pwd;
|
||||
if ($db) $str .= " dbname=".$db;
|
||||
}
|
||||
|
||||
//if ($user) $linea = "user=$user host=$linea password=$pwd dbname=$db port=5432";
|
||||
|
||||
if ($ctype === 1) { // persistent
|
||||
$this->_connectionID = pg_pconnect($str);
|
||||
} else {
|
||||
if ($ctype === -1) { // nconnect, we trick pgsql ext by changing the connection str
|
||||
static $ncnt;
|
||||
|
||||
if (empty($ncnt)) $ncnt = 1;
|
||||
else $ncnt += 1;
|
||||
|
||||
$str .= str_repeat(' ',$ncnt);
|
||||
}
|
||||
$this->_connectionID = pg_connect($str);
|
||||
}
|
||||
if ($this->_connectionID === false) return false;
|
||||
$this->Execute("set datestyle='ISO'");
|
||||
return true;
|
||||
}
|
||||
|
||||
function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName)
|
||||
{
|
||||
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName,-1);
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
//
|
||||
// examples:
|
||||
// $db->PConnect("host=host1 user=user1 password=secret port=4341");
|
||||
// $db->PConnect('host1','user1','secret');
|
||||
function _pconnect($str,$user='',$pwd='',$db='')
|
||||
{
|
||||
return $this->_connect($str,$user,$pwd,$db,1);
|
||||
}
|
||||
|
||||
|
||||
// returns queryID or false
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
|
||||
if ($inputarr) {
|
||||
/*
|
||||
It appears that PREPARE/EXECUTE is slower for many queries.
|
||||
|
||||
For query executed 1000 times:
|
||||
"select id,firstname,lastname from adoxyz
|
||||
where firstname not like ? and lastname not like ? and id = ?"
|
||||
|
||||
with plan = 1.51861286163 secs
|
||||
no plan = 1.26903700829 secs
|
||||
|
||||
|
||||
|
||||
*/
|
||||
$plan = 'P'.md5($sql);
|
||||
|
||||
$execp = '';
|
||||
foreach($inputarr as $v) {
|
||||
if ($execp) $execp .= ',';
|
||||
if (is_string($v)) {
|
||||
if (strncmp($v,"'",1) !== 0) $execp .= $this->qstr($v);
|
||||
} else {
|
||||
$execp .= $v;
|
||||
}
|
||||
}
|
||||
|
||||
if ($execp) $exsql = "EXECUTE $plan ($execp)";
|
||||
else $exsql = "EXECUTE $plan";
|
||||
|
||||
$rez = @pg_exec($this->_connectionID,$exsql);
|
||||
if (!$rez) {
|
||||
# Perhaps plan does not exist? Prepare/compile plan.
|
||||
$params = '';
|
||||
foreach($inputarr as $v) {
|
||||
if ($params) $params .= ',';
|
||||
if (is_string($v)) {
|
||||
$params .= 'VARCHAR';
|
||||
} else if (is_integer($v)) {
|
||||
$params .= 'INTEGER';
|
||||
} else {
|
||||
$params .= "REAL";
|
||||
}
|
||||
}
|
||||
$sqlarr = explode('?',$sql);
|
||||
//print_r($sqlarr);
|
||||
$sql = '';
|
||||
$i = 1;
|
||||
foreach($sqlarr as $v) {
|
||||
$sql .= $v.' $'.$i;
|
||||
$i++;
|
||||
}
|
||||
$s = "PREPARE $plan ($params) AS ".substr($sql,0,strlen($sql)-2);
|
||||
//adodb_pr($s);
|
||||
pg_exec($this->_connectionID,$s);
|
||||
echo $this->ErrorMsg();
|
||||
}
|
||||
|
||||
$rez = pg_exec($this->_connectionID,$exsql);
|
||||
} else {
|
||||
$this->_errorMsg = false;
|
||||
//adodb_backtrace();
|
||||
$rez = pg_exec($this->_connectionID,$sql);
|
||||
}
|
||||
// check if no data returned, then no need to create real recordset
|
||||
if ($rez && pg_numfields($rez) <= 0) {
|
||||
if (is_resource($this->_resultid) && get_resource_type($this->_resultid) === 'pgsql result') {
|
||||
pg_freeresult($this->_resultid);
|
||||
}
|
||||
$this->_resultid = $rez;
|
||||
return true;
|
||||
}
|
||||
|
||||
return $rez;
|
||||
}
|
||||
|
||||
|
||||
/* Returns: the last error message from previous database operation */
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->_errorMsg !== false) return $this->_errorMsg;
|
||||
if (ADODB_PHPVER >= 0x4300) {
|
||||
if (!empty($this->_resultid)) {
|
||||
$this->_errorMsg = @pg_result_error($this->_resultid);
|
||||
if ($this->_errorMsg) return $this->_errorMsg;
|
||||
}
|
||||
|
||||
if (!empty($this->_connectionID)) {
|
||||
$this->_errorMsg = @pg_last_error($this->_connectionID);
|
||||
} else $this->_errorMsg = @pg_last_error();
|
||||
} else {
|
||||
if (empty($this->_connectionID)) $this->_errorMsg = @pg_errormessage();
|
||||
else $this->_errorMsg = @pg_errormessage($this->_connectionID);
|
||||
}
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
$e = $this->ErrorMsg();
|
||||
if (strlen($e)) {
|
||||
return ADOConnection::MetaError($e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
if ($this->transCnt) $this->RollbackTrans();
|
||||
if ($this->_resultid) {
|
||||
@pg_freeresult($this->_resultid);
|
||||
$this->_resultid = false;
|
||||
}
|
||||
@pg_close($this->_connectionID);
|
||||
$this->_connectionID = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Maximum size of C field
|
||||
*/
|
||||
function CharMax()
|
||||
{
|
||||
return 1000000000; // should be 1 Gb?
|
||||
}
|
||||
|
||||
/*
|
||||
* Maximum size of X field
|
||||
*/
|
||||
function TextMax()
|
||||
{
|
||||
return 1000000000; // should be 1 Gb?
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_postgres64 extends ADORecordSet{
|
||||
var $_blobArr;
|
||||
var $databaseType = "postgres64";
|
||||
var $canSeek = true;
|
||||
function ADORecordSet_postgres64($queryID,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch ($mode)
|
||||
{
|
||||
case ADODB_FETCH_NUM: $this->fetchMode = PGSQL_NUM; break;
|
||||
case ADODB_FETCH_ASSOC:$this->fetchMode = PGSQL_ASSOC; break;
|
||||
default:
|
||||
case ADODB_FETCH_DEFAULT:
|
||||
case ADODB_FETCH_BOTH:$this->fetchMode = PGSQL_BOTH; break;
|
||||
}
|
||||
$this->ADORecordSet($queryID);
|
||||
}
|
||||
|
||||
function &GetRowAssoc($upper=true)
|
||||
{
|
||||
if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
|
||||
$row =& ADORecordSet::GetRowAssoc($upper);
|
||||
return $row;
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
$qid = $this->_queryID;
|
||||
$this->_numOfRows = ($ADODB_COUNTRECS)? @pg_numrows($qid):-1;
|
||||
$this->_numOfFields = @pg_numfields($qid);
|
||||
|
||||
// cache types for blob decode check
|
||||
for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) {
|
||||
if (pg_fieldtype($qid,$i) == 'bytea') {
|
||||
$this->_blobArr[$i] = pg_fieldname($qid,$i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Use associative array to get fields array */
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode != PGSQL_NUM) return @$this->fields[$colname];
|
||||
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
function &FetchField($off = 0)
|
||||
{
|
||||
// offsets begin at 0
|
||||
|
||||
$o= new ADOFieldObject();
|
||||
$o->name = @pg_fieldname($this->_queryID,$off);
|
||||
$o->type = @pg_fieldtype($this->_queryID,$off);
|
||||
$o->max_length = @pg_fieldsize($this->_queryID,$off);
|
||||
return $o;
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return @pg_fetch_row($this->_queryID,$row);
|
||||
}
|
||||
|
||||
function _decode($blob)
|
||||
{
|
||||
eval('$realblob="'.adodb_str_replace(array('"','$'),array('\"','\$'),$blob).'";');
|
||||
return $realblob;
|
||||
}
|
||||
|
||||
function _fixblobs()
|
||||
{
|
||||
if ($this->fetchMode == PGSQL_NUM || $this->fetchMode == PGSQL_BOTH) {
|
||||
foreach($this->_blobArr as $k => $v) {
|
||||
$this->fields[$k] = ADORecordSet_postgres64::_decode($this->fields[$k]);
|
||||
}
|
||||
}
|
||||
if ($this->fetchMode == PGSQL_ASSOC || $this->fetchMode == PGSQL_BOTH) {
|
||||
foreach($this->_blobArr as $k => $v) {
|
||||
$this->fields[$v] = ADORecordSet_postgres64::_decode($this->fields[$v]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 10% speedup to move MoveNext to child class
|
||||
function MoveNext()
|
||||
{
|
||||
if (!$this->EOF) {
|
||||
$this->_currentRow++;
|
||||
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
|
||||
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
|
||||
if (is_array($this->fields) && $this->fields) {
|
||||
if (isset($this->_blobArr)) $this->_fixblobs();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->fields = false;
|
||||
$this->EOF = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function _fetch()
|
||||
{
|
||||
|
||||
if ($this->_currentRow >= $this->_numOfRows && $this->_numOfRows >= 0)
|
||||
return false;
|
||||
|
||||
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
|
||||
|
||||
if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
|
||||
|
||||
return (is_array($this->fields));
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
return @pg_freeresult($this->_queryID);
|
||||
}
|
||||
|
||||
function MetaType($t,$len=-1,$fieldobj=false)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
switch (strtoupper($t)) {
|
||||
case 'MONEY': // stupid, postgres expects money to be a string
|
||||
case 'INTERVAL':
|
||||
case 'CHAR':
|
||||
case 'CHARACTER':
|
||||
case 'VARCHAR':
|
||||
case 'NAME':
|
||||
case 'BPCHAR':
|
||||
case '_VARCHAR':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
|
||||
case 'TEXT':
|
||||
return 'X';
|
||||
|
||||
case 'IMAGE': // user defined type
|
||||
case 'BLOB': // user defined type
|
||||
case 'BIT': // This is a bit string, not a single bit, so don't return 'L'
|
||||
case 'VARBIT':
|
||||
case 'BYTEA':
|
||||
return 'B';
|
||||
|
||||
case 'BOOL':
|
||||
case 'BOOLEAN':
|
||||
return 'L';
|
||||
|
||||
case 'DATE':
|
||||
return 'D';
|
||||
|
||||
case 'TIME':
|
||||
case 'DATETIME':
|
||||
case 'TIMESTAMP':
|
||||
case 'TIMESTAMPTZ':
|
||||
return 'T';
|
||||
|
||||
case 'SMALLINT':
|
||||
case 'BIGINT':
|
||||
case 'INTEGER':
|
||||
case 'INT8':
|
||||
case 'INT4':
|
||||
case 'INT2':
|
||||
if (isset($fieldobj) &&
|
||||
empty($fieldobj->primary_key) && empty($fieldobj->unique)) return 'I';
|
||||
|
||||
case 'OID':
|
||||
case 'SERIAL':
|
||||
return 'R';
|
||||
|
||||
default:
|
||||
return 'N';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
192
phpgwapi/inc/adodb/drivers/adodb-postgres7.inc.php
Normal file
192
phpgwapi/inc/adodb/drivers/adodb-postgres7.inc.php
Normal file
@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4.
|
||||
|
||||
Postgres7 support.
|
||||
28 Feb 2001: Currently indicate that we support LIMIT
|
||||
01 Dec 2001: dannym added support for default values
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include_once(ADODB_DIR."/drivers/adodb-postgres64.inc.php");
|
||||
|
||||
class ADODB_postgres7 extends ADODB_postgres64 {
|
||||
var $databaseType = 'postgres7';
|
||||
var $hasLimit = true; // set to true for pgsql 6.5+ only. support pgsql/mysql SELECT * FROM TABLE LIMIT 10
|
||||
var $ansiOuter = true;
|
||||
var $charSet = true; //set to true for Postgres 7 and above - PG client supports encodings
|
||||
|
||||
function ADODB_postgres7()
|
||||
{
|
||||
$this->ADODB_postgres64();
|
||||
}
|
||||
|
||||
|
||||
// the following should be compat with postgresql 7.2,
|
||||
// which makes obsolete the LIMIT limit,offset syntax
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
|
||||
{
|
||||
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
|
||||
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : '';
|
||||
if ($secs2cache)
|
||||
$rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
|
||||
else
|
||||
$rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
|
||||
|
||||
return $rs;
|
||||
}
|
||||
/*
|
||||
function Prepare($sql)
|
||||
{
|
||||
$info = $this->ServerInfo();
|
||||
if ($info['version']>=7.3) {
|
||||
return array($sql,false);
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
*/
|
||||
|
||||
// from Edward Jaramilla, improved version - works on pg 7.4
|
||||
function MetaForeignKeys($table, $owner=false, $upper=false)
|
||||
{
|
||||
$sql = 'SELECT t.tgargs as args
|
||||
FROM
|
||||
pg_trigger t,pg_class c,pg_proc p
|
||||
WHERE
|
||||
t.tgenabled AND
|
||||
t.tgrelid = c.oid AND
|
||||
t.tgfoid = p.oid AND
|
||||
p.proname = \'RI_FKey_check_ins\' AND
|
||||
c.relname = \''.strtolower($table).'\'
|
||||
ORDER BY
|
||||
t.tgrelid';
|
||||
|
||||
$rs = $this->Execute($sql);
|
||||
|
||||
if ($rs && !$rs->EOF) {
|
||||
$arr =& $rs->GetArray();
|
||||
$a = array();
|
||||
foreach($arr as $v)
|
||||
{
|
||||
$data = explode(chr(0), $v['args']);
|
||||
if ($upper) {
|
||||
$a[strtoupper($data[2])][] = strtoupper($data[4].'='.$data[5]);
|
||||
} else {
|
||||
$a[$data[2]][] = $data[4].'='.$data[5];
|
||||
}
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function xMetaForeignKeys($table, $owner=false, $upper=false)
|
||||
{
|
||||
|
||||
$sql = '
|
||||
SELECT t.tgargs as args
|
||||
FROM pg_trigger t,
|
||||
pg_class c,
|
||||
pg_class c2,
|
||||
pg_proc f
|
||||
WHERE t.tgenabled
|
||||
AND t.tgrelid=c.oid
|
||||
AND t.tgconstrrelid=c2.oid
|
||||
AND t.tgfoid=f.oid
|
||||
AND f.proname ~ \'^RI_FKey_check_ins\'
|
||||
AND t.tgargs like \'$1\\\000'.strtolower($table).'%\'
|
||||
ORDER BY t.tgrelid';
|
||||
|
||||
$rs = $this->Execute($sql);
|
||||
if ($rs && !$rs->EOF) {
|
||||
$arr =& $rs->GetArray();
|
||||
$a = array();
|
||||
foreach($arr as $v) {
|
||||
$data = explode(chr(0), $v['args']);
|
||||
if ($upper) {
|
||||
$a[] = array(strtoupper($data[2]) => strtoupper($data[4].'='.$data[5]));
|
||||
} else {
|
||||
$a[] = array($data[2] => $data[4].'='.$data[5]);
|
||||
}
|
||||
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
// this is a set of functions for managing client encoding - very important if the encodings
|
||||
// of your database and your output target (i.e. HTML) don't match
|
||||
//for instance, you may have UNICODE database and server it on-site as WIN1251 etc.
|
||||
// GetCharSet - get the name of the character set the client is using now
|
||||
// the functions should work with Postgres 7.0 and above, the set of charsets supported
|
||||
// depends on compile flags of postgres distribution - if no charsets were compiled into the server
|
||||
// it will return 'SQL_ANSI' always
|
||||
function GetCharSet()
|
||||
{
|
||||
//we will use ADO's builtin property charSet
|
||||
$this->charSet = @pg_client_encoding($this->_connectionID);
|
||||
if (!$this->charSet) {
|
||||
return false;
|
||||
} else {
|
||||
return $this->charSet;
|
||||
}
|
||||
}
|
||||
|
||||
// SetCharSet - switch the client encoding
|
||||
function SetCharSet($charset_name)
|
||||
{
|
||||
$this->GetCharSet();
|
||||
if ($this->charSet !== $charset_name) {
|
||||
$if = pg_set_client_encoding($this->_connectionID, $charset_name);
|
||||
if ($if == "0" & $this->GetCharSet() == $charset_name) {
|
||||
return true;
|
||||
} else return false;
|
||||
} else return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordSet_postgres7 extends ADORecordSet_postgres64{
|
||||
|
||||
var $databaseType = "postgres7";
|
||||
|
||||
|
||||
function ADORecordSet_postgres7($queryID,$mode=false)
|
||||
{
|
||||
$this->ADORecordSet_postgres64($queryID,$mode);
|
||||
}
|
||||
|
||||
// 10% speedup to move MoveNext to child class
|
||||
function MoveNext()
|
||||
{
|
||||
if (!$this->EOF) {
|
||||
$this->_currentRow++;
|
||||
if ($this->_numOfRows < 0 || $this->_numOfRows > $this->_currentRow) {
|
||||
$this->fields = @pg_fetch_array($this->_queryID,$this->_currentRow,$this->fetchMode);
|
||||
|
||||
if (is_array($this->fields)) {
|
||||
if ($this->fields && isset($this->_blobArr)) $this->_fixblobs();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->fields = false;
|
||||
$this->EOF = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
33
phpgwapi/inc/adodb/drivers/adodb-proxy.inc.php
Normal file
33
phpgwapi/inc/adodb/drivers/adodb-proxy.inc.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4.
|
||||
|
||||
Synonym for csv driver.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (! defined("_ADODB_PROXY_LAYER")) {
|
||||
define("_ADODB_PROXY_LAYER", 1 );
|
||||
include(ADODB_DIR."/drivers/adodb-csv.inc.php");
|
||||
|
||||
class ADODB_proxy extends ADODB_csv {
|
||||
var $databaseType = 'proxy';
|
||||
var $databaseProvider = 'csv';
|
||||
}
|
||||
class ADORecordset_proxy extends ADORecordset_csv {
|
||||
var $databaseType = "proxy";
|
||||
|
||||
function ADORecordset_proxy($id,$mode=false)
|
||||
{
|
||||
$this->ADORecordset($id,$mode);
|
||||
}
|
||||
};
|
||||
} // define
|
||||
|
||||
?>
|
66
phpgwapi/inc/adodb/drivers/adodb-sapdb.inc.php
Normal file
66
phpgwapi/inc/adodb/drivers/adodb-sapdb.inc.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
SAPDB data driver. Requires ODBC.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('_ADODB_ODBC_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
|
||||
}
|
||||
if (!defined('ADODB_SAPDB')){
|
||||
define('ADODB_SAPDB',1);
|
||||
|
||||
class ADODB_SAPDB extends ADODB_odbc {
|
||||
var $databaseType = "sapdb";
|
||||
var $concat_operator = '||';
|
||||
var $sysDate = 'DATE';
|
||||
var $sysTimeStamp = 'TIMESTAMP';
|
||||
var $fmtDate = "\\D\\A\\T\\E('Y-m-d')"; /// used by DBDate() as the default date format used by the database
|
||||
var $fmtTimeStamp = "\\T\\I\\M\\E\\S\\T\\A\\M\\P('Y-m-d','H:i:s')"; /// used by DBTimeStamp as the default timestamp fmt.
|
||||
|
||||
function ADODB_SAPDB()
|
||||
{
|
||||
//if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC;
|
||||
$this->ADODB_odbc();
|
||||
}
|
||||
|
||||
/*
|
||||
SelectLimit implementation problems:
|
||||
|
||||
The following will return random 10 rows as order by performed after "WHERE rowno<10"
|
||||
which is not ideal...
|
||||
|
||||
select * from table where rowno < 10 order by 1
|
||||
|
||||
This means that we have to use the adoconnection base class SelectLimit when
|
||||
there is an "order by".
|
||||
|
||||
See http://listserv.sap.com/pipermail/sapdb.general/2002-January/010405.html
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ADORecordSet_sapdb extends ADORecordSet_odbc {
|
||||
|
||||
var $databaseType = "sapdb";
|
||||
|
||||
function ADORecordSet_sapdb($id,$mode=false)
|
||||
{
|
||||
$this->ADORecordSet_odbc($id,$mode);
|
||||
}
|
||||
}
|
||||
|
||||
} //define
|
||||
?>
|
322
phpgwapi/inc/adodb/drivers/adodb-sqlite.inc.php
Normal file
322
phpgwapi/inc/adodb/drivers/adodb-sqlite.inc.php
Normal file
@ -0,0 +1,322 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
SQLite info: http://www.hwaci.com/sw/sqlite/
|
||||
|
||||
Install Instructions:
|
||||
====================
|
||||
1. Place this in adodb/drivers
|
||||
2. Rename the file, remove the .txt prefix.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB_sqlite extends ADOConnection {
|
||||
var $databaseType = "sqlite";
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $concat_operator='||';
|
||||
var $_errorNo = 0;
|
||||
var $hasLimit = true;
|
||||
var $hasInsertID = true; /// supports autoincrement ID?
|
||||
var $hasAffectedRows = true; /// supports affected rows for update/delete?
|
||||
var $metaTablesSQL = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
|
||||
var $sysDate = "adodb_date('Y-m-d')";
|
||||
var $sysTimeStamp = "adodb_date('Y-m-d H:i:s')";
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
|
||||
function ADODB_sqlite()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
function __get($name)
|
||||
{
|
||||
switch($name) {
|
||||
case 'sysDate': return "'".date($this->fmtDate)."'";
|
||||
case 'sysTimeStamp' : return "'".date($this->sysTimeStamp)."'";
|
||||
}
|
||||
}*/
|
||||
|
||||
function ServerInfo()
|
||||
{
|
||||
$arr['version'] = sqlite_libversion();
|
||||
$arr['description'] = 'SQLite ';
|
||||
$arr['encoding'] = sqlite_libencoding();
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$ret = $this->Execute("BEGIN TRANSACTION");
|
||||
$this->transCnt += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
$ret = $this->Execute("COMMIT");
|
||||
if ($this->transCnt>0)$this->transCnt -= 1;
|
||||
return !empty($ret);
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$ret = $this->Execute("ROLLBACK");
|
||||
if ($this->transCnt>0)$this->transCnt -= 1;
|
||||
return !empty($ret);
|
||||
}
|
||||
|
||||
function _insertid()
|
||||
{
|
||||
return sqlite_last_insert_rowid($this->_connectionID);
|
||||
}
|
||||
|
||||
function _affectedrows()
|
||||
{
|
||||
return sqlite_changes($this->_connectionID);
|
||||
}
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->_logsql) return $this->_errorMsg;
|
||||
return ($this->_errorNo) ? sqlite_error_string($this->_errorNo) : '';
|
||||
}
|
||||
|
||||
function ErrorNo()
|
||||
{
|
||||
return $this->_errorNo;
|
||||
}
|
||||
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
$fmt = $this->qstr($fmt);
|
||||
return ($col) ? "adodb_date2($fmt,$col)" : "adodb_date($fmt)";
|
||||
}
|
||||
|
||||
function &MetaColumns($tab)
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$rs = $this->Execute("select * from $tab limit 1");
|
||||
if (!$rs) return false;
|
||||
$arr = array();
|
||||
for ($i=0,$max=$rs->_numOfFields; $i < $max; $i++) {
|
||||
$fld =& $rs->FetchField($i);
|
||||
if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] =& $fld;
|
||||
else $arr[strtoupper($fld->name)] =& $fld;
|
||||
}
|
||||
$rs->Close();
|
||||
return $arr;
|
||||
}
|
||||
|
||||
function _createFunctions()
|
||||
{
|
||||
@sqlite_create_function($this->_connectionID, 'adodb_date', 'adodb_date', 1);
|
||||
@sqlite_create_function($this->_connectionID, 'adodb_date2', 'adodb_date2', 2);
|
||||
}
|
||||
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('sqlite_open')) return null;
|
||||
|
||||
$this->_connectionID = sqlite_open($argHostname);
|
||||
if ($this->_connectionID === false) return false;
|
||||
$this->_createFunctions();
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('sqlite_open')) return null;
|
||||
|
||||
$this->_connectionID = sqlite_popen($argHostname);
|
||||
if ($this->_connectionID === false) return false;
|
||||
$this->_createFunctions();
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns query ID if successful, otherwise false
|
||||
function _query($sql,$inputarr=false)
|
||||
{
|
||||
$rez = sqlite_query($sql,$this->_connectionID);
|
||||
if (!$rez) {
|
||||
$this->_errorNo = sqlite_last_error($this->_connectionID);
|
||||
}
|
||||
|
||||
return $rez;
|
||||
}
|
||||
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
|
||||
{
|
||||
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
|
||||
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : '');
|
||||
if ($secs2cache)
|
||||
$rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
|
||||
else
|
||||
$rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
/*
|
||||
This algorithm is not very efficient, but works even if table locking
|
||||
is not available.
|
||||
|
||||
Will return false if unable to generate an ID after $MAXLOOPS attempts.
|
||||
*/
|
||||
var $_genSeqSQL = "create table %s (id integer)";
|
||||
|
||||
function GenID($seq='adodbseq',$start=1)
|
||||
{
|
||||
// if you have to modify the parameter below, your database is overloaded,
|
||||
// or you need to implement generation of id's yourself!
|
||||
$MAXLOOPS = 100;
|
||||
//$this->debug=1;
|
||||
while (--$MAXLOOPS>=0) {
|
||||
$num = $this->GetOne("select id from $seq");
|
||||
if ($num === false) {
|
||||
$this->Execute(sprintf($this->_genSeqSQL ,$seq));
|
||||
$start -= 1;
|
||||
$num = '0';
|
||||
$ok = $this->Execute("insert into $seq values($start)");
|
||||
if (!$ok) return false;
|
||||
}
|
||||
$this->Execute("update $seq set id=id+1 where id=$num");
|
||||
|
||||
if ($this->affected_rows() > 0) {
|
||||
$num += 1;
|
||||
$this->genID = $num;
|
||||
return $num;
|
||||
}
|
||||
}
|
||||
if ($fn = $this->raiseErrorFn) {
|
||||
$fn($this->databaseType,'GENID',-32000,"Unable to generate unique id after $MAXLOOPS attempts",$seq,$num);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function CreateSequence($seqname='adodbseq',$start=1)
|
||||
{
|
||||
if (empty($this->_genSeqSQL)) return false;
|
||||
$ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname));
|
||||
if (!$ok) return false;
|
||||
$start -= 1;
|
||||
return $this->Execute("insert into $seqname values($start)");
|
||||
}
|
||||
|
||||
var $_dropSeqSQL = 'drop table %s';
|
||||
function DropSequence($seqname)
|
||||
{
|
||||
if (empty($this->_dropSeqSQL)) return false;
|
||||
return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
return @sqlite_close($this->_connectionID);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordset_sqlite extends ADORecordSet {
|
||||
|
||||
var $databaseType = "sqlite";
|
||||
var $bind = false;
|
||||
|
||||
function ADORecordset_sqlite($queryID,$mode=false)
|
||||
{
|
||||
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
switch($mode) {
|
||||
case ADODB_FETCH_NUM: $this->fetchMode = SQLITE_NUM; break;
|
||||
case ADODB_FETCH_ASSOC: $this->fetchMode = SQLITE_ASSOC; break;
|
||||
default: $this->fetchMode = SQLITE_BOTH; break;
|
||||
}
|
||||
|
||||
$this->_queryID = $queryID;
|
||||
|
||||
$this->_inited = true;
|
||||
$this->fields = array();
|
||||
if ($queryID) {
|
||||
$this->_currentRow = 0;
|
||||
$this->EOF = !$this->_fetch();
|
||||
@$this->_initrs();
|
||||
} else {
|
||||
$this->_numOfRows = 0;
|
||||
$this->_numOfFields = 0;
|
||||
$this->EOF = true;
|
||||
}
|
||||
|
||||
return $this->_queryID;
|
||||
}
|
||||
|
||||
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
$fld = new ADOFieldObject;
|
||||
$fld->name = sqlite_field_name($this->_queryID, $fieldOffset);
|
||||
$fld->type = 'VARCHAR';
|
||||
$fld->max_length = -1;
|
||||
return $fld;
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
$this->_numOfRows = @sqlite_num_rows($this->_queryID);
|
||||
$this->_numOfFields = @sqlite_num_fields($this->_queryID);
|
||||
}
|
||||
|
||||
function Fields($colname)
|
||||
{
|
||||
if ($this->fetchMode != SQLITE_NUM) return $this->fields[$colname];
|
||||
if (!$this->bind) {
|
||||
$this->bind = array();
|
||||
for ($i=0; $i < $this->_numOfFields; $i++) {
|
||||
$o = $this->FetchField($i);
|
||||
$this->bind[strtoupper($o->name)] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fields[$this->bind[strtoupper($colname)]];
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return sqlite_seek($this->_queryID, $row);
|
||||
}
|
||||
|
||||
function _fetch($ignore_fields=false)
|
||||
{
|
||||
$this->fields = @sqlite_fetch_array($this->_queryID,$this->fetchMode);
|
||||
return !empty($this->fields);
|
||||
}
|
||||
|
||||
function _close()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
62
phpgwapi/inc/adodb/drivers/adodb-sqlitepo.inc.php
Normal file
62
phpgwapi/inc/adodb/drivers/adodb-sqlitepo.inc.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Portable version of sqlite driver, to make it more similar to other database drivers.
|
||||
The main differences are
|
||||
|
||||
1. When selecting (joining) multiple tables, in assoc mode the table
|
||||
names are included in the assoc keys in the "sqlite" driver.
|
||||
|
||||
In "sqlitepo" driver, the table names are stripped from the returned column names.
|
||||
When this results in a conflict, the first field get preference.
|
||||
|
||||
Contributed by Herman Kuiper herman#ozuzo.net
|
||||
*/
|
||||
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
include_once(ADODB_DIR.'/drivers/adodb-sqlite.inc.php');
|
||||
|
||||
class ADODB_sqlitepo extends ADODB_sqlite {
|
||||
var $databaseType = 'sqlitepo';
|
||||
|
||||
function ADODB_sqlitepo()
|
||||
{
|
||||
$this->ADODB_sqlite();
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
|
||||
class ADORecordset_sqlitepo extends ADORecordset_sqlite {
|
||||
|
||||
var $databaseType = 'sqlitepo';
|
||||
|
||||
function ADORecordset_sqlitepo($queryID,$mode=false)
|
||||
{
|
||||
$this->ADORecordset_sqlite($queryID,$mode);
|
||||
}
|
||||
|
||||
// Modified to strip table names from returned fields
|
||||
function _fetch($ignore_fields=false)
|
||||
{
|
||||
$this->fields = array();
|
||||
$fields = @sqlite_fetch_array($this->_queryID,$this->fetchMode);
|
||||
if(is_array($fields))
|
||||
foreach($fields as $n => $v)
|
||||
{
|
||||
if(($p = strpos($n, ".")) !== false)
|
||||
$n = substr($n, $p+1);
|
||||
$this->fields[$n] = $v;
|
||||
}
|
||||
|
||||
return !empty($this->fields);
|
||||
}
|
||||
}
|
||||
?>
|
408
phpgwapi/inc/adodb/drivers/adodb-sybase.inc.php
Normal file
408
phpgwapi/inc/adodb/drivers/adodb-sybase.inc.php
Normal file
@ -0,0 +1,408 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim. All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Sybase driver contributed by Toni (toni.tunkkari@finebyte.com)
|
||||
|
||||
- MSSQL date patch applied.
|
||||
|
||||
Date patch by Toni 15 Feb 2002
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class ADODB_sybase extends ADOConnection {
|
||||
var $databaseType = "sybase";
|
||||
//var $dataProvider = 'sybase';
|
||||
var $replaceQuote = "''"; // string to use to replace quotes
|
||||
var $fmtDate = "'Y-m-d'";
|
||||
var $fmtTimeStamp = "'Y-m-d H:i:s'";
|
||||
var $hasInsertID = true;
|
||||
var $hasAffectedRows = true;
|
||||
var $metaTablesSQL="select name from sysobjects where type='U' or type='V'";
|
||||
// see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
|
||||
var $metaColumnsSQL = "SELECT c.column_name, c.column_type, c.width FROM syscolumn c, systable t WHERE t.table_name='%s' AND c.table_id=t.table_id AND t.table_type='BASE'";
|
||||
/*
|
||||
"select c.name,t.name,c.length from
|
||||
syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
|
||||
where o.name='%s'";
|
||||
*/
|
||||
var $concat_operator = '+';
|
||||
var $arrayClass = 'ADORecordSet_array_sybase';
|
||||
var $sysDate = 'GetDate()';
|
||||
var $leftOuter = '*=';
|
||||
var $rightOuter = '=*';
|
||||
|
||||
function ADODB_sybase()
|
||||
{
|
||||
}
|
||||
|
||||
// might require begintrans -- committrans
|
||||
function _insertid()
|
||||
{
|
||||
return $this->GetOne('select @@identity');
|
||||
}
|
||||
// might require begintrans -- committrans
|
||||
function _affectedrows()
|
||||
{
|
||||
return $this->GetOne('select @@rowcount');
|
||||
}
|
||||
|
||||
|
||||
function BeginTrans()
|
||||
{
|
||||
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt += 1;
|
||||
|
||||
$this->Execute('BEGIN TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
function CommitTrans($ok=true)
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
|
||||
if (!$ok) return $this->RollbackTrans();
|
||||
|
||||
$this->transCnt -= 1;
|
||||
$this->Execute('COMMIT TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
function RollbackTrans()
|
||||
{
|
||||
if ($this->transOff) return true;
|
||||
$this->transCnt -= 1;
|
||||
$this->Execute('ROLLBACK TRAN');
|
||||
return true;
|
||||
}
|
||||
|
||||
// http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
|
||||
function RowLock($tables,$where)
|
||||
{
|
||||
if (!$this->_hastrans) $this->BeginTrans();
|
||||
$tables = str_replace(',',' HOLDLOCK,',$tables);
|
||||
return $this->GetOne("select top 1 null as ignore from $tables HOLDLOCK where $where");
|
||||
|
||||
}
|
||||
|
||||
function SelectDB($dbName) {
|
||||
$this->databaseName = $dbName;
|
||||
if ($this->_connectionID) {
|
||||
return @sybase_select_db($dbName);
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
/* Returns: the last error message from previous database operation
|
||||
Note: This function is NOT available for Microsoft SQL Server. */
|
||||
|
||||
function ErrorMsg()
|
||||
{
|
||||
if ($this->_logsql) return $this->_errorMsg;
|
||||
$this->_errorMsg = sybase_get_last_message();
|
||||
return $this->_errorMsg;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('sybase_connect')) return null;
|
||||
|
||||
$this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
// returns true or false
|
||||
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
|
||||
{
|
||||
if (!function_exists('sybase_connect')) return null;
|
||||
|
||||
$this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
|
||||
if ($this->_connectionID === false) return false;
|
||||
if ($argDatabasename) return $this->SelectDB($argDatabasename);
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns query ID if successful, otherwise false
|
||||
function _query($sql,$inputarr)
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
|
||||
if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
|
||||
return sybase_unbuffered_query($sql,$this->_connectionID);
|
||||
else
|
||||
return sybase_query($sql,$this->_connectionID);
|
||||
}
|
||||
|
||||
// See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
|
||||
{
|
||||
if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
|
||||
$rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
|
||||
return $rs;
|
||||
}
|
||||
$cnt = ($nrows > 0) ? $nrows : 0;
|
||||
if ($offset > 0 && $cnt) $cnt += $offset;
|
||||
|
||||
$this->Execute("set rowcount $cnt");
|
||||
$rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0);
|
||||
$this->Execute("set rowcount 0");
|
||||
|
||||
return $rs;
|
||||
}
|
||||
|
||||
// returns true or false
|
||||
function _close()
|
||||
{
|
||||
return @sybase_close($this->_connectionID);
|
||||
}
|
||||
|
||||
function UnixDate($v)
|
||||
{
|
||||
return ADORecordSet_array_sybase::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return ADORecordSet_array_sybase::UnixTimeStamp($v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Added 2003-10-05 by Chris Phillipson
|
||||
# Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=16756?target=%25N%15_12018_START_RESTART_N%25
|
||||
# to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
|
||||
// Format date column in sql string given an input format that understands Y M D
|
||||
function SQLDate($fmt, $col=false)
|
||||
{
|
||||
if (!$col) $col = $this->sysTimeStamp;
|
||||
$s = '';
|
||||
|
||||
$len = strlen($fmt);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($s) $s .= '+';
|
||||
$ch = $fmt[$i];
|
||||
switch($ch) {
|
||||
case 'Y':
|
||||
case 'y':
|
||||
$s .= "datename(yy,$col)";
|
||||
break;
|
||||
case 'M':
|
||||
$s .= "convert(char(3),$col,0)";
|
||||
break;
|
||||
case 'm':
|
||||
$s .= "replace(str(month($col),2),' ','0')";
|
||||
break;
|
||||
case 'Q':
|
||||
case 'q':
|
||||
$s .= "datename(qq,$col)";
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
$s .= "replace(str(datepart(dd,$col),2),' ','0')";
|
||||
break;
|
||||
case 'h':
|
||||
$s .= "substring(convert(char(14),$col,0),13,2)";
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
$s .= "replace(str(datepart(hh,$col),2),' ','0')";
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
$s .= "replace(str(datepart(mi,$col),2),' ','0')";
|
||||
break;
|
||||
case 's':
|
||||
$s .= "replace(str(datepart(ss,$col),2),' ','0')";
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
$s .= "substring(convert(char(19),$col,0),18,2)";
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($ch == '\\') {
|
||||
$i++;
|
||||
$ch = substr($fmt,$i,1);
|
||||
}
|
||||
$s .= $this->qstr($ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
# Added 2003-10-07 by Chris Phillipson
|
||||
# Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
|
||||
# to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
|
||||
function MetaPrimaryKeys($table)
|
||||
{
|
||||
$sql = "SELECT c.column_name " .
|
||||
"FROM syscolumn c, systable t " .
|
||||
"WHERE t.table_name='$table' AND c.table_id=t.table_id " .
|
||||
"AND t.table_type='BASE' " .
|
||||
"AND c.pkey = 'Y' " .
|
||||
"ORDER BY c.column_id";
|
||||
|
||||
$a = $this->GetCol($sql);
|
||||
if ($a && sizeof($a)>0) return $a;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------------------
|
||||
Class Name: Recordset
|
||||
--------------------------------------------------------------------------------------*/
|
||||
global $ADODB_sybase_mths;
|
||||
$ADODB_sybase_mths = array(
|
||||
'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
|
||||
'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
|
||||
|
||||
class ADORecordset_sybase extends ADORecordSet {
|
||||
|
||||
var $databaseType = "sybase";
|
||||
var $canSeek = true;
|
||||
// _mths works only in non-localised system
|
||||
var $_mths = array('JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
|
||||
|
||||
function ADORecordset_sybase($id,$mode=false)
|
||||
{
|
||||
if ($mode === false) {
|
||||
global $ADODB_FETCH_MODE;
|
||||
$mode = $ADODB_FETCH_MODE;
|
||||
}
|
||||
if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
|
||||
else $this->fetchMode = $mode;
|
||||
return $this->ADORecordSet($id,$mode);
|
||||
}
|
||||
|
||||
/* Returns: an object containing field information.
|
||||
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
|
||||
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
|
||||
fetchField() is retrieved. */
|
||||
function &FetchField($fieldOffset = -1)
|
||||
{
|
||||
if ($fieldOffset != -1) {
|
||||
$o = @sybase_fetch_field($this->_queryID, $fieldOffset);
|
||||
}
|
||||
else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
|
||||
$o = @sybase_fetch_field($this->_queryID);
|
||||
}
|
||||
// older versions of PHP did not support type, only numeric
|
||||
if ($o && !isset($o->type)) $o->type = ($o->numeric) ? 'float' : 'varchar';
|
||||
return $o;
|
||||
}
|
||||
|
||||
function _initrs()
|
||||
{
|
||||
global $ADODB_COUNTRECS;
|
||||
$this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1;
|
||||
$this->_numOfFields = @sybase_num_fields($this->_queryID);
|
||||
}
|
||||
|
||||
function _seek($row)
|
||||
{
|
||||
return @sybase_data_seek($this->_queryID, $row);
|
||||
}
|
||||
|
||||
function _fetch($ignore_fields=false)
|
||||
{
|
||||
if ($this->fetchMode == ADODB_FETCH_NUM) {
|
||||
$this->fields = @sybase_fetch_row($this->_queryID);
|
||||
} else if ($this->fetchMode == ADODB_FETCH_ASSOC) {
|
||||
$this->fields = @sybase_fetch_row($this->_queryID);
|
||||
if (is_array($this->fields)) {
|
||||
$this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
$this->fields = @sybase_fetch_array($this->_queryID);
|
||||
}
|
||||
if ( is_array($this->fields)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* close() only needs to be called if you are worried about using too much memory while your script
|
||||
is running. All associated result memory for the specified result identifier will automatically be freed. */
|
||||
function _close() {
|
||||
return @sybase_free_result($this->_queryID);
|
||||
}
|
||||
|
||||
// sybase/mssql uses a default date like Dec 30 2000 12:00AM
|
||||
function UnixDate($v)
|
||||
{
|
||||
return ADORecordSet_array_sybase::UnixDate($v);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
return ADORecordSet_array_sybase::UnixTimeStamp($v);
|
||||
}
|
||||
}
|
||||
|
||||
class ADORecordSet_array_sybase extends ADORecordSet_array {
|
||||
function ADORecordSet_array_sybase($id=-1)
|
||||
{
|
||||
$this->ADORecordSet_array($id);
|
||||
}
|
||||
|
||||
// sybase/mssql uses a default date like Dec 30 2000 12:00AM
|
||||
function UnixDate($v)
|
||||
{
|
||||
global $ADODB_sybase_mths;
|
||||
|
||||
//Dec 30 2000 12:00AM
|
||||
if (!ereg( "([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})"
|
||||
,$v, $rr)) return parent::UnixDate($v);
|
||||
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
|
||||
|
||||
$themth = substr(strtoupper($rr[1]),0,3);
|
||||
$themth = $ADODB_sybase_mths[$themth];
|
||||
if ($themth <= 0) return false;
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime(0,0,0,$themth,$rr[2],$rr[3]);
|
||||
}
|
||||
|
||||
function UnixTimeStamp($v)
|
||||
{
|
||||
global $ADODB_sybase_mths;
|
||||
//11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com
|
||||
//Changed [0-9] to [0-9 ] in day conversion
|
||||
if (!ereg( "([A-Za-z]{3})[-/\. ]([0-9 ]{1,2})[-/\. ]([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})"
|
||||
,$v, $rr)) return parent::UnixTimeStamp($v);
|
||||
if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
|
||||
|
||||
$themth = substr(strtoupper($rr[1]),0,3);
|
||||
$themth = $ADODB_sybase_mths[$themth];
|
||||
if ($themth <= 0) return false;
|
||||
|
||||
switch (strtoupper($rr[6])) {
|
||||
case 'P':
|
||||
if ($rr[4]<12) $rr[4] += 12;
|
||||
break;
|
||||
case 'A':
|
||||
if ($rr[4]==12) $rr[4] = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// h-m-s-MM-DD-YY
|
||||
return mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);
|
||||
}
|
||||
}
|
||||
?>
|
106
phpgwapi/inc/adodb/drivers/adodb-vfp.inc.php
Normal file
106
phpgwapi/inc/adodb/drivers/adodb-vfp.inc.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Microsoft Visual FoxPro data driver. Requires ODBC. Works only on MS Windows.
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
if (!defined('_ADODB_ODBC_LAYER')) {
|
||||
include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
|
||||
}
|
||||
if (!defined('ADODB_VFP')){
|
||||
define('ADODB_VFP',1);
|
||||
class ADODB_vfp extends ADODB_odbc {
|
||||
var $databaseType = "vfp";
|
||||
var $fmtDate = "{^Y-m-d}";
|
||||
var $fmtTimeStamp = "{^Y-m-d, h:i:sA}";
|
||||
var $replaceQuote = "'+chr(39)+'" ;
|
||||
var $true = '.T.';
|
||||
var $false = '.F.';
|
||||
var $hasTop = 'top'; // support mssql SELECT TOP 10 * FROM TABLE
|
||||
var $_bindInputArray = false; // strangely enough, setting to true does not work reliably
|
||||
var $sysTimeStamp = 'datetime()';
|
||||
var $sysDate = 'date()';
|
||||
var $ansiOuter = true;
|
||||
var $hasTransactions = false;
|
||||
var $curmode = SQL_CUR_USE_ODBC ; // See sqlext.h, SQL_CUR_DEFAULT == SQL_CUR_USE_DRIVER == 2L
|
||||
|
||||
function ADODB_vfp()
|
||||
{
|
||||
$this->ADODB_odbc();
|
||||
}
|
||||
|
||||
function Time()
|
||||
{
|
||||
return time();
|
||||
}
|
||||
|
||||
function BeginTrans() { return false;}
|
||||
|
||||
// quote string to be sent back to database
|
||||
function qstr($s,$nofixquotes=false)
|
||||
{
|
||||
if (!$nofixquotes) return "'".str_replace("\r\n","'+chr(13)+'",str_replace("'",$this->replaceQuote,$s))."'";
|
||||
return "'".$s."'";
|
||||
}
|
||||
|
||||
|
||||
// TOP requires ORDER BY for VFP
|
||||
function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
|
||||
{
|
||||
$this->hasTop = preg_match('/ORDER[ \t\r\n]+BY/is',$sql) ? 'top' : false;
|
||||
return ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ADORecordSet_vfp extends ADORecordSet_odbc {
|
||||
|
||||
var $databaseType = "vfp";
|
||||
|
||||
|
||||
function ADORecordSet_vfp($id,$mode=false)
|
||||
{
|
||||
return $this->ADORecordSet_odbc($id,$mode);
|
||||
}
|
||||
|
||||
function MetaType($t,$len=-1)
|
||||
{
|
||||
if (is_object($t)) {
|
||||
$fieldobj = $t;
|
||||
$t = $fieldobj->type;
|
||||
$len = $fieldobj->max_length;
|
||||
}
|
||||
switch (strtoupper($t)) {
|
||||
case 'C':
|
||||
if ($len <= $this->blobSize) return 'C';
|
||||
case 'M':
|
||||
return 'X';
|
||||
|
||||
case 'D': return 'D';
|
||||
|
||||
case 'T': return 'T';
|
||||
|
||||
case 'L': return 'L';
|
||||
|
||||
case 'I': return 'I';
|
||||
|
||||
default: return 'N';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //define
|
||||
?>
|
436
phpgwapi/inc/adodb/pear/Auth/Container/ADOdb.php
Normal file
436
phpgwapi/inc/adodb/pear/Auth/Container/ADOdb.php
Normal file
@ -0,0 +1,436 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Martin Jansen <mj@php.net>
|
||||
// | Richard Tango-Lowy <richtl@arscognita.com> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
|
||||
require_once 'Auth/Container.php';
|
||||
require_once 'adodb.inc.php';
|
||||
require_once 'adodb-pear.inc.php';
|
||||
require_once 'adodb-errorpear.inc.php';
|
||||
|
||||
/**
|
||||
* Storage driver for fetching login data from a database using ADOdb-PHP.
|
||||
*
|
||||
* This storage driver can use all databases which are supported
|
||||
* by the ADBdb DB abstraction layer to fetch login data.
|
||||
* See http://php.weblogs.com/adodb for information on ADOdb.
|
||||
* NOTE: The ADOdb directory MUST be in your PHP include_path!
|
||||
*
|
||||
* @author Richard Tango-Lowy <richtl@arscognita.com>
|
||||
* @package Auth
|
||||
* @version $Revision$
|
||||
*/
|
||||
class Auth_Container_ADOdb extends Auth_Container
|
||||
{
|
||||
|
||||
/**
|
||||
* Additional options for the storage container
|
||||
* @var array
|
||||
*/
|
||||
var $options = array();
|
||||
|
||||
/**
|
||||
* DB object
|
||||
* @var object
|
||||
*/
|
||||
var $db = null;
|
||||
var $dsn = '';
|
||||
|
||||
/**
|
||||
* User that is currently selected from the DB.
|
||||
* @var string
|
||||
*/
|
||||
var $activeUser = '';
|
||||
|
||||
// {{{ Constructor
|
||||
|
||||
/**
|
||||
* Constructor of the container class
|
||||
*
|
||||
* Initate connection to the database via PEAR::ADOdb
|
||||
*
|
||||
* @param string Connection data or DB object
|
||||
* @return object Returns an error object if something went wrong
|
||||
*/
|
||||
function Auth_Container_ADOdb($dsn)
|
||||
{
|
||||
$this->_setDefaults();
|
||||
|
||||
if (is_array($dsn)) {
|
||||
$this->_parseOptions($dsn);
|
||||
|
||||
if (empty($this->options['dsn'])) {
|
||||
PEAR::raiseError('No connection parameters specified!');
|
||||
}
|
||||
} else {
|
||||
// Extract db_type from dsn string.
|
||||
$this->options['dsn'] = $dsn;
|
||||
$this->_parseDsn( $dsn );
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _connect()
|
||||
|
||||
/**
|
||||
* Connect to database by using the given DSN string
|
||||
*
|
||||
* @access private
|
||||
* @param string DSN string
|
||||
* @return mixed Object on error, otherwise bool
|
||||
*/
|
||||
function _connect($dsn)
|
||||
{
|
||||
if (is_string($dsn) || is_array($dsn)) {
|
||||
if(!$this->db) {
|
||||
$this->db = &ADONewConnection($this->options['db_type']);
|
||||
|
||||
if( $err = ADODB_Pear_error() ) {
|
||||
return PEAR::raiseError($err);
|
||||
}
|
||||
}
|
||||
|
||||
$dbconnected = $this->db->Connect(
|
||||
$this->options['db_host'],
|
||||
$this->options['db_user'],
|
||||
$this->options['db_pass'],
|
||||
$this->options['db_name'] );
|
||||
if( !$dbconnected ) {
|
||||
PEAR::raiseError('Unable to connect to database' );
|
||||
}
|
||||
|
||||
} else {
|
||||
return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
|
||||
41,
|
||||
PEAR_ERROR_RETURN,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
if(!$this->db) {
|
||||
return PEAR::raiseError(ADODB_Pear_error());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _prepare()
|
||||
|
||||
/**
|
||||
* Prepare database connection
|
||||
*
|
||||
* This function checks if we have already opened a connection to
|
||||
* the database. If that's not the case, a new connection is opened.
|
||||
*
|
||||
* @access private
|
||||
* @return mixed True or a DB error object.
|
||||
*/
|
||||
function _prepare()
|
||||
{
|
||||
if(!$this->db) {
|
||||
$res = $this->_connect($this->options['dsn']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ query()
|
||||
|
||||
/**
|
||||
* Prepare query to the database
|
||||
*
|
||||
* This function checks if we have already opened a connection to
|
||||
* the database. If that's not the case, a new connection is opened.
|
||||
* After that the query is passed to the database.
|
||||
*
|
||||
* @access public
|
||||
* @param string Query string
|
||||
* @return mixed a DB_result object or DB_OK on success, a DB
|
||||
* or PEAR error on failure
|
||||
*/
|
||||
function query($query)
|
||||
{
|
||||
$err = $this->_prepare();
|
||||
if ($err !== true) {
|
||||
return $err;
|
||||
}
|
||||
return $this->db->query($query);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _setDefaults()
|
||||
|
||||
/**
|
||||
* Set some default options
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
function _setDefaults()
|
||||
{
|
||||
$this->options['db_type'] = 'mysql';
|
||||
$this->options['table'] = 'auth';
|
||||
$this->options['usernamecol'] = 'username';
|
||||
$this->options['passwordcol'] = 'password';
|
||||
$this->options['dsn'] = '';
|
||||
$this->options['db_fields'] = '';
|
||||
$this->options['cryptType'] = 'md5';
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ _parseOptions()
|
||||
|
||||
/**
|
||||
* Parse options passed to the container class
|
||||
*
|
||||
* @access private
|
||||
* @param array
|
||||
*/
|
||||
function _parseOptions($array)
|
||||
{
|
||||
foreach ($array as $key => $value) {
|
||||
if (isset($this->options[$key])) {
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/* Include additional fields if they exist */
|
||||
if(!empty($this->options['db_fields'])){
|
||||
if(is_array($this->options['db_fields'])){
|
||||
$this->options['db_fields'] = join($this->options['db_fields'], ', ');
|
||||
}
|
||||
$this->options['db_fields'] = ', '.$this->options['db_fields'];
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ fetchData()
|
||||
|
||||
/**
|
||||
* Get user information from database
|
||||
*
|
||||
* This function uses the given username to fetch
|
||||
* the corresponding login data from the database
|
||||
* table. If an account that matches the passed username
|
||||
* and password is found, the function returns true.
|
||||
* Otherwise it returns false.
|
||||
*
|
||||
* @param string Username
|
||||
* @param string Password
|
||||
* @return mixed Error object or boolean
|
||||
*/
|
||||
function fetchData($username, $password)
|
||||
{
|
||||
// Prepare for a database query
|
||||
$err = $this->_prepare();
|
||||
if ($err !== true) {
|
||||
return PEAR::raiseError($err->getMessage(), $err->getCode());
|
||||
}
|
||||
|
||||
// Find if db_fields contains a *, i so assume all col are selected
|
||||
if(strstr($this->options['db_fields'], '*')){
|
||||
$sql_from = "*";
|
||||
}
|
||||
else{
|
||||
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
|
||||
}
|
||||
|
||||
$query = "SELECT ".$sql_from.
|
||||
" FROM ".$this->options['table'].
|
||||
" WHERE ".$this->options['usernamecol']." = " . $this->db->Quote($username);
|
||||
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
$rset = $this->db->Execute( $query );
|
||||
$res = $rset->fetchRow();
|
||||
|
||||
if (DB::isError($res)) {
|
||||
return PEAR::raiseError($res->getMessage(), $res->getCode());
|
||||
}
|
||||
if (!is_array($res)) {
|
||||
$this->activeUser = '';
|
||||
return false;
|
||||
}
|
||||
if ($this->verifyPassword(trim($password, "\r\n"),
|
||||
trim($res[$this->options['passwordcol']], "\r\n"),
|
||||
$this->options['cryptType'])) {
|
||||
// Store additional field values in the session
|
||||
foreach ($res as $key => $value) {
|
||||
if ($key == $this->options['passwordcol'] ||
|
||||
$key == $this->options['usernamecol']) {
|
||||
continue;
|
||||
}
|
||||
// Use reference to the auth object if exists
|
||||
// This is because the auth session variable can change so a static call to setAuthData does not make sence
|
||||
if(is_object($this->_auth_obj)){
|
||||
$this->_auth_obj->setAuthData($key, $value);
|
||||
} else {
|
||||
Auth::setAuthData($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->activeUser = $res[$this->options['usernamecol']];
|
||||
return false;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ listUsers()
|
||||
|
||||
function listUsers()
|
||||
{
|
||||
$err = $this->_prepare();
|
||||
if ($err !== true) {
|
||||
return PEAR::raiseError($err->getMessage(), $err->getCode());
|
||||
}
|
||||
|
||||
$retVal = array();
|
||||
|
||||
// Find if db_fileds contains a *, i so assume all col are selected
|
||||
if(strstr($this->options['db_fields'], '*')){
|
||||
$sql_from = "*";
|
||||
}
|
||||
else{
|
||||
$sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
|
||||
}
|
||||
|
||||
$query = sprintf("SELECT %s FROM %s",
|
||||
$sql_from,
|
||||
$this->options['table']
|
||||
);
|
||||
$res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
|
||||
|
||||
if (DB::isError($res)) {
|
||||
return PEAR::raiseError($res->getMessage(), $res->getCode());
|
||||
} else {
|
||||
foreach ($res as $user) {
|
||||
$user['username'] = $user[$this->options['usernamecol']];
|
||||
$retVal[] = $user;
|
||||
}
|
||||
}
|
||||
return $retVal;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ addUser()
|
||||
|
||||
/**
|
||||
* Add user to the storage container
|
||||
*
|
||||
* @access public
|
||||
* @param string Username
|
||||
* @param string Password
|
||||
* @param mixed Additional information that are stored in the DB
|
||||
*
|
||||
* @return mixed True on success, otherwise error object
|
||||
*/
|
||||
function addUser($username, $password, $additional = "")
|
||||
{
|
||||
if (function_exists($this->options['cryptType'])) {
|
||||
$cryptFunction = $this->options['cryptType'];
|
||||
} else {
|
||||
$cryptFunction = 'md5';
|
||||
}
|
||||
|
||||
$additional_key = '';
|
||||
$additional_value = '';
|
||||
|
||||
if (is_array($additional)) {
|
||||
foreach ($additional as $key => $value) {
|
||||
$additional_key .= ', ' . $key;
|
||||
$additional_value .= ", '" . $value . "'";
|
||||
}
|
||||
}
|
||||
|
||||
$query = sprintf("INSERT INTO %s (%s, %s%s) VALUES ('%s', '%s'%s)",
|
||||
$this->options['table'],
|
||||
$this->options['usernamecol'],
|
||||
$this->options['passwordcol'],
|
||||
$additional_key,
|
||||
$username,
|
||||
$cryptFunction($password),
|
||||
$additional_value
|
||||
);
|
||||
|
||||
$res = $this->query($query);
|
||||
|
||||
if (DB::isError($res)) {
|
||||
return PEAR::raiseError($res->getMessage(), $res->getCode());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ removeUser()
|
||||
|
||||
/**
|
||||
* Remove user from the storage container
|
||||
*
|
||||
* @access public
|
||||
* @param string Username
|
||||
*
|
||||
* @return mixed True on success, otherwise error object
|
||||
*/
|
||||
function removeUser($username)
|
||||
{
|
||||
$query = sprintf("DELETE FROM %s WHERE %s = '%s'",
|
||||
$this->options['table'],
|
||||
$this->options['usernamecol'],
|
||||
$username
|
||||
);
|
||||
|
||||
$res = $this->query($query);
|
||||
|
||||
if (DB::isError($res)) {
|
||||
return PEAR::raiseError($res->getMessage(), $res->getCode());
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
|
||||
function _parseDsn( $dsn )
|
||||
{
|
||||
if( is_string( $dsn )) {
|
||||
preg_match( '/^(\w*):\/\/(\w*)(:(\w*))?@(\w*)\/(\w*)$/', $dsn, $match );
|
||||
|
||||
$this->options['db_type'] = $match[1];
|
||||
$this->options['db_user'] = $match[2];
|
||||
$this->options['db_pass'] = $match[3];
|
||||
$this->options['db_host'] = $match[5];
|
||||
$this->options['db_name'] = $match[6];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showDbg( $string ) {
|
||||
print "<P>$string</P>";
|
||||
}
|
||||
function dump( $var, $str, $vardump = false ) {
|
||||
print "<H4>$str</H4><pre>";
|
||||
( !$vardump ) ? ( print_r( $var )) : ( var_dump( $var ));
|
||||
print "</pre>";
|
||||
}
|
||||
?>
|
102
phpgwapi/inc/adodb/perf/perf-db2.inc.php
Normal file
102
phpgwapi/inc/adodb/perf/perf-db2.inc.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for basic performance monitoring and tuning
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
// Simple guide to configuring db2: so-so http://www.devx.com/gethelpon/10MinuteSolution/16575
|
||||
|
||||
// SELECT * FROM TABLE(SNAPSHOT_APPL('SAMPLE', -1)) as t
|
||||
class perf_db2 extends adodb_perf{
|
||||
var $createTableSQL = "CREATE TABLE adodb_logsql (
|
||||
created TIMESTAMP NOT NULL,
|
||||
sql0 varchar(250) NOT NULL,
|
||||
sql1 varchar(4000) NOT NULL,
|
||||
params varchar(3000) NOT NULL,
|
||||
tracer varchar(500) NOT NULL,
|
||||
timer decimal(16,6) NOT NULL
|
||||
)";
|
||||
|
||||
var $settings = array(
|
||||
'Ratios',
|
||||
'data cache hit ratio' => array('RATIO',
|
||||
"SELECT
|
||||
case when sum(POOL_DATA_L_READS+POOL_INDEX_L_READS)=0 then 0
|
||||
else 100*(1-sum(POOL_DATA_P_READS+POOL_INDEX_P_READS)/sum(POOL_DATA_L_READS+POOL_INDEX_L_READS)) end
|
||||
FROM TABLE(SNAPSHOT_APPL('',-2)) as t",
|
||||
'=WarnCacheRatio'),
|
||||
|
||||
'Data Cache',
|
||||
'data cache buffers' => array('DATAC',
|
||||
'select sum(npages) from SYSCAT.BUFFERPOOLS',
|
||||
'See <a href=http://www7b.boulder.ibm.com/dmdd/library/techarticle/anshum/0107anshum.html#bufferpoolsize>tuning reference</a>.' ),
|
||||
'cache blocksize' => array('DATAC',
|
||||
'select avg(pagesize) from SYSCAT.BUFFERPOOLS',
|
||||
'' ),
|
||||
'data cache size' => array('DATAC',
|
||||
'select sum(npages*pagesize) from SYSCAT.BUFFERPOOLS',
|
||||
'' ),
|
||||
'Connections',
|
||||
'current connections' => array('SESS',
|
||||
"SELECT count(*) FROM TABLE(SNAPSHOT_APPL_INFO('',-2)) as t",
|
||||
''),
|
||||
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
function perf_db2(&$conn)
|
||||
{
|
||||
$this->conn =& $conn;
|
||||
}
|
||||
|
||||
function Explain($sql,$partial=false)
|
||||
{
|
||||
$save = $this->conn->LogSQL(false);
|
||||
if ($partial) {
|
||||
$sqlq = $this->conn->qstr($sql.'%');
|
||||
$arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
|
||||
if ($arr) {
|
||||
foreach($arr as $row) {
|
||||
$sql = reset($row);
|
||||
if (crc32($sql) == $partial) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$qno = rand();
|
||||
$ok = $this->conn->Execute("EXPLAIN PLAN SET QUERYNO=$qno FOR $sql");
|
||||
ob_start();
|
||||
if (!$ok) echo "<p>Have EXPLAIN tables been created?</p>";
|
||||
else {
|
||||
$rs = $this->conn->Execute("select * from explain_statement where queryno=$qno");
|
||||
if ($rs) rs2html($rs);
|
||||
}
|
||||
$s = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->conn->LogSQL($save);
|
||||
|
||||
$s .= $this->Tracer($sql);
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
function Tables()
|
||||
{
|
||||
$rs = $this->conn->Execute("select tabschema,tabname,card as rows,
|
||||
npages pages_used,fpages pages_allocated, tbspace tablespace
|
||||
from syscat.tables where tabschema not in ('SYSCAT','SYSIBM','SYSSTAT') order by 1,2");
|
||||
return rs2html($rs,false,false,false,false);
|
||||
}
|
||||
}
|
||||
?>
|
70
phpgwapi/inc/adodb/perf/perf-informix.inc.php
Normal file
70
phpgwapi/inc/adodb/perf/perf-informix.inc.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for basic performance monitoring and tuning
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
//
|
||||
// Thx to Fernando Ortiz, mailto:fortiz#lacorona.com.mx
|
||||
// With info taken from http://www.oninit.com/oninit/sysmaster/index.html
|
||||
//
|
||||
class perf_informix extends adodb_perf{
|
||||
|
||||
// Maximum size on varchar upto 9.30 255 chars
|
||||
// better truncate varchar to 255 than char(4000) ?
|
||||
var $createTableSQL = "CREATE TABLE adodb_logsql (
|
||||
created datetime year to second NOT NULL,
|
||||
sql0 varchar(250) NOT NULL,
|
||||
sql1 varchar(255) NOT NULL,
|
||||
params varchar(255) NOT NULL,
|
||||
tracer varchar(255) NOT NULL,
|
||||
timer decimal(16,6) NOT NULL
|
||||
)";
|
||||
|
||||
var $tablesSQL = "select a.tabname tablename, ti_nptotal*2 size_in_k, ti_nextns extents, ti_nrows records from systables c, sysmaster:systabnames a, sysmaster:systabinfo b where c.tabname not matches 'sys*' and c.partnum = a.partnum and c.partnum = b.ti_partnum";
|
||||
|
||||
var $settings = array(
|
||||
'Ratios',
|
||||
'data cache hit ratio' => array('RATIOH',
|
||||
"select round((1-(wt.value / (rd.value + wr.value)))*100,2)
|
||||
from sysmaster:sysprofile wr, sysmaster:sysprofile rd, sysmaster:sysprofile wt
|
||||
where rd.name = 'pagreads' and
|
||||
wr.name = 'pagwrites' and
|
||||
wt.name = 'buffwts'",
|
||||
'=WarnCacheRatio'),
|
||||
'IO',
|
||||
'data reads' => array('IO',
|
||||
"select value from sysmaster:sysprofile where name='pagreads'",
|
||||
'Page reads'),
|
||||
|
||||
'data writes' => array('IO',
|
||||
"select value from sysmaster:sysprofile where name='pagwrites'",
|
||||
'Page writes'),
|
||||
|
||||
'Connections',
|
||||
'current connections' => array('SESS',
|
||||
'select count(*) from sysmaster:syssessions',
|
||||
'Number of sessions'),
|
||||
|
||||
false
|
||||
|
||||
);
|
||||
|
||||
function perf_informix(&$conn)
|
||||
{
|
||||
$this->conn =& $conn;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
164
phpgwapi/inc/adodb/perf/perf-mssql.inc.php
Normal file
164
phpgwapi/inc/adodb/perf/perf-mssql.inc.php
Normal file
@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for basic performance monitoring and tuning
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
/*
|
||||
MSSQL has moved most performance info to Performance Monitor
|
||||
*/
|
||||
class perf_mssql extends adodb_perf{
|
||||
var $sql1 = 'cast(sql1 as text)';
|
||||
var $createTableSQL = "CREATE TABLE adodb_logsql (
|
||||
created datetime NOT NULL,
|
||||
sql0 varchar(250) NOT NULL,
|
||||
sql1 varchar(4000) NOT NULL,
|
||||
params varchar(3000) NOT NULL,
|
||||
tracer varchar(500) NOT NULL,
|
||||
timer decimal(16,6) NOT NULL
|
||||
)";
|
||||
|
||||
var $settings = array(
|
||||
'Ratios',
|
||||
'data cache hit ratio' => array('RATIO',
|
||||
"select round((a.cntr_value*100.0)/b.cntr_value,2) from master.dbo.sysperfinfo a, master.dbo.sysperfinfo b where a.counter_name = 'Buffer cache hit ratio' and b.counter_name='Buffer cache hit ratio base'",
|
||||
'=WarnCacheRatio'),
|
||||
'prepared sql hit ratio' => array('RATIO',
|
||||
array('dbcc cachestats','Prepared',1,100),
|
||||
''),
|
||||
'adhoc sql hit ratio' => array('RATIO',
|
||||
array('dbcc cachestats','Adhoc',1,100),
|
||||
''),
|
||||
'IO',
|
||||
'data reads' => array('IO',
|
||||
"select cntr_value from master.dbo.sysperfinfo where counter_name = 'Page reads/sec'"),
|
||||
'data writes' => array('IO',
|
||||
"select cntr_value from master.dbo.sysperfinfo where counter_name = 'Page writes/sec'"),
|
||||
|
||||
'Data Cache',
|
||||
'data cache size' => array('DATAC',
|
||||
"select cntr_value*8192 from master.dbo.sysperfinfo where counter_name = 'Total Pages' and object_name='SQLServer:Buffer Manager'",
|
||||
'' ),
|
||||
'data cache blocksize' => array('DATAC',
|
||||
"select 8192",'page size'),
|
||||
'Connections',
|
||||
'current connections' => array('SESS',
|
||||
'=sp_who',
|
||||
''),
|
||||
'max connections' => array('SESS',
|
||||
"SELECT @@MAX_CONNECTIONS",
|
||||
''),
|
||||
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
function perf_mssql(&$conn)
|
||||
{
|
||||
if ($conn->dataProvider == 'odbc') {
|
||||
$this->sql1 = 'sql1';
|
||||
//$this->explain = false;
|
||||
}
|
||||
$this->conn =& $conn;
|
||||
}
|
||||
|
||||
function Explain($sql,$partial=false)
|
||||
{
|
||||
|
||||
$save = $this->conn->LogSQL(false);
|
||||
if ($partial) {
|
||||
$sqlq = $this->conn->qstr($sql.'%');
|
||||
$arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
|
||||
if ($arr) {
|
||||
foreach($arr as $row) {
|
||||
$sql = reset($row);
|
||||
if (crc32($sql) == $partial) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$s = '<p><b>Explain</b>: '.htmlspecialchars($sql).'</p>';
|
||||
$this->conn->Execute("SET SHOWPLAN_ALL ON;");
|
||||
$sql = str_replace('?',"''",$sql);
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$rs =& $this->conn->Execute($sql);
|
||||
//adodb_printr($rs);
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
if ($rs) {
|
||||
$rs->MoveNext();
|
||||
$s .= '<table bgcolor=white border=0 cellpadding="1" callspacing=0><tr><td nowrap align=center> Rows<td nowrap align=center> IO<td nowrap align=center> CPU<td align=left> Plan</tr>';
|
||||
while (!$rs->EOF) {
|
||||
$s .= '<tr><td>'.round($rs->fields[8],1).'<td>'.round($rs->fields[9],3).'<td align=right>'.round($rs->fields[10],3).'<td nowrap><pre>'.htmlspecialchars($rs->fields[0])."</td></pre></tr>\n"; ## NOTE CORRUPT </td></pre> tag is intentional!!!!
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$s .= '</table>';
|
||||
|
||||
$rs->NextRecordSet();
|
||||
}
|
||||
|
||||
$this->conn->Execute("SET SHOWPLAN_ALL OFF;");
|
||||
$this->conn->LogSQL($save);
|
||||
$s .= $this->Tracer($sql);
|
||||
return $s;
|
||||
}
|
||||
|
||||
function Tables()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
//$this->conn->debug=1;
|
||||
$s = '<table border=1 bgcolor=white><tr><td><b>tablename</b></td><td><b>size_in_k</b></td><td><b>index size</b></td><td><b>reserved size</b></td></tr>';
|
||||
$rs1 = $this->conn->Execute("select distinct name from sysobjects where xtype='U'");
|
||||
if ($rs1) {
|
||||
while (!$rs1->EOF) {
|
||||
$tab = $rs1->fields[0];
|
||||
$tabq = $this->conn->qstr($tab);
|
||||
$rs2 = $this->conn->Execute("sp_spaceused $tabq");
|
||||
if ($rs2) {
|
||||
$s .= '<tr><td>'.$tab.'</td><td align=right>'.$rs2->fields[3].'</td><td align=right>'.$rs2->fields[4].'</td><td align=right>'.$rs2->fields[2].'</td></tr>';
|
||||
$rs2->Close();
|
||||
}
|
||||
$rs1->MoveNext();
|
||||
}
|
||||
$rs1->Close();
|
||||
}
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
return $s.'</table>';
|
||||
}
|
||||
|
||||
function sp_who()
|
||||
{
|
||||
$arr = $this->conn->GetArray('sp_who');
|
||||
return sizeof($arr);
|
||||
}
|
||||
|
||||
function HealthCheck($cli=false)
|
||||
{
|
||||
|
||||
$this->conn->Execute('dbcc traceon(3604)');
|
||||
$html = adodb_perf::HealthCheck($cli);
|
||||
$this->conn->Execute('dbcc traceoff(3604)');
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
259
phpgwapi/inc/adodb/perf/perf-mysql.inc.php
Normal file
259
phpgwapi/inc/adodb/perf/perf-mysql.inc.php
Normal file
@ -0,0 +1,259 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for basic performance monitoring and tuning
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class perf_mysql extends adodb_perf{
|
||||
|
||||
var $tablesSQL = 'show table status';
|
||||
|
||||
var $createTableSQL = "CREATE TABLE adodb_logsql (
|
||||
created datetime NOT NULL,
|
||||
sql0 varchar(250) NOT NULL,
|
||||
sql1 text NOT NULL,
|
||||
params text NOT NULL,
|
||||
tracer text NOT NULL,
|
||||
timer decimal(16,6) NOT NULL
|
||||
)";
|
||||
|
||||
var $settings = array(
|
||||
'Ratios',
|
||||
'MyISAM cache hit ratio' => array('RATIO',
|
||||
'=GetKeyHitRatio',
|
||||
'=WarnCacheRatio'),
|
||||
'InnoDB cache hit ratio' => array('RATIO',
|
||||
'=GetInnoDBHitRatio',
|
||||
'=WarnCacheRatio'),
|
||||
'data cache hit ratio' => array('HIDE', # only if called
|
||||
'=FindDBHitRatio',
|
||||
'=WarnCacheRatio'),
|
||||
'sql cache hit ratio' => array('RATIO',
|
||||
'=GetQHitRatio',
|
||||
''),
|
||||
'IO',
|
||||
'data reads' => array('IO',
|
||||
'=GetReads',
|
||||
'Number of selects (Key_reads is not accurate)'),
|
||||
'data writes' => array('IO',
|
||||
'=GetWrites',
|
||||
'Number of inserts/updates/deletes * coef (Key_writes is not accurate)'),
|
||||
|
||||
'Data Cache',
|
||||
'MyISAM data cache size' => array('DATAC',
|
||||
array("show variables", 'key_buffer_size'),
|
||||
'' ),
|
||||
'BDB data cache size' => array('DATAC',
|
||||
array("show variables", 'bdb_cache_size'),
|
||||
'' ),
|
||||
'InnoDB data cache size' => array('DATAC',
|
||||
array("show variables", 'innodb_buffer_pool_size'),
|
||||
'' ),
|
||||
'Memory Usage',
|
||||
'read buffer size' => array('CACHE',
|
||||
array("show variables", 'read_buffer_size'),
|
||||
'(per session)'),
|
||||
'sort buffer size' => array('CACHE',
|
||||
array("show variables", 'sort_buffer_size'),
|
||||
'Size of sort buffer (per session)' ),
|
||||
'table cache' => array('CACHE',
|
||||
array("show variables", 'table_cache'),
|
||||
'Number of tables to keep open'),
|
||||
'Connections',
|
||||
'current connections' => array('SESS',
|
||||
array('show status','Threads_connected'),
|
||||
''),
|
||||
'max connections' => array( 'SESS',
|
||||
array("show variables",'max_connections'),
|
||||
''),
|
||||
|
||||
false
|
||||
);
|
||||
|
||||
function perf_mysql(&$conn)
|
||||
{
|
||||
$this->conn =& $conn;
|
||||
}
|
||||
|
||||
function Explain($sql,$partial=false)
|
||||
{
|
||||
|
||||
if (strtoupper(substr(trim($sql),0,6)) !== 'SELECT') return '<p>Unable to EXPLAIN non-select statement</p>';
|
||||
$save = $this->conn->LogSQL(false);
|
||||
if ($partial) {
|
||||
$sqlq = $this->conn->qstr($sql.'%');
|
||||
$arr = $this->conn->GetArray("select distinct sql1 from adodb_logsql where sql1 like $sqlq");
|
||||
if ($arr) {
|
||||
foreach($arr as $row) {
|
||||
$sql = reset($row);
|
||||
if (crc32($sql) == $partial) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sql = str_replace('?',"''",$sql);
|
||||
|
||||
if ($partial) {
|
||||
$sqlq = $this->conn->qstr($sql.'%');
|
||||
$sql = $this->conn->GetOne("select sql1 from adodb_logsql where sql1 like $sqlq");
|
||||
}
|
||||
|
||||
$s = '<p><b>Explain</b>: '.htmlspecialchars($sql).'</p>';
|
||||
$rs = $this->conn->Execute('EXPLAIN '.$sql);
|
||||
$s .= rs2html($rs,false,false,false,false);
|
||||
$this->conn->LogSQL($save);
|
||||
$s .= $this->Tracer($sql);
|
||||
return $s;
|
||||
}
|
||||
|
||||
function Tables()
|
||||
{
|
||||
if (!$this->tablesSQL) return false;
|
||||
|
||||
$rs = $this->conn->Execute($this->tablesSQL);
|
||||
if (!$rs) return false;
|
||||
|
||||
$html = rs2html($rs,false,false,false,false);
|
||||
return $html;
|
||||
}
|
||||
|
||||
function GetReads()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$rs = $this->conn->Execute('show status');
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!$rs) return 0;
|
||||
$val = 0;
|
||||
while (!$rs->EOF) {
|
||||
switch($rs->fields[0]) {
|
||||
case 'Com_select':
|
||||
$val = $rs->fields[1];
|
||||
$rs->Close();
|
||||
return $val;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
function GetWrites()
|
||||
{
|
||||
global $ADODB_FETCH_MODE;
|
||||
$save = $ADODB_FETCH_MODE;
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
$rs = $this->conn->Execute('show status');
|
||||
$ADODB_FETCH_MODE = $save;
|
||||
|
||||
if (!$rs) return 0;
|
||||
$val = 0.0;
|
||||
while (!$rs->EOF) {
|
||||
switch($rs->fields[0]) {
|
||||
case 'Com_insert':
|
||||
$val += $rs->fields[1]; break;
|
||||
case 'Com_delete':
|
||||
$val += $rs->fields[1]; break;
|
||||
case 'Com_update':
|
||||
$val += $rs->fields[1]/2;
|
||||
$rs->Close();
|
||||
return $val;
|
||||
}
|
||||
$rs->MoveNext();
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
|
||||
return $val;
|
||||
}
|
||||
|
||||
function FindDBHitRatio()
|
||||
{
|
||||
// first find out type of table
|
||||
//$this->conn->debug=1;
|
||||
$rs = $this->conn->Execute('show table status');
|
||||
if (!$rs) return '';
|
||||
$type = strtoupper($rs->fields[1]);
|
||||
$rs->Close();
|
||||
switch($type){
|
||||
case 'MYISAM':
|
||||
case 'ISAM':
|
||||
return $this->DBParameter('MyISAM cache hit ratio').' (MyISAM)';
|
||||
case 'INNODB':
|
||||
return $this->DBParameter('InnoDB cache hit ratio').' (InnoDB)';
|
||||
default:
|
||||
return $type.' not supported';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function GetQHitRatio()
|
||||
{
|
||||
//Total number of queries = Qcache_inserts + Qcache_hits + Qcache_not_cached
|
||||
$hits = $this->_DBParameter(array("show status","Qcache_hits"));
|
||||
$total = $this->_DBParameter(array("show status","Qcache_inserts"));
|
||||
$total += $this->_DBParameter(array("show status","Qcache_not_cached"));
|
||||
|
||||
$total += $hits;
|
||||
if ($total) return ($hits*100)/$total;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Use session variable to store Hit percentage, because MySQL
|
||||
does not remember last value of SHOW INNODB STATUS hit ratio
|
||||
|
||||
# 1st query to SHOW INNODB STATUS
|
||||
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
|
||||
Buffer pool hit rate 1000 / 1000
|
||||
|
||||
# 2nd query to SHOW INNODB STATUS
|
||||
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
|
||||
No buffer pool activity since the last printout
|
||||
*/
|
||||
function GetInnoDBHitRatio()
|
||||
{
|
||||
global $HTTP_SESSION_VARS;
|
||||
|
||||
$rs = $this->conn->Execute('show innodb status');
|
||||
if (!$rs || $rs->EOF) return 0;
|
||||
$stat = $rs->fields[0];
|
||||
$rs->Close();
|
||||
$at = strpos($stat,'Buffer pool hit rate');
|
||||
$stat = substr($stat,$at,200);
|
||||
if (preg_match('!Buffer pool hit rate\s*([0-9]*) / ([0-9]*)!',$stat,$arr)) {
|
||||
$val = 100*$arr[1]/$arr[2];
|
||||
$HTTP_SESSION_VARS['INNODB_HIT_PCT'] = $val;
|
||||
return $val;
|
||||
} else {
|
||||
if (isset($HTTP_SESSION_VARS['INNODB_HIT_PCT'])) return $HTTP_SESSION_VARS['INNODB_HIT_PCT'];
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function GetKeyHitRatio()
|
||||
{
|
||||
$hits = $this->_DBParameter(array("show status","Key_read_requests"));
|
||||
$reqs = $this->_DBParameter(array("show status","Key_reads"));
|
||||
if ($reqs == 0) return 0;
|
||||
|
||||
return ($hits/($reqs+$hits))*100;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
499
phpgwapi/inc/adodb/perf/perf-oci8.inc.php
Normal file
499
phpgwapi/inc/adodb/perf/perf-oci8.inc.php
Normal file
@ -0,0 +1,499 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for basic performance monitoring and tuning
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
class perf_oci8 extends ADODB_perf{
|
||||
|
||||
var $tablesSQL = "select segment_name as \"tablename\", sum(bytes)/1024 as \"size_in_k\",tablespace_name as \"tablespace\",count(*) \"extents\" from sys.user_extents
|
||||
group by segment_name,tablespace_name";
|
||||
|
||||
var $version;
|
||||
var $createTableSQL = "CREATE TABLE adodb_logsql (
|
||||
created date NOT NULL,
|
||||
sql0 varchar(250) NOT NULL,
|
||||
sql1 varchar(4000) NOT NULL,
|
||||
params varchar(4000),
|
||||
tracer varchar(4000),
|
||||
timer decimal(16,6) NOT NULL
|
||||
)";
|
||||
|
||||
var $settings = array(
|
||||
'Ratios',
|
||||
'data cache hit ratio' => array('RATIOH',
|
||||
"select round((1-(phy.value / (cur.value + con.value)))*100,2)
|
||||
from v\$sysstat cur, v\$sysstat con, v\$sysstat phy
|
||||
where cur.name = 'db block gets' and
|
||||
con.name = 'consistent gets' and
|
||||
phy.name = 'physical reads'",
|
||||
'=WarnCacheRatio'),
|
||||
|
||||
'sql cache hit ratio' => array( 'RATIOH',
|
||||
'select round(100*(sum(pins)-sum(reloads))/sum(pins),2) from v$librarycache',
|
||||
'increase <i>shared_pool_size</i> if too ratio low'),
|
||||
|
||||
'datadict cache hit ratio' => array('RATIOH',
|
||||
"select
|
||||
round((1 - (sum(getmisses) / (sum(gets) +
|
||||
sum(getmisses))))*100,2)
|
||||
from v\$rowcache",
|
||||
'increase <i>shared_pool_size</i> if too ratio low'),
|
||||
|
||||
'memory sort ratio' => array('RATIOH',
|
||||
"SELECT ROUND((100 * b.VALUE) /DECODE ((a.VALUE + b.VALUE),
|
||||
0,1,(a.VALUE + b.VALUE)),2)
|
||||
FROM v\$sysstat a,
|
||||
v\$sysstat b
|
||||
WHERE a.name = 'sorts (disk)'
|
||||
AND b.name = 'sorts (memory)'",
|
||||
"% of memory sorts compared to disk sorts - should be over 95%"),
|
||||
|
||||
'IO',
|
||||
'data reads' => array('IO',
|
||||
"select value from v\$sysstat where name='physical reads'"),
|
||||
|
||||
'data writes' => array('IO',
|
||||
"select value from v\$sysstat where name='physical writes'"),
|
||||
|
||||
'Data Cache',
|
||||
'data cache buffers' => array( 'DATAC',
|
||||
"select a.value/b.value from v\$parameter a, v\$parameter b
|
||||
where a.name = 'db_cache_size' and b.name= 'db_block_size'",
|
||||
'Number of cache buffers. Tune <i>db_cache_size</i> if the <i>data cache hit ratio</i> is too low.'),
|
||||
'data cache blocksize' => array('DATAC',
|
||||
"select value from v\$parameter where name='db_block_size'",
|
||||
'' ),
|
||||
'Memory Pools',
|
||||
'data cache size' => array('DATAC',
|
||||
"select value from v\$parameter where name = 'db_cache_size'",
|
||||
'db_cache_size' ),
|
||||
'shared pool size' => array('DATAC',
|
||||
"select value from v\$parameter where name = 'shared_pool_size'",
|
||||
'shared_pool_size, which holds shared sql, stored procedures, dict cache and similar shared structs' ),
|
||||
'java pool size' => array('DATAJ',
|
||||
"select value from v\$parameter where name = 'java_pool_size'",
|
||||
'java_pool_size' ),
|
||||
'large pool buffer size' => array('CACHE',
|
||||
"select value from v\$parameter where name='large_pool_size'",
|
||||
'this pool is for large mem allocations (not because it is larger than shared pool), for MTS sessions, parallel queries, io buffers (large_pool_size) ' ),
|
||||
|
||||
'pga buffer size' => array('CACHE',
|
||||
"select value from v\$parameter where name='pga_aggregate_target'",
|
||||
'program global area is private memory for sorting, and hash and bitmap merges - since oracle 9i (pga_aggregate_target)' ),
|
||||
|
||||
|
||||
'Connections',
|
||||
'current connections' => array('SESS',
|
||||
'select count(*) from sys.v_$session where username is not null',
|
||||
''),
|
||||
'max connections' => array( 'SESS',
|
||||
"select value from v\$parameter where name='sessions'",
|
||||
''),
|
||||
|
||||
'Memory Utilization',
|
||||
'data cache utilization ratio' => array('RATIOU',
|
||||
"select round((1-bytes/sgasize)*100, 2)
|
||||
from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
|
||||
where name = 'free memory' and pool = 'shared pool'",
|
||||
'Percentage of data cache actually in use - should be over 85%'),
|
||||
|
||||
'shared pool utilization ratio' => array('RATIOU',
|
||||
'select round((sga.bytes/p.value)*100,2)
|
||||
from v$sgastat sga, v$parameter p
|
||||
where sga.name = \'free memory\' and sga.pool = \'shared pool\'
|
||||
and p.name = \'shared_pool_size\'',
|
||||
'Percentage of shared pool actually used - too low is bad, too high is worse'),
|
||||
|
||||
'large pool utilization ratio' => array('RATIOU',
|
||||
"select round((1-bytes/sgasize)*100, 2)
|
||||
from (select sum(bytes) sgasize from sys.v_\$sgastat) s, sys.v_\$sgastat f
|
||||
where name = 'free memory' and pool = 'large pool'",
|
||||
'Percentage of large_pool actually in use - too low is bad, too high is worse'),
|
||||
'sort buffer size' => array('CACHE',
|
||||
"select value from v\$parameter where name='sort_area_size'",
|
||||
'max in-mem sort_area_size (per query), uses memory in pga' ),
|
||||
|
||||
'pga usage at peak' => array('RATIOU',
|
||||
'=PGA','Mb utilization at peak transactions (requires Oracle 9i+)'),
|
||||
'Transactions',
|
||||
'rollback segments' => array('ROLLBACK',
|
||||
"select count(*) from sys.v_\$rollstat",
|
||||
''),
|
||||
|
||||
'peak transactions' => array('ROLLBACK',
|
||||
"select max_utilization tx_hwm
|
||||
from sys.v_\$resource_limit
|
||||
where resource_name = 'transactions'",
|
||||
'Taken from high-water-mark'),
|
||||
'max transactions' => array('ROLLBACK',
|
||||
"select value from v\$parameter where name = 'transactions'",
|
||||
'max transactions / rollback segments < 3.5 (or transactions_per_rollback_segment)'),
|
||||
'Parameters',
|
||||
'cursor sharing' => array('CURSOR',
|
||||
"select value from v\$parameter where name = 'cursor_sharing'",
|
||||
'Cursor reuse strategy. Recommended is FORCE (8i+) or SIMILAR (9i+). See <a href=http://www.praetoriate.com/oracle_tips_cursor_sharing.htm>cursor_sharing</a>.'),
|
||||
/*
|
||||
'cursor reuse' => array('CURSOR',
|
||||
"select count(*) from (select sql_text_wo_constants, count(*)
|
||||
from t1
|
||||
group by sql_text_wo_constants
|
||||
having count(*) > 100)",'These are sql statements that should be using bind variables'),*/
|
||||
'index cache cost' => array('COST',
|
||||
"select value from v\$parameter where name = 'optimizer_index_caching'",
|
||||
'=WarnIndexCost'),
|
||||
'random page cost' => array('COST',
|
||||
"select value from v\$parameter where name = 'optimizer_index_cost_adj'",
|
||||
'=WarnPageCost'),
|
||||
|
||||
false
|
||||
|
||||
);
|
||||
|
||||
|
||||
function perf_oci8(&$conn)
|
||||
{
|
||||
$savelog = $conn->LogSQL(false);
|
||||
$this->version = $conn->ServerInfo();
|
||||
$conn->LogSQL($savelog);
|
||||
$this->conn =& $conn;
|
||||
}
|
||||
|
||||
function WarnPageCost($val)
|
||||
{
|
||||
if ($val == 100) $s = '<font color=red><b>Too High</b>. </font>';
|
||||
else $s = '';
|
||||
|
||||
return $s.'Recommended is 20-50 for TP, and 50 for data warehouses. Default is 100. See <a href=http://www.dba-oracle.com/oracle_tips_cost_adj.htm>optimizer_index_cost_adj</a>. ';
|
||||
}
|
||||
|
||||
function WarnIndexCost($val)
|
||||
{
|
||||
if ($val == 0) $s = '<font color=red><b>Too Low</b>. </font>';
|
||||
else $s = '';
|
||||
|
||||
return $s.'Percentage of indexed data blocks expected in the cache.
|
||||
Recommended is 20 (fast disk array) to 50 (slower hard disks). Default is 0.
|
||||
See <a href=http://www.dba-oracle.com/oracle_tips_cbo_part1.htm>optimizer_index_caching</a>.';
|
||||
}
|
||||
|
||||
function PGA()
|
||||
{
|
||||
if ($this->version['version'] < 9) return 'Oracle 9i or later required';
|
||||
|
||||
$rs = $this->conn->Execute("select a.mb,a.targ as pga_size_pct,a.pct from
|
||||
(select round(pga_target_for_estimate/1024.0/1024.0,0) Mb,
|
||||
pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r
|
||||
from v\$pga_target_advice) a left join
|
||||
(select round(pga_target_for_estimate/1024.0/1024.0,0) Mb,
|
||||
pga_target_factor targ,estd_pga_cache_hit_percentage pct,rownum as r
|
||||
from v\$pga_target_advice) b on
|
||||
a.r = b.r+1 where
|
||||
b.pct < 100");
|
||||
if (!$rs) return "Only in 9i or later";
|
||||
$rs->Close();
|
||||
if ($rs->EOF) return "PGA could be too big";
|
||||
|
||||
return reset($rs->fields);
|
||||
}
|
||||
|
||||
function Explain($sql,$partial=false)
|
||||
{
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
$rs =& $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
|
||||
if (!$rs) {
|
||||
echo "<p><b>Missing PLAN_TABLE</b></p>
|
||||
<pre>
|
||||
CREATE TABLE PLAN_TABLE (
|
||||
STATEMENT_ID VARCHAR2(30),
|
||||
TIMESTAMP DATE,
|
||||
REMARKS VARCHAR2(80),
|
||||
OPERATION VARCHAR2(30),
|
||||
OPTIONS VARCHAR2(30),
|
||||
OBJECT_NODE VARCHAR2(128),
|
||||
OBJECT_OWNER VARCHAR2(30),
|
||||
OBJECT_NAME VARCHAR2(30),
|
||||
OBJECT_INSTANCE NUMBER(38),
|
||||
OBJECT_TYPE VARCHAR2(30),
|
||||
OPTIMIZER VARCHAR2(255),
|
||||
SEARCH_COLUMNS NUMBER,
|
||||
ID NUMBER(38),
|
||||
PARENT_ID NUMBER(38),
|
||||
POSITION NUMBER(38),
|
||||
COST NUMBER(38),
|
||||
CARDINALITY NUMBER(38),
|
||||
BYTES NUMBER(38),
|
||||
OTHER_TAG VARCHAR2(255),
|
||||
PARTITION_START VARCHAR2(255),
|
||||
PARTITION_STOP VARCHAR2(255),
|
||||
PARTITION_ID NUMBER(38),
|
||||
OTHER LONG,
|
||||
DISTRIBUTION VARCHAR2(30)
|
||||
);
|
||||
</pre>";
|
||||
return false;
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
// $this->conn->debug=1;
|
||||
|
||||
if ($partial) {
|
||||
$sqlq = $this->conn->qstr($sql.'%');
|
||||
$arr = $this->conn->GetArray("select distinct distinct sql1 from adodb_logsql where sql1 like $sqlq");
|
||||
if ($arr) {
|
||||
foreach($arr as $row) {
|
||||
$sql = reset($row);
|
||||
if (crc32($sql) == $partial) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$s = "<p><b>Explain</b>: ".htmlspecialchars($sql)."</p>";
|
||||
|
||||
$this->conn->BeginTrans();
|
||||
$id = "ADODB ".microtime();
|
||||
$rs =& $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
|
||||
$m = $this->conn->ErrorMsg();
|
||||
if ($m) {
|
||||
$this->conn->RollbackTrans();
|
||||
$this->conn->LogSQL($savelog);
|
||||
$s .= "<p>$m</p>";
|
||||
return $s;
|
||||
}
|
||||
$rs = $this->conn->Execute("
|
||||
select
|
||||
'<pre>'||lpad('--', (level-1)*2,'-') || trim(operation) || ' ' || trim(options)||'</pre>' as Operation,
|
||||
object_name,COST,CARDINALITY,bytes
|
||||
FROM plan_table
|
||||
START WITH id = 0 and STATEMENT_ID='$id'
|
||||
CONNECT BY prior id=parent_id and statement_id='$id'");
|
||||
|
||||
$s .= rs2html($rs,false,false,false,false);
|
||||
$this->conn->RollbackTrans();
|
||||
$this->conn->LogSQL($savelog);
|
||||
$s .= $this->Tracer($sql,$partial);
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
function CheckMemory()
|
||||
{
|
||||
if ($this->version['version'] < 9) return 'Oracle 9i or later required';
|
||||
|
||||
$rs =& $this->conn->Execute("
|
||||
select a.size_for_estimate as cache_mb_estimate,
|
||||
case when a.size_factor=1 then
|
||||
'<<= current'
|
||||
when a.estd_physical_read_factor-b.estd_physical_read_factor > 0 and a.estd_physical_read_factor<1 then
|
||||
'- BETTER - '
|
||||
else ' ' end as currsize,
|
||||
a.estd_physical_read_factor-b.estd_physical_read_factor as best_when_0
|
||||
from (select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$db_cache_advice) a ,
|
||||
(select size_for_estimate,size_factor,estd_physical_read_factor,rownum r from v\$db_cache_advice) b where a.r = b.r-1");
|
||||
if (!$rs) return false;
|
||||
|
||||
/*
|
||||
The v$db_cache_advice utility show the marginal changes in physical data block reads for different sizes of db_cache_size
|
||||
*/
|
||||
$s = "<h3>Data Cache Estimate</h3>";
|
||||
if ($rs->EOF) {
|
||||
$s .= "<p>Cache that is 50% of current size is still too big</p>";
|
||||
} else {
|
||||
$s .= "Ideal size of Data Cache is when \"best_when_0\" changes from a positive number and becomes zero.";
|
||||
$s .= rs2html($rs,false,false,false,false);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
/*
|
||||
Generate html for suspicious/expensive sql
|
||||
*/
|
||||
function tohtml(&$rs,$type)
|
||||
{
|
||||
$o1 = $rs->FetchField(0);
|
||||
$o2 = $rs->FetchField(1);
|
||||
$o3 = $rs->FetchField(2);
|
||||
if ($rs->EOF) return '<p>None found</p>';
|
||||
$check = '';
|
||||
$sql = '';
|
||||
$s = "\n\n<table border=1 bgcolor=white><tr><td><b>".$o1->name.'</b></td><td><b>'.$o2->name.'</b></td><td><b>'.$o3->name.'</b></td></tr>';
|
||||
while (!$rs->EOF) {
|
||||
if ($check != $rs->fields[0].'::'.$rs->fields[1]) {
|
||||
if ($check) {
|
||||
$carr = explode('::',$check);
|
||||
$prefix = "<a href=\"?$type=1&sql=".rawurlencode($sql).'&x#explain">';
|
||||
$suffix = '</a>';
|
||||
if (strlen($prefix)>2000) {
|
||||
$prefix = '';
|
||||
$suffix = '';
|
||||
}
|
||||
|
||||
$s .= "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
|
||||
}
|
||||
$sql = $rs->fields[2];
|
||||
$check = $rs->fields[0].'::'.$rs->fields[1];
|
||||
} else
|
||||
$sql .= $rs->fields[2];
|
||||
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
$carr = explode('::',$check);
|
||||
$prefix = "<a target=".rand()." href=\"?&hidem=1&$type=1&sql=".rawurlencode($sql).'&x#explain">';
|
||||
$suffix = '</a>';
|
||||
if (strlen($prefix)>2000) {
|
||||
$prefix = '';
|
||||
$suffix = '';
|
||||
}
|
||||
$s .= "\n<tr><td align=right>".$carr[0].'</td><td align=right>'.$carr[1].'</td><td>'.$prefix.$sql.$suffix.'</td></tr>';
|
||||
|
||||
return $s."</table>\n\n";
|
||||
}
|
||||
|
||||
// code thanks to Ixora.
|
||||
// http://www.ixora.com.au/scripts/query_opt.htm
|
||||
// requires oracle 8.1.7 or later
|
||||
function SuspiciousSQL($numsql=10)
|
||||
{
|
||||
$sql = "
|
||||
select
|
||||
substr(to_char(s.pct, '99.00'), 2) || '%' load,
|
||||
s.executions executes,
|
||||
p.sql_text
|
||||
from
|
||||
(
|
||||
select
|
||||
address,
|
||||
buffer_gets,
|
||||
executions,
|
||||
pct,
|
||||
rank() over (order by buffer_gets desc) ranking
|
||||
from
|
||||
(
|
||||
select
|
||||
address,
|
||||
buffer_gets,
|
||||
executions,
|
||||
100 * ratio_to_report(buffer_gets) over () pct
|
||||
from
|
||||
sys.v_\$sql
|
||||
where
|
||||
command_type != 47 and module != 'T.O.A.D.'
|
||||
)
|
||||
where
|
||||
buffer_gets > 50 * executions
|
||||
) s,
|
||||
sys.v_\$sqltext p
|
||||
where
|
||||
s.ranking <= $numsql and
|
||||
p.address = s.address
|
||||
order by
|
||||
1 desc, s.address, p.piece";
|
||||
|
||||
global $ADODB_CACHE_MODE,$HTTP_GET_VARS;
|
||||
if (isset($HTTP_GET_VARS['expsixora']) && isset($HTTP_GET_VARS['sql'])) {
|
||||
$partial = empty($HTTP_GET_VARS['part']);
|
||||
echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
|
||||
}
|
||||
|
||||
if (isset($HTTP_GET_VARS['sql'])) return $this->_SuspiciousSQL();
|
||||
|
||||
$save = $ADODB_CACHE_MODE;
|
||||
$ADODB_CACHE_MODE = ADODB_FETCH_NUM;
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
$rs =& $this->conn->SelectLimit($sql);
|
||||
$this->conn->LogSQL($savelog);
|
||||
$ADODB_CACHE_MODE = $save;
|
||||
if ($rs) {
|
||||
$s = "\n<h3>Ixora Suspicious SQL</h3>";
|
||||
$s .= $this->tohtml($rs,'expsixora');
|
||||
} else
|
||||
$s = '';
|
||||
|
||||
if ($s) $s .= '<p>';
|
||||
$s .= $this->_SuspiciousSQL();
|
||||
return $s;
|
||||
}
|
||||
|
||||
// code thanks to Ixora.
|
||||
// http://www.ixora.com.au/scripts/query_opt.htm
|
||||
// requires oracle 8.1.7 or later
|
||||
function ExpensiveSQL($numsql = 10)
|
||||
{
|
||||
$sql = "
|
||||
select
|
||||
substr(to_char(s.pct, '99.00'), 2) || '%' load,
|
||||
s.executions executes,
|
||||
p.sql_text
|
||||
from
|
||||
(
|
||||
select
|
||||
address,
|
||||
disk_reads,
|
||||
executions,
|
||||
pct,
|
||||
rank() over (order by disk_reads desc) ranking
|
||||
from
|
||||
(
|
||||
select
|
||||
address,
|
||||
disk_reads,
|
||||
executions,
|
||||
100 * ratio_to_report(disk_reads) over () pct
|
||||
from
|
||||
sys.v_\$sql
|
||||
where
|
||||
command_type != 47 and module != 'T.O.A.D.'
|
||||
)
|
||||
where
|
||||
disk_reads > 50 * executions
|
||||
) s,
|
||||
sys.v_\$sqltext p
|
||||
where
|
||||
s.ranking <= $numsql and
|
||||
p.address = s.address
|
||||
order by
|
||||
1 desc, s.address, p.piece
|
||||
";
|
||||
global $ADODB_CACHE_MODE,$HTTP_GET_VARS;
|
||||
if (isset($HTTP_GET_VARS['expeixora']) && isset($HTTP_GET_VARS['sql'])) {
|
||||
$partial = empty($HTTP_GET_VARS['part']);
|
||||
echo "<a name=explain></a>".$this->Explain($HTTP_GET_VARS['sql'],$partial)."\n";
|
||||
}
|
||||
|
||||
if (isset($HTTP_GET_VARS['sql'])) {
|
||||
$var =& $this->_ExpensiveSQL();
|
||||
return $var;
|
||||
}
|
||||
$save = $ADODB_CACHE_MODE;
|
||||
$ADODB_CACHE_MODE = ADODB_FETCH_NUM;
|
||||
$savelog = $this->conn->LogSQL(false);
|
||||
$rs =& $this->conn->Execute($sql);
|
||||
$this->conn->LogSQL($savelog);
|
||||
$ADODB_CACHE_MODE = $save;
|
||||
if ($rs) {
|
||||
$s = "\n<h3>Ixora Expensive SQL</h3>";
|
||||
$s .= $this->tohtml($rs,'expeixora');
|
||||
} else
|
||||
$s = '';
|
||||
|
||||
|
||||
if ($s) $s .= '<p>';
|
||||
$s .= $this->_ExpensiveSQL();
|
||||
return $s;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
123
phpgwapi/inc/adodb/perf/perf-postgres.inc.php
Normal file
123
phpgwapi/inc/adodb/perf/perf-postgres.inc.php
Normal file
@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence. See License.txt.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
|
||||
Library for basic performance monitoring and tuning
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_DIR')) die();
|
||||
|
||||
/*
|
||||
Notice that PostgreSQL has no sql query cache
|
||||
*/
|
||||
class perf_postgres extends adodb_perf{
|
||||
|
||||
var $tablesSQL =
|
||||
"select a.relname as tablename,(a.relpages+CASE WHEN b.relpages is null THEN 0 ELSE b.relpages END+CASE WHEN c.relpages is null THEN 0 ELSE c.relpages END)*8 as size_in_K,a.relfilenode as \"OID\" from pg_class a left join pg_class b
|
||||
on b.relname = 'pg_toast_'||trim(a.relfilenode)
|
||||
left join pg_class c on c.relname = 'pg_toast_'||trim(a.relfilenode)||'_index'
|
||||
where a.relname in (select tablename from pg_tables where tablename not like 'pg_%')";
|
||||
|
||||
var $createTableSQL = "CREATE TABLE adodb_logsql (
|
||||
created timestamp NOT NULL,
|
||||
sql0 varchar(250) NOT NULL,
|
||||
sql1 text NOT NULL,
|
||||
params text NOT NULL,
|
||||
tracer text NOT NULL,
|
||||
timer decimal(16,6) NOT NULL
|
||||
)";
|
||||
|
||||
var $settings = array(
|
||||
'Ratios',
|
||||
'statistics collector' => array('RATIO',
|
||||
"select case when count(*)=3 then 'TRUE' else 'FALSE' end from pg_settings where (name='stats_block_level' or name='stats_row_level' or name='stats_start_collector') and setting='on' ",
|
||||
'Value must be TRUE to enable hit ratio statistics (<i>stats_start_collector</i>,<i>stats_row_level</i> and <i>stats_block_level</i> must be set to true in postgresql.conf)'),
|
||||
'data cache hit ratio' => array('RATIO',
|
||||
"select case when blks_hit=0 then 0 else (1-blks_read::float/blks_hit)*100 end from pg_stat_database where datname='\$DATABASE'",
|
||||
'=WarnCacheRatio'),
|
||||
'IO',
|
||||
'data reads' => array('IO',
|
||||
'select sum(heap_blks_read+toast_blks_read) from pg_statio_user_tables',
|
||||
),
|
||||
'data writes' => array('IO',
|
||||
'select sum(n_tup_ins/4.0+n_tup_upd/8.0+n_tup_del/4.0)/16 from pg_stat_user_tables',
|
||||
'Count of inserts/updates/deletes * coef'),
|
||||
|
||||
'Data Cache',
|
||||
'data cache buffers' => array('DATAC',
|
||||
"select setting from pg_settings where name='shared_buffers'",
|
||||
'Number of cache buffers. <a href=http://www.varlena.com/GeneralBits/Tidbits/perf.html#basic>Tuning</a>'),
|
||||
'cache blocksize' => array('DATAC',
|
||||
'select 8192',
|
||||
'(estimate)' ),
|
||||
'data cache size' => array( 'DATAC',
|
||||
"select setting::integer*8192 from pg_settings where name='shared_buffers'",
|
||||
'' ),
|
||||
'operating system cache size' => array( 'DATA',
|
||||
"select setting::integer*8192 from pg_settings where name='effective_cache_size'",
|
||||
'(effective cache size)' ),
|
||||
'Memory Usage',
|
||||
'sort buffer size' => array('CACHE',
|
||||
"select setting::integer*1024 from pg_settings where name='sort_mem'",
|
||||
'Size of sort buffer (per query)' ),
|
||||
'Connections',
|
||||
'current connections' => array('SESS',
|
||||
'select count(*) from pg_stat_activity',
|
||||
''),
|
||||
'max connections' => array('SESS',
|
||||
"select setting from pg_settings where name='max_connections'",
|
||||
''),
|
||||
'Parameters',
|
||||
'rollback buffers' => array('COST',
|
||||
"select setting from pg_settings where name='wal_buffers'",
|
||||
'WAL buffers'),
|
||||
'random page cost' => array('COST',
|
||||
"select setting from pg_settings where name='random_page_cost'",
|
||||
'Cost of doing a seek (default=4). See <a href=http://www.varlena.com/GeneralBits/Tidbits/perf.html#less>random_page_cost</a>'),
|
||||
false
|
||||
);
|
||||
|
||||
function perf_postgres(&$conn)
|
||||
{
|
||||
$this->conn =& $conn;
|
||||
}
|
||||
|
||||
function Explain($sql,$partial=false)
|
||||
{
|
||||
$save = $this->conn->LogSQL(false);
|
||||
|
||||
if ($partial) {
|
||||
$sqlq = $this->conn->qstr($sql.'%');
|
||||
$arr = $this->conn->GetArray("select distinct distinct sql1 from adodb_logsql where sql1 like $sqlq");
|
||||
if ($arr) {
|
||||
foreach($arr as $row) {
|
||||
$sql = reset($row);
|
||||
if (crc32($sql) == $partial) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sql = str_replace('?',"''",$sql);
|
||||
$s = '<p><b>Explain</b>: '.htmlspecialchars($sql).'</p>';
|
||||
$rs = $this->conn->Execute('EXPLAIN '.$sql);
|
||||
$this->conn->LogSQL($save);
|
||||
$s .= '<pre>';
|
||||
if ($rs)
|
||||
while (!$rs->EOF) {
|
||||
$s .= reset($rs->fields)."\n";
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$s .= '</pre>';
|
||||
$s .= $this->Tracer($sql,$partial);
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
?>
|
118
phpgwapi/inc/adodb/session/adodb-compress-bzip2.php
Normal file
118
phpgwapi/inc/adodb/session/adodb-compress-bzip2.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
if (!function_exists('bzcompress')) {
|
||||
trigger_error('bzip2 functions are not available', E_USER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
class ADODB_Compress_Bzip2 {
|
||||
/**
|
||||
*/
|
||||
var $_block_size = null;
|
||||
|
||||
/**
|
||||
*/
|
||||
var $_work_level = null;
|
||||
|
||||
/**
|
||||
*/
|
||||
var $_min_length = 1;
|
||||
|
||||
/**
|
||||
*/
|
||||
function getBlockSize() {
|
||||
return $this->_block_size;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setBlockSize($block_size) {
|
||||
assert('$block_size >= 1');
|
||||
assert('$block_size <= 9');
|
||||
$this->_block_size = (int) $block_size;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function getWorkLevel() {
|
||||
return $this->_work_level;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setWorkLevel($work_level) {
|
||||
assert('$work_level >= 0');
|
||||
assert('$work_level <= 250');
|
||||
$this->_work_level = (int) $work_level;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function getMinLength() {
|
||||
return $this->_min_length;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setMinLength($min_length) {
|
||||
assert('$min_length >= 0');
|
||||
$this->_min_length = (int) $min_length;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function ADODB_Compress_Bzip2($block_size = null, $work_level = null, $min_length = null) {
|
||||
if (!is_null($block_size)) {
|
||||
$this->setBlockSize($block_size);
|
||||
}
|
||||
|
||||
if (!is_null($work_level)) {
|
||||
$this->setWorkLevel($work_level);
|
||||
}
|
||||
|
||||
if (!is_null($min_length)) {
|
||||
$this->setMinLength($min_length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function write($data, $key) {
|
||||
if (strlen($data) < $this->_min_length) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (!is_null($this->_block_size)) {
|
||||
if (!is_null($this->_work_level)) {
|
||||
return bzcompress($data, $this->_block_size, $this->_work_level);
|
||||
} else {
|
||||
return bzcompress($data, $this->_block_size);
|
||||
}
|
||||
}
|
||||
|
||||
return bzcompress($data);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function read($data, $key) {
|
||||
return $data ? bzdecompress($data) : $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
?>
|
93
phpgwapi/inc/adodb/session/adodb-compress-gzip.php
Normal file
93
phpgwapi/inc/adodb/session/adodb-compress-gzip.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
if (!function_exists('gzcompress')) {
|
||||
trigger_error('gzip functions are not available', E_USER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
class ADODB_Compress_Gzip {
|
||||
/**
|
||||
*/
|
||||
var $_level = null;
|
||||
|
||||
/**
|
||||
*/
|
||||
var $_min_length = 1;
|
||||
|
||||
/**
|
||||
*/
|
||||
function getLevel() {
|
||||
return $this->_level;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setLevel($level) {
|
||||
assert('$level >= 0');
|
||||
assert('$level <= 9');
|
||||
$this->_level = (int) $level;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function getMinLength() {
|
||||
return $this->_min_length;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setMinLength($min_length) {
|
||||
assert('$min_length >= 0');
|
||||
$this->_min_length = (int) $min_length;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function ADODB_Compress_Gzip($level = null, $min_length = null) {
|
||||
if (!is_null($level)) {
|
||||
$this->setLevel($level);
|
||||
}
|
||||
|
||||
if (!is_null($min_length)) {
|
||||
$this->setMinLength($min_length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function write($data, $key) {
|
||||
if (strlen($data) < $this->_min_length) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (!is_null($this->_level)) {
|
||||
return gzcompress($data, $this->_level);
|
||||
} else {
|
||||
return gzcompress($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function read($data, $key) {
|
||||
return $data ? gzuncompress($data) : $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
?>
|
24
phpgwapi/inc/adodb/session/adodb-cryptsession.php
Normal file
24
phpgwapi/inc/adodb/session/adodb-cryptsession.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is provided for backwards compatibility purposes
|
||||
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/adodb-session.php';
|
||||
require_once ADODB_SESSION . '/adodb-encrypt-md5.php';
|
||||
|
||||
ADODB_Session::filter(new ADODB_Encrypt_MD5());
|
||||
|
||||
?>
|
109
phpgwapi/inc/adodb/session/adodb-encrypt-mcrypt.php
Normal file
109
phpgwapi/inc/adodb/session/adodb-encrypt-mcrypt.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
if (!function_exists('mcrypt_encrypt')) {
|
||||
trigger_error('Mcrypt functions are not available', E_USER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
class ADODB_Encrypt_MCrypt {
|
||||
/**
|
||||
*/
|
||||
var $_cipher;
|
||||
|
||||
/**
|
||||
*/
|
||||
var $_mode;
|
||||
|
||||
/**
|
||||
*/
|
||||
var $_source;
|
||||
|
||||
/**
|
||||
*/
|
||||
function getCipher() {
|
||||
return $this->_cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setCipher($cipher) {
|
||||
$this->_cipher = $cipher;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function getMode() {
|
||||
return $this->_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setMode($mode) {
|
||||
$this->_mode = $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function getSource() {
|
||||
return $this->_source;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function setSource($source) {
|
||||
$this->_source = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function ADODB_Encrypt_MCrypt($cipher = null, $mode = null, $source = null) {
|
||||
if (!$cipher) {
|
||||
$cipher = MCRYPT_RIJNDAEL_256;
|
||||
}
|
||||
if (!$mode) {
|
||||
$mode = MCRYPT_MODE_ECB;
|
||||
}
|
||||
if (!$source) {
|
||||
$source = MCRYPT_RAND;
|
||||
}
|
||||
|
||||
$this->_cipher = $cipher;
|
||||
$this->_mode = $mode;
|
||||
$this->_source = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function write($data, $key) {
|
||||
$iv_size = mcrypt_get_iv_size($this->_cipher, $this->_mode);
|
||||
$iv = mcrypt_create_iv($iv_size, $this->_source);
|
||||
return mcrypt_encrypt($this->_cipher, $key, $data, $this->_mode, $iv);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function read($data, $key) {
|
||||
$iv_size = mcrypt_get_iv_size($this->_cipher, $this->_mode);
|
||||
$iv = mcrypt_create_iv($iv_size, $this->_source);
|
||||
$rv = mcrypt_decrypt($this->_cipher, $key, $data, $this->_mode, $iv);
|
||||
return rtrim($rv, "\0");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
?>
|
39
phpgwapi/inc/adodb/session/adodb-encrypt-md5.php
Normal file
39
phpgwapi/inc/adodb/session/adodb-encrypt-md5.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
// security - hide paths
|
||||
if (!defined('ADODB_SESSION')) die();
|
||||
|
||||
include_once ADODB_SESSION . '/crypt.inc.php';
|
||||
|
||||
/**
|
||||
*/
|
||||
class ADODB_Encrypt_MD5 {
|
||||
/**
|
||||
*/
|
||||
function write($data, $key) {
|
||||
$md5crypt =& new MD5Crypt();
|
||||
return $md5crypt->encrypt($data, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function read($data, $key) {
|
||||
$md5crypt =& new MD5Crypt();
|
||||
return $md5crypt->decrypt($data, $key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
?>
|
48
phpgwapi/inc/adodb/session/adodb-encrypt-secret.php
Normal file
48
phpgwapi/inc/adodb/session/adodb-encrypt-secret.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
@define('HORDE_BASE', dirname(dirname(dirname(__FILE__))) . '/horde');
|
||||
|
||||
if (!is_dir(HORDE_BASE)) {
|
||||
trigger_error(sprintf('Directory not found: \'%s\'', HORDE_BASE), E_USER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
include_once HORDE_BASE . '/lib/Horde.php';
|
||||
include_once HORDE_BASE . '/lib/Secret.php';
|
||||
|
||||
/**
|
||||
|
||||
NOTE: On Windows 2000 SP4 with PHP 4.3.1, MCrypt 2.4.x, and Apache 1.3.28,
|
||||
the session didn't work properly.
|
||||
|
||||
This may be resolved with 4.3.3.
|
||||
|
||||
*/
|
||||
class ADODB_Encrypt_Secret {
|
||||
/**
|
||||
*/
|
||||
function write($data, $key) {
|
||||
return Secret::write($key, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function read($data, $key) {
|
||||
return Secret::read($key, $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
?>
|
23
phpgwapi/inc/adodb/session/adodb-session-clob.php
Normal file
23
phpgwapi/inc/adodb/session/adodb-session-clob.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is provided for backwards compatibility purposes
|
||||
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/adodb-session.php';
|
||||
|
||||
ADODB_Session::clob('CLOB');
|
||||
|
||||
?>
|
817
phpgwapi/inc/adodb/session/adodb-session.php
Normal file
817
phpgwapi/inc/adodb/session/adodb-session.php
Normal file
@ -0,0 +1,817 @@
|
||||
<?php
|
||||
|
||||
|
||||
/*
|
||||
V4.01 23 Oct 2003 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Contributed by Ross Smith (adodb@netebb.com).
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
*/
|
||||
|
||||
/*
|
||||
You may want to rename the 'data' field to 'session_data' as
|
||||
'data' appears to be a reserved word for one or more of the following:
|
||||
ANSI SQL
|
||||
IBM DB2
|
||||
MS SQL Server
|
||||
Postgres
|
||||
SAP
|
||||
|
||||
If you do, then execute:
|
||||
|
||||
ADODB_Session::dataFieldName('session_data');
|
||||
|
||||
*/
|
||||
|
||||
if (!defined('_ADODB_LAYER')) {
|
||||
require_once realpath(dirname(__FILE__) . '/../adodb.inc.php');
|
||||
}
|
||||
|
||||
if (defined('ADODB_SESSION')) return 1;
|
||||
|
||||
define('ADODB_SESSION', dirname(__FILE__));
|
||||
|
||||
/*!
|
||||
\static
|
||||
*/
|
||||
class ADODB_Session {
|
||||
/////////////////////
|
||||
// getter/setter methods
|
||||
/////////////////////
|
||||
|
||||
/*!
|
||||
*/
|
||||
function driver($driver = null) {
|
||||
static $_driver = 'mysql';
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($driver)) {
|
||||
$_driver = trim($driver);
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_DRIVER'])) {
|
||||
return $GLOBALS['ADODB_SESSION_DRIVER'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_driver;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function host($host = null) {
|
||||
static $_host = 'localhost';
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($host)) {
|
||||
$_host = trim($host);
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_CONNECT'])) {
|
||||
return $GLOBALS['ADODB_SESSION_CONNECT'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_host;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function user($user = null) {
|
||||
static $_user = 'root';
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($user)) {
|
||||
$_user = trim($user);
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_USER'])) {
|
||||
return $GLOBALS['ADODB_SESSION_USER'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_user;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function password($password = null) {
|
||||
static $_password = '';
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($password)) {
|
||||
$_password = $password;
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_PWD'])) {
|
||||
return $GLOBALS['ADODB_SESSION_PWD'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_password;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function database($database = null) {
|
||||
static $_database = 'xphplens_2';
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($database)) {
|
||||
$_database = trim($database);
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_DB'])) {
|
||||
return $GLOBALS['ADODB_SESSION_DB'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_database;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function persist($persist = null) {
|
||||
static $_persist = true;
|
||||
|
||||
if (!is_null($persist)) {
|
||||
$_persist = trim($persist);
|
||||
}
|
||||
|
||||
return $_persist;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function lifetime($lifetime = null) {
|
||||
static $_lifetime;
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($lifetime)) {
|
||||
$_lifetime = (int) $lifetime;
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESS_LIFE'])) {
|
||||
return $GLOBALS['ADODB_SESS_LIFE'];
|
||||
}
|
||||
}
|
||||
if (!$_lifetime) {
|
||||
$_lifetime = ini_get('session.gc_maxlifetime');
|
||||
if ($_lifetime <= 1) {
|
||||
// bug in PHP 4.0.3 pl 1 -- how about other versions?
|
||||
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $lifetime</h3>";
|
||||
$_lifetime = 1440;
|
||||
}
|
||||
}
|
||||
|
||||
return $_lifetime;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function debug($debug = null) {
|
||||
static $_debug = false;
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($debug)) {
|
||||
$_debug = (bool) $debug;
|
||||
|
||||
$conn = ADODB_Session::_conn();
|
||||
if ($conn) {
|
||||
$conn->debug = $_debug;
|
||||
}
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESS_DEBUG'])) {
|
||||
return $GLOBALS['ADODB_SESS_DEBUG'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_debug;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function expireNotify($expire_notify = null) {
|
||||
static $_expire_notify;
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($expire_notify)) {
|
||||
$_expire_notify = $expire_notify;
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'])) {
|
||||
return $GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_expire_notify;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function table($table = null) {
|
||||
static $_table = 'sessions';
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($table)) {
|
||||
$_table = trim($table);
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_TBL'])) {
|
||||
return $GLOBALS['ADODB_SESSION_TBL'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_table;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function optimize($optimize = null) {
|
||||
static $_optimize = false;
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($optimize)) {
|
||||
$_optimize = (bool) $optimize;
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (defined('ADODB_SESSION_OPTIMIZE')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return $_optimize;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function syncSeconds($sync_seconds = null) {
|
||||
static $_sync_seconds = 60;
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($sync_seconds)) {
|
||||
$_sync_seconds = (int) $sync_seconds;
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (defined('ADODB_SESSION_SYNCH_SECS')) {
|
||||
return ADODB_SESSION_SYNCH_SECS;
|
||||
}
|
||||
}
|
||||
|
||||
return $_sync_seconds;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function clob($clob = null) {
|
||||
static $_clob = false;
|
||||
static $set = false;
|
||||
|
||||
if (!is_null($clob)) {
|
||||
$_clob = strtolower(trim($clob));
|
||||
$set = true;
|
||||
} elseif (!$set) {
|
||||
// backwards compatibility
|
||||
if (isset($GLOBALS['ADODB_SESSION_USE_LOBS'])) {
|
||||
return $GLOBALS['ADODB_SESSION_USE_LOBS'];
|
||||
}
|
||||
}
|
||||
|
||||
return $_clob;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function dataFieldName($data_field_name = null) {
|
||||
static $_data_field_name = 'data';
|
||||
|
||||
if (!is_null($data_field_name)) {
|
||||
$_data_field_name = trim($data_field_name);
|
||||
}
|
||||
|
||||
return $_data_field_name;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function filter($filter = null) {
|
||||
static $_filter = array();
|
||||
|
||||
if (!is_null($filter)) {
|
||||
if (!is_array($filter)) {
|
||||
$filter = array($filter);
|
||||
}
|
||||
$_filter = $filter;
|
||||
}
|
||||
|
||||
return $_filter;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function encryptionKey($encryption_key = null) {
|
||||
static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
|
||||
|
||||
if (!is_null($encryption_key)) {
|
||||
$_encryption_key = $encryption_key;
|
||||
}
|
||||
|
||||
return $_encryption_key;
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// private methods
|
||||
/////////////////////
|
||||
|
||||
/*!
|
||||
*/
|
||||
function &_conn($conn=null) {
|
||||
return $GLOBALS['ADODB_SESS_CONN'];
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function _crc($crc = null) {
|
||||
static $_crc = false;
|
||||
|
||||
if (!is_null($crc)) {
|
||||
$_crc = $crc;
|
||||
}
|
||||
|
||||
return $_crc;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function _init() {
|
||||
session_module_name('user');
|
||||
session_set_save_handler(
|
||||
array('ADODB_Session', 'open'),
|
||||
array('ADODB_Session', 'close'),
|
||||
array('ADODB_Session', 'read'),
|
||||
array('ADODB_Session', 'write'),
|
||||
array('ADODB_Session', 'destroy'),
|
||||
array('ADODB_Session', 'gc')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
*/
|
||||
function _sessionKey() {
|
||||
// use this function to create the encryption key for crypted sessions
|
||||
// crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt
|
||||
return crypt(ADODB_Session::encryptionKey(), session_id());
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function _dumprs($rs) {
|
||||
$conn =& ADODB_Session::_conn();
|
||||
$debug = ADODB_Session::debug();
|
||||
|
||||
if (!$conn) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$debug) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$rs) {
|
||||
echo "<br />\$rs is null or false<br />\n";
|
||||
return;
|
||||
}
|
||||
|
||||
//echo "<br />\nAffected_Rows=",$conn->Affected_Rows(),"<br />\n";
|
||||
|
||||
if (!is_object($rs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
require_once ADODB_SESSION.'/../tohtml.inc.php';
|
||||
rs2html($rs);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// public methods
|
||||
/////////////////////
|
||||
|
||||
/*!
|
||||
Create the connection to the database.
|
||||
|
||||
If $conn already exists, reuse that connection
|
||||
*/
|
||||
function open($save_path, $session_name, $persist = null) {
|
||||
$conn =& ADODB_Session::_conn();
|
||||
|
||||
if ($conn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$database = ADODB_Session::database();
|
||||
$debug = ADODB_Session::debug();
|
||||
$driver = ADODB_Session::driver();
|
||||
$host = ADODB_Session::host();
|
||||
$password = ADODB_Session::password();
|
||||
$user = ADODB_Session::user();
|
||||
|
||||
if (!is_null($persist)) {
|
||||
$persist = (bool) $persist;
|
||||
ADODB_Session::persist($persist);
|
||||
} else {
|
||||
$persist = ADODB_Session::persist();
|
||||
}
|
||||
|
||||
# these can all be defaulted to in php.ini
|
||||
# assert('$database');
|
||||
# assert('$driver');
|
||||
# assert('$host');
|
||||
|
||||
// cannot use =& below - do not know why...
|
||||
$conn = ADONewConnection($driver);
|
||||
|
||||
if ($debug) {
|
||||
$conn->debug = true;
|
||||
// ADOConnection::outp( " driver=$driver user=$user pwd=$password db=$database ");
|
||||
}
|
||||
|
||||
if ($persist) {
|
||||
$ok = $conn->PConnect($host, $user, $password, $database);
|
||||
} else {
|
||||
$ok = $conn->Connect($host, $user, $password, $database);
|
||||
}
|
||||
|
||||
if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
|
||||
else
|
||||
ADOConnection::outp('<p>Session: connection failed</p>', false);
|
||||
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/*!
|
||||
Close the connection
|
||||
*/
|
||||
function close() {
|
||||
$conn =& ADODB_Session::_conn();
|
||||
|
||||
if ($conn) {
|
||||
$conn->Close();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Slurp in the session variables and return the serialized string
|
||||
*/
|
||||
function read($key) {
|
||||
$conn =& ADODB_Session::_conn();
|
||||
$data = ADODB_Session::dataFieldName();
|
||||
$filter = ADODB_Session::filter();
|
||||
$table = ADODB_Session::table();
|
||||
|
||||
if (!$conn) {
|
||||
return '';
|
||||
}
|
||||
|
||||
assert('$table');
|
||||
|
||||
$qkey = $conn->quote($key);
|
||||
$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
|
||||
|
||||
$sql = "SELECT $data FROM $table WHERE $binary sesskey = $qkey AND expiry >= " . time();
|
||||
$rs =& $conn->Execute($sql);
|
||||
//ADODB_Session::_dumprs($rs);
|
||||
if ($rs) {
|
||||
if ($rs->EOF) {
|
||||
$v = '';
|
||||
} else {
|
||||
$v = reset($rs->fields);
|
||||
$filter = array_reverse($filter);
|
||||
foreach ($filter as $f) {
|
||||
if (is_object($f)) {
|
||||
$v = $f->read($v, ADODB_Session::_sessionKey());
|
||||
}
|
||||
}
|
||||
$v = rawurldecode($v);
|
||||
}
|
||||
|
||||
$rs->Close();
|
||||
|
||||
ADODB_Session::_crc(strlen($v) . crc32($v));
|
||||
return $v;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/*!
|
||||
Write the serialized data to a database.
|
||||
|
||||
If the data has not been modified since the last read(), we do not write.
|
||||
*/
|
||||
function write($key, $val) {
|
||||
$clob = ADODB_Session::clob();
|
||||
$conn =& ADODB_Session::_conn();
|
||||
$crc = ADODB_Session::_crc();
|
||||
$data = ADODB_Session::dataFieldName();
|
||||
$debug = ADODB_Session::debug();
|
||||
$driver = ADODB_Session::driver();
|
||||
$expire_notify = ADODB_Session::expireNotify();
|
||||
$filter = ADODB_Session::filter();
|
||||
$lifetime = ADODB_Session::lifetime();
|
||||
$table = ADODB_Session::table();
|
||||
|
||||
if (!$conn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert('$table');
|
||||
|
||||
$expiry = time() + $lifetime;
|
||||
|
||||
$qkey = $conn->quote($key);
|
||||
$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
|
||||
|
||||
// crc32 optimization since adodb 2.1
|
||||
// now we only update expiry date, thx to sebastian thom in adodb 2.32
|
||||
if ($crc !== false && $crc == (strlen($val) . crc32($val))) {
|
||||
if ($debug) {
|
||||
echo '<p>Session: Only updating date - crc32 not changed</p>';
|
||||
}
|
||||
$sql = "UPDATE $table SET expiry = $expiry WHERE $binary sesskey = $qkey AND expiry >= " . time();
|
||||
$rs =& $conn->Execute($sql);
|
||||
ADODB_Session::_dumprs($rs);
|
||||
if ($rs) {
|
||||
$rs->Close();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
$val = rawurlencode($val);
|
||||
foreach ($filter as $f) {
|
||||
if (is_object($f)) {
|
||||
$val = $f->write($val, ADODB_Session::_sessionKey());
|
||||
}
|
||||
}
|
||||
|
||||
$arr = array('sesskey' => $key, 'expiry' => $expiry, $data => $val, 'expireref' => '');
|
||||
if ($expire_notify) {
|
||||
$var = reset($expire_notify);
|
||||
global $$var;
|
||||
if (isset($$var)) {
|
||||
$arr['expireref'] = $$var;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$clob) { // no lobs, simply use replace()
|
||||
$arr[$data] = $conn->qstr($val);
|
||||
$rs = $conn->Replace($table, $arr, 'sesskey', $autoQuote = true);
|
||||
ADODB_Session::_dumprs($rs);
|
||||
} else {
|
||||
// what value shall we insert/update for lob row?
|
||||
switch ($driver) {
|
||||
// empty_clob or empty_lob for oracle dbs
|
||||
case 'oracle':
|
||||
case 'oci8':
|
||||
case 'oci8po':
|
||||
case 'oci805':
|
||||
$lob_value = sprintf('empty_%s()', strtolower($clob));
|
||||
break;
|
||||
|
||||
// null for all other
|
||||
default:
|
||||
$lob_value = 'null';
|
||||
break;
|
||||
}
|
||||
|
||||
// do we insert or update? => as for sesskey
|
||||
$rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = $qkey");
|
||||
ADODB_Session::_dumprs($rs);
|
||||
if ($rs && reset($rs->fields) > 0) {
|
||||
$sql = "UPDATE $table SET expiry = $expiry, $data = $lob_value WHERE sesskey = $qkey";
|
||||
} else {
|
||||
$sql = "INSERT INTO $table (expiry, $data, sesskey) VALUES ($expiry, $lob_value, $qkey)";
|
||||
}
|
||||
if ($rs) {
|
||||
$rs->Close();
|
||||
}
|
||||
|
||||
$err = '';
|
||||
$rs1 =& $conn->Execute($sql);
|
||||
ADODB_Session::_dumprs($rs1);
|
||||
if (!$rs1) {
|
||||
$err = $conn->ErrorMsg()."\n";
|
||||
}
|
||||
$rs2 =& $conn->UpdateBlob($table, $data, $val, " sesskey=$qkey", strtoupper($clob));
|
||||
ADODB_Session::_dumprs($rs2);
|
||||
if (!$rs2) {
|
||||
$err .= $conn->ErrorMsg()."\n";
|
||||
}
|
||||
$rs = ($rs && $rs2) ? true : false;
|
||||
if ($rs1) {
|
||||
$rs1->Close();
|
||||
}
|
||||
if (is_object($rs2)) {
|
||||
$rs2->Close();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$rs) {
|
||||
ADOConnection::outp('<p>Session Replace: ' . $conn->ErrorMsg() . '</p>', false);
|
||||
return false;
|
||||
} else {
|
||||
// bug in access driver (could be odbc?) means that info is not committed
|
||||
// properly unless select statement executed in Win2000
|
||||
if ($conn->databaseType == 'access') {
|
||||
$sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
|
||||
$rs =& $conn->Execute($sql);
|
||||
ADODB_Session::_dumprs($rs);
|
||||
if ($rs) {
|
||||
$rs->Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $rs ? true : false;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function destroy($key) {
|
||||
$conn =& ADODB_Session::_conn();
|
||||
$table = ADODB_Session::table();
|
||||
$expire_notify = ADODB_Session::expireNotify();
|
||||
|
||||
if (!$conn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert('$table');
|
||||
|
||||
$qkey = $conn->quote($key);
|
||||
$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
|
||||
|
||||
if ($expire_notify) {
|
||||
reset($expire_notify);
|
||||
$fn = next($expire_notify);
|
||||
$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
|
||||
$rs =& $conn->Execute($sql);
|
||||
ADODB_Session::_dumprs($rs);
|
||||
$conn->SetFetchMode($savem);
|
||||
if (!$rs) {
|
||||
return false;
|
||||
}
|
||||
if (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
//assert('$ref');
|
||||
//assert('$key');
|
||||
$fn($ref, $key);
|
||||
}
|
||||
$rs->Close();
|
||||
}
|
||||
|
||||
$sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
|
||||
$rs =& $conn->Execute($sql);
|
||||
ADODB_Session::_dumprs($rs);
|
||||
if ($rs) {
|
||||
$rs->Close();
|
||||
}
|
||||
|
||||
return $rs ? true : false;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
function gc($maxlifetime) {
|
||||
$conn =& ADODB_Session::_conn();
|
||||
$debug = ADODB_Session::debug();
|
||||
$expire_notify = ADODB_Session::expireNotify();
|
||||
$optimize = ADODB_Session::optimize();
|
||||
$sync_seconds = ADODB_Session::syncSeconds();
|
||||
$table = ADODB_Session::table();
|
||||
|
||||
if (!$conn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert('$table');
|
||||
|
||||
$time = time();
|
||||
|
||||
$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
|
||||
|
||||
if ($expire_notify) {
|
||||
reset($expire_notify);
|
||||
$fn = next($expire_notify);
|
||||
$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time";
|
||||
$rs =& $conn->Execute($sql);
|
||||
ADODB_Session::_dumprs($rs);
|
||||
$conn->SetFetchMode($savem);
|
||||
if ($rs) {
|
||||
$conn->BeginTrans();
|
||||
$keys = array();
|
||||
while (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
$fn($ref, $key);
|
||||
$del = $conn->Execute("DELETE FROM $table WHERE sesskey='$key'");
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
$conn->CommitTrans();
|
||||
}
|
||||
} else {
|
||||
$sql = "DELETE FROM $table WHERE expiry < $time";
|
||||
$rs =& $conn->Execute($sql);
|
||||
ADODB_Session::_dumprs($rs);
|
||||
if ($rs) {
|
||||
$rs->Close();
|
||||
}
|
||||
if ($debug) {
|
||||
ADOConnection::outp("<p><b>Garbage Collection</b>: $sql</p>");
|
||||
}
|
||||
}
|
||||
|
||||
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
|
||||
if ($optimize) {
|
||||
$driver = ADODB_Session::driver();
|
||||
|
||||
if (preg_match('/mysql/i', $driver)) {
|
||||
$sql = "OPTIMIZE TABLE $table";
|
||||
}
|
||||
if (preg_match('/postgres/i', $driver)) {
|
||||
$sql = "VACUUM $table";
|
||||
}
|
||||
if (!empty($sql)) {
|
||||
$conn->Execute($sql);
|
||||
}
|
||||
}
|
||||
|
||||
if ($sync_seconds) {
|
||||
$sql = 'SELECT ';
|
||||
if ($conn->dataProvider === 'oci8') {
|
||||
$sql .= "TO_CHAR({$conn->sysTimeStamp}, 'RRRR-MM-DD HH24:MI:SS')";
|
||||
} else {
|
||||
$sql .= $conn->sysTimeStamp;
|
||||
}
|
||||
$sql .= " FROM $table";
|
||||
|
||||
$rs =& $conn->SelectLimit($sql, 1);
|
||||
if ($rs && !$rs->EOF) {
|
||||
$dbts = reset($rs->fields);
|
||||
$rs->Close();
|
||||
$dbt = $conn->UnixTimeStamp($dbts);
|
||||
$t = time();
|
||||
|
||||
if (abs($dbt - $t) >= $sync_seconds) {
|
||||
global $HTTP_SERVER_VARS;
|
||||
$msg = __FILE__ .
|
||||
": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: " .
|
||||
" database=$dbt ($dbts), webserver=$t (diff=". (abs($dbt - $t) / 3600) . ' hours)';
|
||||
error_log($msg);
|
||||
if ($debug) {
|
||||
ADOConnection::outp("<p>$msg</p>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ADODB_Session::_init();
|
||||
|
||||
|
||||
// for backwards compatability only
|
||||
function adodb_sess_open($save_path, $session_name, $persist = true) {
|
||||
return ADODB_Session::open($save_path, $session_name, $persist);
|
||||
}
|
||||
|
||||
// for backwards compatability only
|
||||
function adodb_sess_gc($t)
|
||||
{
|
||||
return ADODB_Session::gc($t);
|
||||
}
|
||||
|
||||
?>
|
321
phpgwapi/inc/adodb/session/old/adodb-cryptsession.php
Normal file
321
phpgwapi/inc/adodb/session/old/adodb-cryptsession.php
Normal file
@ -0,0 +1,321 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Made table name configurable - by David Johnson djohnson@inpro.net
|
||||
Encryption by Ari Kuorikoski <ari.kuorikoski@finebyte.com>
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version of ADODB is available at http://php.weblogs.com/adodb
|
||||
======================================================================
|
||||
|
||||
This file provides PHP4 session management using the ADODB database
|
||||
wrapper library.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
include('adodb.inc.php');
|
||||
#---------------------------------#
|
||||
include('adodb-cryptsession.php');
|
||||
#---------------------------------#
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
1. Create a new database in MySQL or Access "sessions" like
|
||||
so:
|
||||
|
||||
create table sessions (
|
||||
SESSKEY char(32) not null,
|
||||
EXPIRY int(11) unsigned not null,
|
||||
EXPIREREF varchar(64),
|
||||
DATA CLOB,
|
||||
primary key (sesskey)
|
||||
);
|
||||
|
||||
2. Then define the following parameters. You can either modify
|
||||
this file, or define them before this file is included:
|
||||
|
||||
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
|
||||
$ADODB_SESSION_CONNECT='server to connect to';
|
||||
$ADODB_SESSION_USER ='user';
|
||||
$ADODB_SESSION_PWD ='password';
|
||||
$ADODB_SESSION_DB ='database';
|
||||
$ADODB_SESSION_TBL = 'sessions'
|
||||
|
||||
3. Recommended is PHP 4.0.2 or later. There are documented
|
||||
session bugs in earlier versions of PHP.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
include_once('crypt.inc.php');
|
||||
|
||||
if (!defined('_ADODB_LAYER')) {
|
||||
include (dirname(__FILE__).'/adodb.inc.php');
|
||||
}
|
||||
|
||||
/* if database time and system time is difference is greater than this, then give warning */
|
||||
define('ADODB_SESSION_SYNCH_SECS',60);
|
||||
|
||||
if (!defined('ADODB_SESSION')) {
|
||||
|
||||
define('ADODB_SESSION',1);
|
||||
|
||||
GLOBAL $ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_DRIVER,
|
||||
$ADODB_SESSION_USER,
|
||||
$ADODB_SESSION_PWD,
|
||||
$ADODB_SESSION_DB,
|
||||
$ADODB_SESS_CONN,
|
||||
$ADODB_SESS_LIFE,
|
||||
$ADODB_SESS_DEBUG,
|
||||
$ADODB_SESS_INSERT,
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY,
|
||||
$ADODB_SESSION_TBL;
|
||||
|
||||
//$ADODB_SESS_DEBUG = true;
|
||||
|
||||
/* SET THE FOLLOWING PARAMETERS */
|
||||
if (empty($ADODB_SESSION_DRIVER)) {
|
||||
$ADODB_SESSION_DRIVER='mysql';
|
||||
$ADODB_SESSION_CONNECT='localhost';
|
||||
$ADODB_SESSION_USER ='root';
|
||||
$ADODB_SESSION_PWD ='';
|
||||
$ADODB_SESSION_DB ='xphplens_2';
|
||||
}
|
||||
|
||||
if (empty($ADODB_SESSION_TBL)){
|
||||
$ADODB_SESSION_TBL = 'sessions';
|
||||
}
|
||||
|
||||
if (empty($ADODB_SESSION_EXPIRE_NOTIFY)) {
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY = false;
|
||||
}
|
||||
|
||||
function ADODB_Session_Key()
|
||||
{
|
||||
$ADODB_CRYPT_KEY = 'CRYPTED ADODB SESSIONS ROCK!';
|
||||
|
||||
/* USE THIS FUNCTION TO CREATE THE ENCRYPTION KEY FOR CRYPTED SESSIONS */
|
||||
/* Crypt the used key, $ADODB_CRYPT_KEY as key and session_ID as SALT */
|
||||
return crypt($ADODB_CRYPT_KEY, session_ID());
|
||||
}
|
||||
|
||||
$ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
|
||||
if ($ADODB_SESS_LIFE <= 1) {
|
||||
// bug in PHP 4.0.3 pl 1 -- how about other versions?
|
||||
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $ADODB_SESS_LIFE</h3>";
|
||||
$ADODB_SESS_LIFE=1440;
|
||||
}
|
||||
|
||||
function adodb_sess_open($save_path, $session_name)
|
||||
{
|
||||
GLOBAL $ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_DRIVER,
|
||||
$ADODB_SESSION_USER,
|
||||
$ADODB_SESSION_PWD,
|
||||
$ADODB_SESSION_DB,
|
||||
$ADODB_SESS_CONN,
|
||||
$ADODB_SESS_DEBUG;
|
||||
|
||||
$ADODB_SESS_INSERT = false;
|
||||
|
||||
if (isset($ADODB_SESS_CONN)) return true;
|
||||
|
||||
$ADODB_SESS_CONN = ADONewConnection($ADODB_SESSION_DRIVER);
|
||||
if (!empty($ADODB_SESS_DEBUG)) {
|
||||
$ADODB_SESS_CONN->debug = true;
|
||||
print" conn=$ADODB_SESSION_CONNECT user=$ADODB_SESSION_USER pwd=$ADODB_SESSION_PWD db=$ADODB_SESSION_DB ";
|
||||
}
|
||||
return $ADODB_SESS_CONN->PConnect($ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
|
||||
|
||||
}
|
||||
|
||||
function adodb_sess_close()
|
||||
{
|
||||
global $ADODB_SESS_CONN;
|
||||
|
||||
if ($ADODB_SESS_CONN) $ADODB_SESS_CONN->Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
function adodb_sess_read($key)
|
||||
{
|
||||
$Crypt = new MD5Crypt;
|
||||
global $ADODB_SESS_CONN,$ADODB_SESS_INSERT,$ADODB_SESSION_TBL;
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT data FROM $ADODB_SESSION_TBL WHERE sesskey = '$key' AND expiry >= " . time());
|
||||
if ($rs) {
|
||||
if ($rs->EOF) {
|
||||
$ADODB_SESS_INSERT = true;
|
||||
$v = '';
|
||||
} else {
|
||||
// Decrypt session data
|
||||
$v = rawurldecode($Crypt->Decrypt(reset($rs->fields), ADODB_Session_Key()));
|
||||
}
|
||||
$rs->Close();
|
||||
return $v;
|
||||
}
|
||||
else $ADODB_SESS_INSERT = true;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function adodb_sess_write($key, $val)
|
||||
{
|
||||
$Crypt = new MD5Crypt;
|
||||
global $ADODB_SESS_INSERT,$ADODB_SESS_CONN, $ADODB_SESS_LIFE, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
|
||||
|
||||
$expiry = time() + $ADODB_SESS_LIFE;
|
||||
|
||||
// encrypt session data..
|
||||
$val = $Crypt->Encrypt(rawurlencode($val), ADODB_Session_Key());
|
||||
|
||||
$arr = array('sesskey' => $key, 'expiry' => $expiry, 'data' => $val);
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
$var = reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
global $$var;
|
||||
$arr['expireref'] = $$var;
|
||||
}
|
||||
$rs = $ADODB_SESS_CONN->Replace($ADODB_SESSION_TBL,
|
||||
$arr,
|
||||
'sesskey',$autoQuote = true);
|
||||
|
||||
if (!$rs) {
|
||||
ADOConnection::outp( '<p>Session Replace: '.$ADODB_SESS_CONN->ErrorMsg().'</p>',false);
|
||||
} else {
|
||||
// bug in access driver (could be odbc?) means that info is not commited
|
||||
// properly unless select statement executed in Win2000
|
||||
|
||||
if ($ADODB_SESS_CONN->databaseType == 'access') $rs = $ADODB_SESS_CONN->Execute("select sesskey from $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
}
|
||||
return isset($rs);
|
||||
}
|
||||
|
||||
function adodb_sess_destroy($key)
|
||||
{
|
||||
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
|
||||
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$ADODB_SESS_CONN->SetFetchMode($savem);
|
||||
if ($rs) {
|
||||
$ADODB_SESS_CONN->BeginTrans();
|
||||
while (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
$fn($ref,$key);
|
||||
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$ADODB_SESS_CONN->CommitTrans();
|
||||
}
|
||||
} else {
|
||||
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE sesskey = '$key'";
|
||||
$rs = $ADODB_SESS_CONN->Execute($qry);
|
||||
}
|
||||
return $rs ? true : false;
|
||||
}
|
||||
|
||||
|
||||
function adodb_sess_gc($maxlifetime) {
|
||||
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY,$ADODB_SESS_DEBUG;
|
||||
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$t = time();
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
|
||||
$ADODB_SESS_CONN->SetFetchMode($savem);
|
||||
if ($rs) {
|
||||
$ADODB_SESS_CONN->BeginTrans();
|
||||
while (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
$fn($ref,$key);
|
||||
//$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
$ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < $t");
|
||||
$ADODB_SESS_CONN->CommitTrans();
|
||||
}
|
||||
} else {
|
||||
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time();
|
||||
$ADODB_SESS_CONN->Execute($qry);
|
||||
}
|
||||
|
||||
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
|
||||
if (defined('ADODB_SESSION_OPTIMIZE'))
|
||||
{
|
||||
switch( $ADODB_SESSION_DRIVER ) {
|
||||
case 'mysql':
|
||||
case 'mysqlt':
|
||||
$opt_qry = 'OPTIMIZE TABLE '.$ADODB_SESSION_TBL;
|
||||
break;
|
||||
case 'postgresql':
|
||||
case 'postgresql7':
|
||||
$opt_qry = 'VACUUM '.$ADODB_SESSION_TBL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
|
||||
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
|
||||
|
||||
$rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
|
||||
if ($rs && !$rs->EOF) {
|
||||
|
||||
$dbts = reset($rs->fields);
|
||||
$rs->Close();
|
||||
$dbt = $ADODB_SESS_CONN->UnixTimeStamp($dbts);
|
||||
$t = time();
|
||||
if (abs($dbt - $t) >= ADODB_SESSION_SYNCH_SECS) {
|
||||
global $HTTP_SERVER_VARS;
|
||||
$msg =
|
||||
__FILE__.": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: database=$dbt ($dbts), webserver=$t (diff=".(abs($dbt-$t)/3600)." hrs)";
|
||||
error_log($msg);
|
||||
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p>$msg</p>");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
session_module_name('user');
|
||||
session_set_save_handler(
|
||||
"adodb_sess_open",
|
||||
"adodb_sess_close",
|
||||
"adodb_sess_read",
|
||||
"adodb_sess_write",
|
||||
"adodb_sess_destroy",
|
||||
"adodb_sess_gc");
|
||||
}
|
||||
|
||||
/* TEST SCRIPT -- UNCOMMENT */
|
||||
/*
|
||||
if (0) {
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
|
||||
}
|
||||
*/
|
||||
?>
|
444
phpgwapi/inc/adodb/session/old/adodb-session-clob.php
Normal file
444
phpgwapi/inc/adodb/session/old/adodb-session-clob.php
Normal file
@ -0,0 +1,444 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version of ADODB is available at http://php.weblogs.com/adodb
|
||||
======================================================================
|
||||
|
||||
This file provides PHP4 session management using the ADODB database
|
||||
wrapper library, using Oracle CLOB's to store data. Contributed by achim.gosse@ddd.de.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
include('adodb.inc.php');
|
||||
include('adodb-session.php');
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
|
||||
|
||||
To force non-persistent connections, call adodb_session_open first before session_start():
|
||||
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
include('adodb.inc.php');
|
||||
include('adodb-session.php');
|
||||
adodb_session_open(false,false,false);
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
1. Create this table in your database (syntax might vary depending on your db):
|
||||
|
||||
create table sessions (
|
||||
SESSKEY char(32) not null,
|
||||
EXPIRY int(11) unsigned not null,
|
||||
EXPIREREF varchar(64),
|
||||
DATA CLOB,
|
||||
primary key (sesskey)
|
||||
);
|
||||
|
||||
|
||||
2. Then define the following parameters in this file:
|
||||
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
|
||||
$ADODB_SESSION_CONNECT='server to connect to';
|
||||
$ADODB_SESSION_USER ='user';
|
||||
$ADODB_SESSION_PWD ='password';
|
||||
$ADODB_SESSION_DB ='database';
|
||||
$ADODB_SESSION_TBL = 'sessions'
|
||||
$ADODB_SESSION_USE_LOBS = false; (or, if you wanna use CLOBS (= 'CLOB') or ( = 'BLOB')
|
||||
|
||||
3. Recommended is PHP 4.0.6 or later. There are documented
|
||||
session bugs in earlier versions of PHP.
|
||||
|
||||
4. If you want to receive notifications when a session expires, then
|
||||
you can tag a session with an EXPIREREF, and before the session
|
||||
record is deleted, we can call a function that will pass the EXPIREREF
|
||||
as the first parameter, and the session key as the second parameter.
|
||||
|
||||
To do this, define a notification function, say NotifyFn:
|
||||
|
||||
function NotifyFn($expireref, $sesskey)
|
||||
{
|
||||
}
|
||||
|
||||
Then you need to define a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
|
||||
This is an array with 2 elements, the first being the name of the variable
|
||||
you would like to store in the EXPIREREF field, and the 2nd is the
|
||||
notification function's name.
|
||||
|
||||
In this example, we want to be notified when a user's session
|
||||
has expired, so we store the user id in the global variable $USERID,
|
||||
store this value in the EXPIREREF field:
|
||||
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
|
||||
|
||||
Then when the NotifyFn is called, we are passed the $USERID as the first
|
||||
parameter, eg. NotifyFn($userid, $sesskey).
|
||||
*/
|
||||
|
||||
if (!defined('_ADODB_LAYER')) {
|
||||
include (dirname(__FILE__).'/adodb.inc.php');
|
||||
}
|
||||
|
||||
if (!defined('ADODB_SESSION')) {
|
||||
|
||||
define('ADODB_SESSION',1);
|
||||
|
||||
/* if database time and system time is difference is greater than this, then give warning */
|
||||
define('ADODB_SESSION_SYNCH_SECS',60);
|
||||
|
||||
/****************************************************************************************\
|
||||
Global definitions
|
||||
\****************************************************************************************/
|
||||
GLOBAL $ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_DRIVER,
|
||||
$ADODB_SESSION_USER,
|
||||
$ADODB_SESSION_PWD,
|
||||
$ADODB_SESSION_DB,
|
||||
$ADODB_SESS_CONN,
|
||||
$ADODB_SESS_LIFE,
|
||||
$ADODB_SESS_DEBUG,
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY,
|
||||
$ADODB_SESSION_CRC,
|
||||
$ADODB_SESSION_USE_LOBS,
|
||||
$ADODB_SESSION_TBL;
|
||||
|
||||
if (!isset($ADODB_SESSION_USE_LOBS)) $ADODB_SESSION_USE_LOBS = 'CLOB';
|
||||
|
||||
$ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
|
||||
if ($ADODB_SESS_LIFE <= 1) {
|
||||
// bug in PHP 4.0.3 pl 1 -- how about other versions?
|
||||
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $ADODB_SESS_LIFE</h3>";
|
||||
$ADODB_SESS_LIFE=1440;
|
||||
}
|
||||
$ADODB_SESSION_CRC = false;
|
||||
//$ADODB_SESS_DEBUG = true;
|
||||
|
||||
//////////////////////////////////
|
||||
/* SET THE FOLLOWING PARAMETERS */
|
||||
//////////////////////////////////
|
||||
|
||||
if (empty($ADODB_SESSION_DRIVER)) {
|
||||
$ADODB_SESSION_DRIVER='mysql';
|
||||
$ADODB_SESSION_CONNECT='localhost';
|
||||
$ADODB_SESSION_USER ='root';
|
||||
$ADODB_SESSION_PWD ='';
|
||||
$ADODB_SESSION_DB ='xphplens_2';
|
||||
}
|
||||
|
||||
if (empty($ADODB_SESSION_EXPIRE_NOTIFY)) {
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY = false;
|
||||
}
|
||||
// Made table name configurable - by David Johnson djohnson@inpro.net
|
||||
if (empty($ADODB_SESSION_TBL)){
|
||||
$ADODB_SESSION_TBL = 'sessions';
|
||||
}
|
||||
|
||||
|
||||
// defaulting $ADODB_SESSION_USE_LOBS
|
||||
if (!isset($ADODB_SESSION_USE_LOBS) || empty($ADODB_SESSION_USE_LOBS)) {
|
||||
$ADODB_SESSION_USE_LOBS = false;
|
||||
}
|
||||
|
||||
/*
|
||||
$ADODB_SESS['driver'] = $ADODB_SESSION_DRIVER;
|
||||
$ADODB_SESS['connect'] = $ADODB_SESSION_CONNECT;
|
||||
$ADODB_SESS['user'] = $ADODB_SESSION_USER;
|
||||
$ADODB_SESS['pwd'] = $ADODB_SESSION_PWD;
|
||||
$ADODB_SESS['db'] = $ADODB_SESSION_DB;
|
||||
$ADODB_SESS['life'] = $ADODB_SESS_LIFE;
|
||||
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
|
||||
|
||||
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
|
||||
$ADODB_SESS['table'] = $ADODB_SESS_TBL;
|
||||
*/
|
||||
|
||||
/****************************************************************************************\
|
||||
Create the connection to the database.
|
||||
|
||||
If $ADODB_SESS_CONN already exists, reuse that connection
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_open($save_path, $session_name,$persist=true)
|
||||
{
|
||||
GLOBAL $ADODB_SESS_CONN;
|
||||
if (isset($ADODB_SESS_CONN)) return true;
|
||||
|
||||
GLOBAL $ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_DRIVER,
|
||||
$ADODB_SESSION_USER,
|
||||
$ADODB_SESSION_PWD,
|
||||
$ADODB_SESSION_DB,
|
||||
$ADODB_SESS_DEBUG;
|
||||
|
||||
// cannot use & below - do not know why...
|
||||
$ADODB_SESS_CONN = ADONewConnection($ADODB_SESSION_DRIVER);
|
||||
if (!empty($ADODB_SESS_DEBUG)) {
|
||||
$ADODB_SESS_CONN->debug = true;
|
||||
ADOConnection::outp( " conn=$ADODB_SESSION_CONNECT user=$ADODB_SESSION_USER pwd=$ADODB_SESSION_PWD db=$ADODB_SESSION_DB ");
|
||||
}
|
||||
if ($persist) $ok = $ADODB_SESS_CONN->PConnect($ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
|
||||
else $ok = $ADODB_SESS_CONN->Connect($ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
|
||||
|
||||
if (!$ok) ADOConnection::outp( "<p>Session: connection failed</p>",false);
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
Close the connection
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_close()
|
||||
{
|
||||
global $ADODB_SESS_CONN;
|
||||
|
||||
if ($ADODB_SESS_CONN) $ADODB_SESS_CONN->Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
Slurp in the session variables and return the serialized string
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_read($key)
|
||||
{
|
||||
global $ADODB_SESS_CONN,$ADODB_SESSION_TBL,$ADODB_SESSION_CRC;
|
||||
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT data FROM $ADODB_SESSION_TBL WHERE sesskey = '$key' AND expiry >= " . time());
|
||||
if ($rs) {
|
||||
if ($rs->EOF) {
|
||||
$v = '';
|
||||
} else
|
||||
$v = rawurldecode(reset($rs->fields));
|
||||
|
||||
$rs->Close();
|
||||
|
||||
// new optimization adodb 2.1
|
||||
$ADODB_SESSION_CRC = strlen($v).crc32($v);
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
return ''; // thx to Jorma Tuomainen, webmaster#wizactive.com
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
Write the serialized data to a database.
|
||||
|
||||
If the data has not been modified since adodb_sess_read(), we do not write.
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_write($key, $val)
|
||||
{
|
||||
global
|
||||
$ADODB_SESS_CONN,
|
||||
$ADODB_SESS_LIFE,
|
||||
$ADODB_SESSION_TBL,
|
||||
$ADODB_SESS_DEBUG,
|
||||
$ADODB_SESSION_CRC,
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY,
|
||||
$ADODB_SESSION_DRIVER, // added
|
||||
$ADODB_SESSION_USE_LOBS; // added
|
||||
|
||||
$expiry = time() + $ADODB_SESS_LIFE;
|
||||
|
||||
// crc32 optimization since adodb 2.1
|
||||
// now we only update expiry date, thx to sebastian thom in adodb 2.32
|
||||
if ($ADODB_SESSION_CRC !== false && $ADODB_SESSION_CRC == strlen($val).crc32($val)) {
|
||||
if ($ADODB_SESS_DEBUG) echo "<p>Session: Only updating date - crc32 not changed</p>";
|
||||
$qry = "UPDATE $ADODB_SESSION_TBL SET expiry=$expiry WHERE sesskey='$key' AND expiry >= " . time();
|
||||
$rs = $ADODB_SESS_CONN->Execute($qry);
|
||||
return true;
|
||||
}
|
||||
$val = rawurlencode($val);
|
||||
|
||||
$arr = array('sesskey' => $key, 'expiry' => $expiry, 'data' => $val);
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
$var = reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
global $$var;
|
||||
$arr['expireref'] = $$var;
|
||||
}
|
||||
|
||||
|
||||
if ($ADODB_SESSION_USE_LOBS === false) { // no lobs, simply use replace()
|
||||
$rs = $ADODB_SESS_CONN->Replace($ADODB_SESSION_TBL,$arr, 'sesskey',$autoQuote = true);
|
||||
if (!$rs) {
|
||||
$err = $ADODB_SESS_CONN->ErrorMsg();
|
||||
}
|
||||
} else {
|
||||
// what value shall we insert/update for lob row?
|
||||
switch ($ADODB_SESSION_DRIVER) {
|
||||
// empty_clob or empty_lob for oracle dbs
|
||||
case "oracle":
|
||||
case "oci8":
|
||||
case "oci8po":
|
||||
case "oci805":
|
||||
$lob_value = sprintf("empty_%s()", strtolower($ADODB_SESSION_USE_LOBS));
|
||||
break;
|
||||
|
||||
// null for all other
|
||||
default:
|
||||
$lob_value = "null";
|
||||
break;
|
||||
}
|
||||
|
||||
// do we insert or update? => as for sesskey
|
||||
$res = $ADODB_SESS_CONN->Execute("select count(*) as cnt from $ADODB_SESSION_TBL where sesskey = '$key'");
|
||||
if ($res && reset($res->fields) > 0) {
|
||||
$qry = sprintf("update %s set expiry = %d, data = %s where sesskey = '%s'", $ADODB_SESSION_TBL, $expiry, $lob_value, $key);
|
||||
} else {
|
||||
// insert
|
||||
$qry = sprintf("insert into %s (sesskey, expiry, data) values ('%s', %d, %s)", $ADODB_SESSION_TBL, $key, $expiry, $lob_value);
|
||||
}
|
||||
|
||||
$err = "";
|
||||
$rs1 = $ADODB_SESS_CONN->Execute($qry);
|
||||
if (!$rs1) {
|
||||
$err .= $ADODB_SESS_CONN->ErrorMsg()."\n";
|
||||
}
|
||||
$rs2 = $ADODB_SESS_CONN->UpdateBlob($ADODB_SESSION_TBL, 'data', $val, "sesskey='$key'", strtoupper($ADODB_SESSION_USE_LOBS));
|
||||
if (!$rs2) {
|
||||
$err .= $ADODB_SESS_CONN->ErrorMsg()."\n";
|
||||
}
|
||||
$rs = ($rs1 && $rs2) ? true : false;
|
||||
}
|
||||
|
||||
if (!$rs) {
|
||||
ADOConnection::outp( '<p>Session Replace: '.nl2br($err).'</p>',false);
|
||||
} else {
|
||||
// bug in access driver (could be odbc?) means that info is not commited
|
||||
// properly unless select statement executed in Win2000
|
||||
if ($ADODB_SESS_CONN->databaseType == 'access')
|
||||
$rs = $ADODB_SESS_CONN->Execute("select sesskey from $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
}
|
||||
return !empty($rs);
|
||||
}
|
||||
|
||||
function adodb_sess_destroy($key)
|
||||
{
|
||||
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
|
||||
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$ADODB_SESS_CONN->SetFetchMode($savem);
|
||||
if ($rs) {
|
||||
$ADODB_SESS_CONN->BeginTrans();
|
||||
while (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
$fn($ref,$key);
|
||||
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$ADODB_SESS_CONN->CommitTrans();
|
||||
}
|
||||
} else {
|
||||
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE sesskey = '$key'";
|
||||
$rs = $ADODB_SESS_CONN->Execute($qry);
|
||||
}
|
||||
return $rs ? true : false;
|
||||
}
|
||||
|
||||
function adodb_sess_gc($maxlifetime)
|
||||
{
|
||||
global $ADODB_SESS_DEBUG, $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
|
||||
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$t = time();
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
|
||||
$ADODB_SESS_CONN->SetFetchMode($savem);
|
||||
if ($rs) {
|
||||
$ADODB_SESS_CONN->BeginTrans();
|
||||
while (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
$fn($ref,$key);
|
||||
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
//$ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < $t");
|
||||
$ADODB_SESS_CONN->CommitTrans();
|
||||
|
||||
}
|
||||
} else {
|
||||
$ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
|
||||
|
||||
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p><b>Garbage Collection</b>: $qry</p>");
|
||||
}
|
||||
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
|
||||
if (defined('ADODB_SESSION_OPTIMIZE')) {
|
||||
global $ADODB_SESSION_DRIVER;
|
||||
|
||||
switch( $ADODB_SESSION_DRIVER ) {
|
||||
case 'mysql':
|
||||
case 'mysqlt':
|
||||
$opt_qry = 'OPTIMIZE TABLE '.$ADODB_SESSION_TBL;
|
||||
break;
|
||||
case 'postgresql':
|
||||
case 'postgresql7':
|
||||
$opt_qry = 'VACUUM '.$ADODB_SESSION_TBL;
|
||||
break;
|
||||
}
|
||||
if (!empty($opt_qry)) {
|
||||
$ADODB_SESS_CONN->Execute($opt_qry);
|
||||
}
|
||||
}
|
||||
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
|
||||
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
|
||||
|
||||
$rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
|
||||
if ($rs && !$rs->EOF) {
|
||||
|
||||
$dbts = reset($rs->fields);
|
||||
$rs->Close();
|
||||
$dbt = $ADODB_SESS_CONN->UnixTimeStamp($dbts);
|
||||
$t = time();
|
||||
if (abs($dbt - $t) >= ADODB_SESSION_SYNCH_SECS) {
|
||||
global $HTTP_SERVER_VARS;
|
||||
$msg =
|
||||
__FILE__.": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: database=$dbt ($dbts), webserver=$t (diff=".(abs($dbt-$t)/3600)." hrs)";
|
||||
error_log($msg);
|
||||
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p>$msg</p>");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
session_module_name('user');
|
||||
session_set_save_handler(
|
||||
"adodb_sess_open",
|
||||
"adodb_sess_close",
|
||||
"adodb_sess_read",
|
||||
"adodb_sess_write",
|
||||
"adodb_sess_destroy",
|
||||
"adodb_sess_gc");
|
||||
}
|
||||
|
||||
/* TEST SCRIPT -- UNCOMMENT */
|
||||
|
||||
if (0) {
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
ADOConnection::outp( "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>",false);
|
||||
}
|
||||
|
||||
?>
|
403
phpgwapi/inc/adodb/session/old/adodb-session.php
Normal file
403
phpgwapi/inc/adodb/session/old/adodb-session.php
Normal file
@ -0,0 +1,403 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version of ADODB is available at http://php.weblogs.com/adodb
|
||||
======================================================================
|
||||
|
||||
This file provides PHP4 session management using the ADODB database
|
||||
wrapper library.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
include('adodb.inc.php');
|
||||
include('adodb-session.php');
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
|
||||
|
||||
To force non-persistent connections, call adodb_session_open first before session_start():
|
||||
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
include('adodb.inc.php');
|
||||
include('adodb-session.php');
|
||||
adodb_sess_open(false,false,false);
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
print "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>";
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
1. Create this table in your database (syntax might vary depending on your db):
|
||||
|
||||
create table sessions (
|
||||
SESSKEY char(32) not null,
|
||||
EXPIRY int(11) unsigned not null,
|
||||
EXPIREREF varchar(64),
|
||||
DATA text not null,
|
||||
primary key (sesskey)
|
||||
);
|
||||
|
||||
For oracle:
|
||||
create table sessions (
|
||||
SESSKEY char(32) not null,
|
||||
EXPIRY DECIMAL(16) not null,
|
||||
EXPIREREF varchar(64),
|
||||
DATA varchar(4000) not null,
|
||||
primary key (sesskey)
|
||||
);
|
||||
|
||||
|
||||
2. Then define the following parameters. You can either modify
|
||||
this file, or define them before this file is included:
|
||||
|
||||
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
|
||||
$ADODB_SESSION_CONNECT='server to connect to';
|
||||
$ADODB_SESSION_USER ='user';
|
||||
$ADODB_SESSION_PWD ='password';
|
||||
$ADODB_SESSION_DB ='database';
|
||||
$ADODB_SESSION_TBL = 'sessions'
|
||||
|
||||
3. Recommended is PHP 4.0.6 or later. There are documented
|
||||
session bugs in earlier versions of PHP.
|
||||
|
||||
4. If you want to receive notifications when a session expires, then
|
||||
you can tag a session with an EXPIREREF, and before the session
|
||||
record is deleted, we can call a function that will pass the EXPIREREF
|
||||
as the first parameter, and the session key as the second parameter.
|
||||
|
||||
To do this, define a notification function, say NotifyFn:
|
||||
|
||||
function NotifyFn($expireref, $sesskey)
|
||||
{
|
||||
}
|
||||
|
||||
Then you need to define a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
|
||||
This is an array with 2 elements, the first being the name of the variable
|
||||
you would like to store in the EXPIREREF field, and the 2nd is the
|
||||
notification function's name.
|
||||
|
||||
In this example, we want to be notified when a user's session
|
||||
has expired, so we store the user id in the global variable $USERID,
|
||||
store this value in the EXPIREREF field:
|
||||
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
|
||||
|
||||
Then when the NotifyFn is called, we are passed the $USERID as the first
|
||||
parameter, eg. NotifyFn($userid, $sesskey).
|
||||
*/
|
||||
|
||||
if (!defined('_ADODB_LAYER')) {
|
||||
include (dirname(__FILE__).'/adodb.inc.php');
|
||||
}
|
||||
|
||||
if (!defined('ADODB_SESSION')) {
|
||||
|
||||
define('ADODB_SESSION',1);
|
||||
|
||||
/* if database time and system time is difference is greater than this, then give warning */
|
||||
define('ADODB_SESSION_SYNCH_SECS',60);
|
||||
|
||||
/****************************************************************************************\
|
||||
Global definitions
|
||||
\****************************************************************************************/
|
||||
GLOBAL $ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_DRIVER,
|
||||
$ADODB_SESSION_USER,
|
||||
$ADODB_SESSION_PWD,
|
||||
$ADODB_SESSION_DB,
|
||||
$ADODB_SESS_CONN,
|
||||
$ADODB_SESS_LIFE,
|
||||
$ADODB_SESS_DEBUG,
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY,
|
||||
$ADODB_SESSION_CRC,
|
||||
$ADODB_SESSION_TBL;
|
||||
|
||||
|
||||
$ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
|
||||
if ($ADODB_SESS_LIFE <= 1) {
|
||||
// bug in PHP 4.0.3 pl 1 -- how about other versions?
|
||||
//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $ADODB_SESS_LIFE</h3>";
|
||||
$ADODB_SESS_LIFE=1440;
|
||||
}
|
||||
$ADODB_SESSION_CRC = false;
|
||||
//$ADODB_SESS_DEBUG = true;
|
||||
|
||||
//////////////////////////////////
|
||||
/* SET THE FOLLOWING PARAMETERS */
|
||||
//////////////////////////////////
|
||||
|
||||
if (empty($ADODB_SESSION_DRIVER)) {
|
||||
$ADODB_SESSION_DRIVER='mysql';
|
||||
$ADODB_SESSION_CONNECT='localhost';
|
||||
$ADODB_SESSION_USER ='root';
|
||||
$ADODB_SESSION_PWD ='';
|
||||
$ADODB_SESSION_DB ='xphplens_2';
|
||||
}
|
||||
|
||||
if (empty($ADODB_SESSION_EXPIRE_NOTIFY)) {
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY = false;
|
||||
}
|
||||
// Made table name configurable - by David Johnson djohnson@inpro.net
|
||||
if (empty($ADODB_SESSION_TBL)){
|
||||
$ADODB_SESSION_TBL = 'sessions';
|
||||
}
|
||||
|
||||
/*
|
||||
$ADODB_SESS['driver'] = $ADODB_SESSION_DRIVER;
|
||||
$ADODB_SESS['connect'] = $ADODB_SESSION_CONNECT;
|
||||
$ADODB_SESS['user'] = $ADODB_SESSION_USER;
|
||||
$ADODB_SESS['pwd'] = $ADODB_SESSION_PWD;
|
||||
$ADODB_SESS['db'] = $ADODB_SESSION_DB;
|
||||
$ADODB_SESS['life'] = $ADODB_SESS_LIFE;
|
||||
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
|
||||
|
||||
$ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
|
||||
$ADODB_SESS['table'] = $ADODB_SESS_TBL;
|
||||
*/
|
||||
|
||||
/****************************************************************************************\
|
||||
Create the connection to the database.
|
||||
|
||||
If $ADODB_SESS_CONN already exists, reuse that connection
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_open($save_path, $session_name,$persist=true)
|
||||
{
|
||||
GLOBAL $ADODB_SESS_CONN;
|
||||
if (isset($ADODB_SESS_CONN)) return true;
|
||||
|
||||
GLOBAL $ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_DRIVER,
|
||||
$ADODB_SESSION_USER,
|
||||
$ADODB_SESSION_PWD,
|
||||
$ADODB_SESSION_DB,
|
||||
$ADODB_SESS_DEBUG;
|
||||
|
||||
// cannot use & below - do not know why...
|
||||
$ADODB_SESS_CONN = ADONewConnection($ADODB_SESSION_DRIVER);
|
||||
if (!empty($ADODB_SESS_DEBUG)) {
|
||||
$ADODB_SESS_CONN->debug = true;
|
||||
ADOConnection::outp( " conn=$ADODB_SESSION_CONNECT user=$ADODB_SESSION_USER pwd=$ADODB_SESSION_PWD db=$ADODB_SESSION_DB ");
|
||||
}
|
||||
if ($persist) $ok = $ADODB_SESS_CONN->PConnect($ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
|
||||
else $ok = $ADODB_SESS_CONN->Connect($ADODB_SESSION_CONNECT,
|
||||
$ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
|
||||
|
||||
if (!$ok) ADOConnection::outp( "<p>Session: connection failed</p>",false);
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
Close the connection
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_close()
|
||||
{
|
||||
global $ADODB_SESS_CONN;
|
||||
|
||||
if ($ADODB_SESS_CONN) $ADODB_SESS_CONN->Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
Slurp in the session variables and return the serialized string
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_read($key)
|
||||
{
|
||||
global $ADODB_SESS_CONN,$ADODB_SESSION_TBL,$ADODB_SESSION_CRC;
|
||||
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT data FROM $ADODB_SESSION_TBL WHERE sesskey = '$key' AND expiry >= " . time());
|
||||
if ($rs) {
|
||||
if ($rs->EOF) {
|
||||
$v = '';
|
||||
} else
|
||||
$v = rawurldecode(reset($rs->fields));
|
||||
|
||||
$rs->Close();
|
||||
|
||||
// new optimization adodb 2.1
|
||||
$ADODB_SESSION_CRC = strlen($v).crc32($v);
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
return ''; // thx to Jorma Tuomainen, webmaster#wizactive.com
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
Write the serialized data to a database.
|
||||
|
||||
If the data has not been modified since adodb_sess_read(), we do not write.
|
||||
\****************************************************************************************/
|
||||
function adodb_sess_write($key, $val)
|
||||
{
|
||||
global
|
||||
$ADODB_SESS_CONN,
|
||||
$ADODB_SESS_LIFE,
|
||||
$ADODB_SESSION_TBL,
|
||||
$ADODB_SESS_DEBUG,
|
||||
$ADODB_SESSION_CRC,
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY;
|
||||
|
||||
$expiry = time() + $ADODB_SESS_LIFE;
|
||||
|
||||
// crc32 optimization since adodb 2.1
|
||||
// now we only update expiry date, thx to sebastian thom in adodb 2.32
|
||||
if ($ADODB_SESSION_CRC !== false && $ADODB_SESSION_CRC == strlen($val).crc32($val)) {
|
||||
if ($ADODB_SESS_DEBUG) echo "<p>Session: Only updating date - crc32 not changed</p>";
|
||||
$qry = "UPDATE $ADODB_SESSION_TBL SET expiry=$expiry WHERE sesskey='$key' AND expiry >= " . time();
|
||||
$rs = $ADODB_SESS_CONN->Execute($qry);
|
||||
return true;
|
||||
}
|
||||
$val = rawurlencode($val);
|
||||
|
||||
$arr = array('sesskey' => $key, 'expiry' => $expiry, 'data' => $val);
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
$var = reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
global $$var;
|
||||
$arr['expireref'] = $$var;
|
||||
}
|
||||
$rs = $ADODB_SESS_CONN->Replace($ADODB_SESSION_TBL,$arr,
|
||||
'sesskey',$autoQuote = true);
|
||||
|
||||
if (!$rs) {
|
||||
ADOConnection::outp( '<p>Session Replace: '.$ADODB_SESS_CONN->ErrorMsg().'</p>',false);
|
||||
} else {
|
||||
// bug in access driver (could be odbc?) means that info is not commited
|
||||
// properly unless select statement executed in Win2000
|
||||
if ($ADODB_SESS_CONN->databaseType == 'access')
|
||||
$rs = $ADODB_SESS_CONN->Execute("select sesskey from $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
}
|
||||
return !empty($rs);
|
||||
}
|
||||
|
||||
function adodb_sess_destroy($key)
|
||||
{
|
||||
global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
|
||||
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$ADODB_SESS_CONN->SetFetchMode($savem);
|
||||
if ($rs) {
|
||||
$ADODB_SESS_CONN->BeginTrans();
|
||||
while (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
$fn($ref,$key);
|
||||
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$ADODB_SESS_CONN->CommitTrans();
|
||||
}
|
||||
} else {
|
||||
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE sesskey = '$key'";
|
||||
$rs = $ADODB_SESS_CONN->Execute($qry);
|
||||
}
|
||||
return $rs ? true : false;
|
||||
}
|
||||
|
||||
function adodb_sess_gc($maxlifetime)
|
||||
{
|
||||
global $ADODB_SESS_DEBUG, $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
|
||||
|
||||
if ($ADODB_SESSION_EXPIRE_NOTIFY) {
|
||||
reset($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
|
||||
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
|
||||
$t = time();
|
||||
$rs =& $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
|
||||
$ADODB_SESS_CONN->SetFetchMode($savem);
|
||||
if ($rs) {
|
||||
$ADODB_SESS_CONN->BeginTrans();
|
||||
while (!$rs->EOF) {
|
||||
$ref = $rs->fields[0];
|
||||
$key = $rs->fields[1];
|
||||
$fn($ref,$key);
|
||||
$del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
|
||||
$rs->MoveNext();
|
||||
}
|
||||
$rs->Close();
|
||||
|
||||
$ADODB_SESS_CONN->CommitTrans();
|
||||
|
||||
}
|
||||
} else {
|
||||
$qry = "DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time();
|
||||
$ADODB_SESS_CONN->Execute($qry);
|
||||
|
||||
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p><b>Garbage Collection</b>: $qry</p>");
|
||||
}
|
||||
// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
|
||||
if (defined('ADODB_SESSION_OPTIMIZE')) {
|
||||
global $ADODB_SESSION_DRIVER;
|
||||
|
||||
switch( $ADODB_SESSION_DRIVER ) {
|
||||
case 'mysql':
|
||||
case 'mysqlt':
|
||||
$opt_qry = 'OPTIMIZE TABLE '.$ADODB_SESSION_TBL;
|
||||
break;
|
||||
case 'postgresql':
|
||||
case 'postgresql7':
|
||||
$opt_qry = 'VACUUM '.$ADODB_SESSION_TBL;
|
||||
break;
|
||||
}
|
||||
if (!empty($opt_qry)) {
|
||||
$ADODB_SESS_CONN->Execute($opt_qry);
|
||||
}
|
||||
}
|
||||
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
|
||||
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
|
||||
|
||||
$rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
|
||||
if ($rs && !$rs->EOF) {
|
||||
|
||||
$dbts = reset($rs->fields);
|
||||
$rs->Close();
|
||||
$dbt = $ADODB_SESS_CONN->UnixTimeStamp($dbts);
|
||||
$t = time();
|
||||
|
||||
if (abs($dbt - $t) >= ADODB_SESSION_SYNCH_SECS) {
|
||||
global $HTTP_SERVER_VARS;
|
||||
$msg =
|
||||
__FILE__.": Server time for webserver {$HTTP_SERVER_VARS['HTTP_HOST']} not in synch with database: database=$dbt ($dbts), webserver=$t (diff=".(abs($dbt-$t)/3600)." hrs)";
|
||||
error_log($msg);
|
||||
if ($ADODB_SESS_DEBUG) ADOConnection::outp("<p>$msg</p>");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
session_module_name('user');
|
||||
session_set_save_handler(
|
||||
"adodb_sess_open",
|
||||
"adodb_sess_close",
|
||||
"adodb_sess_read",
|
||||
"adodb_sess_write",
|
||||
"adodb_sess_destroy",
|
||||
"adodb_sess_gc");
|
||||
}
|
||||
|
||||
/* TEST SCRIPT -- UNCOMMENT */
|
||||
|
||||
if (0) {
|
||||
GLOBAL $HTTP_SESSION_VARS;
|
||||
|
||||
session_start();
|
||||
session_register('AVAR');
|
||||
$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
ADOConnection::outp( "<p>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</p>",false);
|
||||
}
|
||||
|
||||
?>
|
84
phpgwapi/inc/adodb/tests/benchmark.php
Normal file
84
phpgwapi/inc/adodb/tests/benchmark.php
Normal file
@ -0,0 +1,84 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>ADODB Benchmarks</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Benchmark code to test the speed to the ADODB library with different databases.
|
||||
This is a simplistic benchmark to be used as the basis for further testing.
|
||||
It should not be used as proof of the superiority of one database over the other.
|
||||
*/
|
||||
|
||||
$testmssql = true;
|
||||
//$testvfp = true;
|
||||
$testoracle = true;
|
||||
$testado = true;
|
||||
$testibase = true;
|
||||
$testaccess = true;
|
||||
$testmysql = true;
|
||||
$testsqlite = true;;
|
||||
|
||||
set_time_limit(240); // increase timeout
|
||||
|
||||
include("../tohtml.inc.php");
|
||||
include("../adodb.inc.php");
|
||||
|
||||
function testdb(&$db,$createtab="create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)")
|
||||
{
|
||||
GLOBAL $ADODB_version,$ADODB_FETCH_MODE;
|
||||
|
||||
adodb_backtrace();
|
||||
|
||||
$max = 100;
|
||||
$sql = 'select * from ADOXYZ';
|
||||
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
|
||||
|
||||
//print "<h3>ADODB Version: $ADODB_version Host: <i>$db->host</i> Database: <i>$db->database</i></h3>";
|
||||
|
||||
// perform query once to cache results so we are only testing throughput
|
||||
$rs = $db->Execute($sql);
|
||||
if (!$rs){
|
||||
print "Error in recordset<p>";
|
||||
return;
|
||||
}
|
||||
$arr = $rs->GetArray();
|
||||
//$db->debug = true;
|
||||
global $ADODB_COUNTRECS;
|
||||
$ADODB_COUNTRECS = false;
|
||||
$start = microtime();
|
||||
for ($i=0; $i < $max; $i++) {
|
||||
$rs =& $db->Execute($sql);
|
||||
$arr =& $rs->GetArray();
|
||||
// print $arr[0][1];
|
||||
}
|
||||
$end = microtime();
|
||||
$start = explode(' ',$start);
|
||||
$end = explode(' ',$end);
|
||||
|
||||
//print_r($start);
|
||||
//print_r($end);
|
||||
|
||||
// print_r($arr);
|
||||
$total = $end[0]+trim($end[1]) - $start[0]-trim($start[1]);
|
||||
printf ("<p>seconds = %8.2f for %d iterations each with %d records</p>",$total,$max, sizeof($arr));
|
||||
flush();
|
||||
|
||||
|
||||
//$db->Close();
|
||||
}
|
||||
include("testdatabases.inc.php");
|
||||
|
||||
?>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
233
phpgwapi/inc/adodb/tests/test-datadict.php
Normal file
233
phpgwapi/inc/adodb/tests/test-datadict.php
Normal file
@ -0,0 +1,233 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
include_once('../adodb.inc.php');
|
||||
|
||||
foreach(array('sybase','mysqlt','access','oci8','postgres','odbc_mssql','odbc','sybase','firebird','informix','db2') as $dbType) {
|
||||
echo "<h3>$dbType</h3><p>";
|
||||
$db = NewADOConnection($dbType);
|
||||
$dict = NewDataDictionary($db);
|
||||
|
||||
if (!$dict) continue;
|
||||
$dict->debug = 1;
|
||||
|
||||
$opts = array('REPLACE','mysql' => 'TYPE=INNODB', 'oci8' => 'TABLESPACE USERS');
|
||||
|
||||
/* $flds = array(
|
||||
array('id', 'I',
|
||||
'AUTO','KEY'),
|
||||
|
||||
array('name' => 'firstname', 'type' => 'varchar','size' => 30,
|
||||
'DEFAULT'=>'Joan'),
|
||||
|
||||
array('lastname','varchar',28,
|
||||
'DEFAULT'=>'Chen','key'),
|
||||
|
||||
array('averylonglongfieldname','X',1024,
|
||||
'NOTNULL','default' => 'test'),
|
||||
|
||||
array('price','N','7.2',
|
||||
'NOTNULL','default' => '0.00'),
|
||||
|
||||
array('MYDATE', 'D',
|
||||
'DEFDATE'),
|
||||
array('TS','T',
|
||||
'DEFTIMESTAMP')
|
||||
);*/
|
||||
|
||||
$flds = "
|
||||
ID I AUTO KEY,
|
||||
FIRSTNAME VARCHAR(30) DEFAULT 'Joan',
|
||||
LASTNAME VARCHAR(28) DEFAULT 'Chen' key,
|
||||
averylonglongfieldname X(1024) DEFAULT 'test',
|
||||
price N(7.2) DEFAULT '0.00',
|
||||
MYDATE D DEFDATE,
|
||||
BIGFELLOW X NOTNULL,
|
||||
TS T DEFTIMESTAMP";
|
||||
|
||||
|
||||
$sqla = $dict->CreateDatabase('KUTU',array('postgres'=>"LOCATION='/u01/postdata'"));
|
||||
$dict->SetSchema('KUTU');
|
||||
|
||||
$sqli = ($dict->CreateTableSQL('testtable',$flds, $opts));
|
||||
$sqla =& array_merge($sqla,$sqli);
|
||||
|
||||
$sqli = $dict->CreateIndexSQL('idx','testtable','firstname,lastname',array('BITMAP','FULLTEXT','CLUSTERED','HASH'));
|
||||
$sqla =& array_merge($sqla,$sqli);
|
||||
$sqli = $dict->CreateIndexSQL('idx2','testtable','price,lastname');//,array('BITMAP','FULLTEXT','CLUSTERED'));
|
||||
$sqla =& array_merge($sqla,$sqli);
|
||||
|
||||
$addflds = array(array('height', 'F'),array('weight','F'));
|
||||
$sqli = $dict->AddColumnSQL('testtable',$addflds);
|
||||
$sqla =& array_merge($sqla,$sqli);
|
||||
$addflds = array(array('height', 'F','NOTNULL'),array('weight','F','NOTNULL'));
|
||||
$sqli = $dict->AlterColumnSQL('testtable',$addflds);
|
||||
$sqla =& array_merge($sqla,$sqli);
|
||||
|
||||
|
||||
printsqla($dbType,$sqla);
|
||||
|
||||
if (file_exists('d:\inetpub\wwwroot\php\phplens\adodb\adodb.inc.php'))
|
||||
if ($dbType == 'mysql') {
|
||||
$db->Connect('localhost', "root", "", "test");
|
||||
$dict->SetSchema('');
|
||||
$sqla2 = $dict->ChangeTableSQL('adoxyz',$flds);
|
||||
if ($sqla2) printsqla($dbType,$sqla2);
|
||||
}
|
||||
if ($dbType == 'postgres') {
|
||||
$db->Connect('localhost', "tester", "test", "test");
|
||||
$dict->SetSchema('');
|
||||
$sqla2 = $dict->ChangeTableSQL('adoxyz',$flds);
|
||||
if ($sqla2) printsqla($dbType,$sqla2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function printsqla($dbType,$sqla)
|
||||
{
|
||||
print "<pre>";
|
||||
//print_r($dict->MetaTables());
|
||||
foreach($sqla as $s) {
|
||||
$s = htmlspecialchars($s);
|
||||
print "$s;\n";
|
||||
if ($dbType == 'oci8') print "/\n";
|
||||
}
|
||||
print "</pre><hr>";
|
||||
}
|
||||
|
||||
/***
|
||||
|
||||
Generated SQL:
|
||||
|
||||
mysql
|
||||
|
||||
CREATE DATABASE KUTU;
|
||||
DROP TABLE KUTU.testtable;
|
||||
CREATE TABLE KUTU.testtable (
|
||||
id INTEGER NOT NULL AUTO_INCREMENT,
|
||||
firstname VARCHAR(30) DEFAULT 'Joan',
|
||||
lastname VARCHAR(28) NOT NULL DEFAULT 'Chen',
|
||||
averylonglongfieldname LONGTEXT NOT NULL,
|
||||
price NUMERIC(7,2) NOT NULL DEFAULT 0.00,
|
||||
MYDATE DATE DEFAULT CURDATE(),
|
||||
PRIMARY KEY (id, lastname)
|
||||
)TYPE=ISAM;
|
||||
CREATE FULLTEXT INDEX idx ON KUTU.testtable (firstname,lastname);
|
||||
CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
|
||||
ALTER TABLE KUTU.testtable ADD height DOUBLE;
|
||||
ALTER TABLE KUTU.testtable ADD weight DOUBLE;
|
||||
ALTER TABLE KUTU.testtable MODIFY COLUMN height DOUBLE NOT NULL;
|
||||
ALTER TABLE KUTU.testtable MODIFY COLUMN weight DOUBLE NOT NULL;
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
oci8
|
||||
|
||||
CREATE USER KUTU IDENTIFIED BY tiger;
|
||||
/
|
||||
GRANT CREATE SESSION, CREATE TABLE,UNLIMITED TABLESPACE,CREATE SEQUENCE TO KUTU;
|
||||
/
|
||||
DROP TABLE KUTU.testtable CASCADE CONSTRAINTS;
|
||||
/
|
||||
CREATE TABLE KUTU.testtable (
|
||||
id NUMBER(16) NOT NULL,
|
||||
firstname VARCHAR(30) DEFAULT 'Joan',
|
||||
lastname VARCHAR(28) DEFAULT 'Chen' NOT NULL,
|
||||
averylonglongfieldname CLOB NOT NULL,
|
||||
price NUMBER(7,2) DEFAULT 0.00 NOT NULL,
|
||||
MYDATE DATE DEFAULT TRUNC(SYSDATE),
|
||||
PRIMARY KEY (id, lastname)
|
||||
)TABLESPACE USERS;
|
||||
/
|
||||
DROP SEQUENCE KUTU.SEQ_testtable;
|
||||
/
|
||||
CREATE SEQUENCE KUTU.SEQ_testtable;
|
||||
/
|
||||
CREATE OR REPLACE TRIGGER KUTU.TRIG_SEQ_testtable BEFORE insert ON KUTU.testtable
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
select KUTU.SEQ_testtable.nextval into :new.id from dual;
|
||||
END;
|
||||
/
|
||||
CREATE BITMAP INDEX idx ON KUTU.testtable (firstname,lastname);
|
||||
/
|
||||
CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
|
||||
/
|
||||
ALTER TABLE testtable ADD (
|
||||
height NUMBER,
|
||||
weight NUMBER);
|
||||
/
|
||||
ALTER TABLE testtable MODIFY(
|
||||
height NUMBER NOT NULL,
|
||||
weight NUMBER NOT NULL);
|
||||
/
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
postgres
|
||||
AlterColumnSQL not supported for PostgreSQL
|
||||
|
||||
|
||||
CREATE DATABASE KUTU LOCATION='/u01/postdata';
|
||||
DROP TABLE KUTU.testtable;
|
||||
CREATE TABLE KUTU.testtable (
|
||||
id SERIAL,
|
||||
firstname VARCHAR(30) DEFAULT 'Joan',
|
||||
lastname VARCHAR(28) DEFAULT 'Chen' NOT NULL,
|
||||
averylonglongfieldname TEXT NOT NULL,
|
||||
price NUMERIC(7,2) DEFAULT 0.00 NOT NULL,
|
||||
MYDATE DATE DEFAULT CURRENT_DATE,
|
||||
PRIMARY KEY (id, lastname)
|
||||
);
|
||||
CREATE INDEX idx ON KUTU.testtable USING HASH (firstname,lastname);
|
||||
CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
|
||||
ALTER TABLE KUTU.testtable ADD height FLOAT8;
|
||||
ALTER TABLE KUTU.testtable ADD weight FLOAT8;
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
odbc_mssql
|
||||
|
||||
CREATE DATABASE KUTU;
|
||||
DROP TABLE KUTU.testtable;
|
||||
CREATE TABLE KUTU.testtable (
|
||||
id INT IDENTITY(1,1) NOT NULL,
|
||||
firstname VARCHAR(30) DEFAULT 'Joan',
|
||||
lastname VARCHAR(28) DEFAULT 'Chen' NOT NULL,
|
||||
averylonglongfieldname TEXT NOT NULL,
|
||||
price NUMERIC(7,2) DEFAULT 0.00 NOT NULL,
|
||||
MYDATE DATETIME DEFAULT GetDate(),
|
||||
PRIMARY KEY (id, lastname)
|
||||
);
|
||||
CREATE CLUSTERED INDEX idx ON KUTU.testtable (firstname,lastname);
|
||||
CREATE INDEX idx2 ON KUTU.testtable (price,lastname);
|
||||
ALTER TABLE KUTU.testtable ADD
|
||||
height REAL,
|
||||
weight REAL;
|
||||
ALTER TABLE KUTU.testtable ALTER COLUMN height REAL NOT NULL;
|
||||
ALTER TABLE KUTU.testtable ALTER COLUMN weight REAL NOT NULL;
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
echo "<h1>Test XML Schema</h1>";
|
||||
$ff = file('xmlschema.xml');
|
||||
echo "<pre>";
|
||||
foreach($ff as $xml) echo htmlspecialchars($xml);
|
||||
echo "</pre>";
|
||||
include_once('test-xmlschema.php');
|
||||
?>
|
68
phpgwapi/inc/adodb/tests/test-php5.php
Normal file
68
phpgwapi/inc/adodb/tests/test-php5.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
*/
|
||||
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$path = dirname(__FILE__);
|
||||
|
||||
include("$path/../adodb-exceptions.inc.php");
|
||||
include("$path/../adodb.inc.php");
|
||||
|
||||
echo "<h3>PHP ".PHP_VERSION."</h3>\n";
|
||||
try {
|
||||
|
||||
$dbt = 'oci8po';
|
||||
|
||||
switch($dbt) {
|
||||
case 'oci8po':
|
||||
$db = NewADOConnection("oci8po");
|
||||
$db->Connect('','scott','natsoft');
|
||||
break;
|
||||
default:
|
||||
case 'mysql':
|
||||
$db = NewADOConnection("mysql");
|
||||
$db->Connect('localhost','root','','test');
|
||||
break;
|
||||
|
||||
case 'mysqli':
|
||||
$db = NewADOConnection("mysqli://root:@localhost/test");
|
||||
//$db->Connect('localhost','root','','test');
|
||||
break;
|
||||
}
|
||||
|
||||
$db->debug=1;
|
||||
|
||||
$cnt = $db->GetOne("select count(*) from adoxyz where ?<id and id<?",array(10,20));
|
||||
$stmt = $db->Prepare("select * from adoxyz where ?<id and id<?");
|
||||
if (!$stmt) echo $db->ErrorMsg(),"\n";
|
||||
$rs = $db->Execute($stmt,array(10,20));
|
||||
|
||||
$i = 0;
|
||||
foreach($rs as $v) {
|
||||
$i += 1;
|
||||
echo "rec $i: "; adodb_pr($v); adodb_pr($rs->fields);
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
if ($i != $cnt) die("actual cnt is $i, cnt should be $cnt\n");
|
||||
|
||||
|
||||
$rs = $db->Execute("select bad from badder");
|
||||
|
||||
} catch (exception $e) {
|
||||
adodb_pr($e);
|
||||
echo "<h3>adodb_backtrace:</h3>\n";
|
||||
$e = adodb_backtrace($e->gettrace());
|
||||
}
|
||||
|
||||
$rs = $db->Execute("select distinct id, firstname,lastname from adoxyz order by id");
|
||||
echo "Result=\n",$rs;
|
||||
?>
|
53
phpgwapi/inc/adodb/tests/test-xmlschema.php
Normal file
53
phpgwapi/inc/adodb/tests/test-xmlschema.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?PHP
|
||||
|
||||
// V4.50 6 July 2004
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
require( "../adodb-xmlschema.inc.php" );
|
||||
|
||||
// To build the schema, start by creating a normal ADOdb connection:
|
||||
$db = ADONewConnection( 'mysql' );
|
||||
$db->Connect( 'localhost', 'root', '', 'schematest' );
|
||||
|
||||
// To create a schema object and build the query array.
|
||||
$schema = new adoSchema( $db );
|
||||
|
||||
// To upgrade an existing schema object, use the following
|
||||
// To upgrade an existing database to the provided schema,
|
||||
// uncomment the following line:
|
||||
#$schema->upgradeSchema();
|
||||
|
||||
print "<b>SQL to build xmlschema.xml</b>:\n<pre>";
|
||||
// Build the SQL array
|
||||
$sql = $schema->ParseSchema( "xmlschema.xml" );
|
||||
|
||||
print_r( $sql );
|
||||
print "</pre>\n";
|
||||
|
||||
// Execute the SQL on the database
|
||||
//$result = $schema->ExecuteSchema( $sql );
|
||||
|
||||
// Finally, clean up after the XML parser
|
||||
// (PHP won't do this for you!)
|
||||
//$schema->Destroy();
|
||||
|
||||
|
||||
$db2 = ADONewConnection('mssql');
|
||||
$db2->Connect('localhost','sa','natsoft','northwind') || die("Fail 2");
|
||||
|
||||
$db2->Execute("drop table simple_table");
|
||||
|
||||
|
||||
print "<b>SQL to build xmlschema-mssql.xml</b>:\n<pre>";
|
||||
|
||||
$schema = new adoSchema( $db2 );
|
||||
$sql = $schema->ParseSchema( "xmlschema-mssql.xml" );
|
||||
|
||||
print_r( $sql );
|
||||
print "</pre>\n";
|
||||
|
||||
$db2->debug=1;
|
||||
|
||||
$db2->Execute($sql[0]);
|
||||
?>
|
1568
phpgwapi/inc/adodb/tests/test.php
Normal file
1568
phpgwapi/inc/adodb/tests/test.php
Normal file
File diff suppressed because it is too large
Load Diff
41
phpgwapi/inc/adodb/tests/test2.php
Normal file
41
phpgwapi/inc/adodb/tests/test2.php
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Untitled</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
*/
|
||||
#
|
||||
# test connecting to 2 MySQL databases simultaneously and ensure that each connection
|
||||
# is independant.
|
||||
#
|
||||
include("../tohtml.inc.php");
|
||||
include("../adodb.inc.php");
|
||||
|
||||
ADOLoadCode('mysql');
|
||||
|
||||
$c1 = ADONewConnection('oci8');
|
||||
|
||||
if (!$c1->PConnect('','scott','tiger'))
|
||||
die("Cannot connect to server");
|
||||
$c1->debug=1;
|
||||
$rs = $c1->Execute('select rownum, p1.firstname,p2.lastname,p2.firstname,p1.lastname from adoxyz p1, adoxyz p2');
|
||||
print "Records=".$rs->RecordCount()."<br><pre>";
|
||||
//$rs->_array = false;
|
||||
//$rs->connection = false;
|
||||
//print_r($rs);
|
||||
rs2html($rs);
|
||||
?>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
44
phpgwapi/inc/adodb/tests/test3.php
Normal file
44
phpgwapi/inc/adodb/tests/test3.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 8.
|
||||
*/
|
||||
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$path = dirname(__FILE__);
|
||||
|
||||
include("$path/../adodb-exceptions.inc.php");
|
||||
include("$path/../adodb.inc.php");
|
||||
|
||||
try {
|
||||
$db = NewADOConnection("oci8");
|
||||
$db->Connect('','scott','natsoft');
|
||||
$db->debug=1;
|
||||
|
||||
$cnt = $db->GetOne("select count(*) from adoxyz");
|
||||
$rs = $db->Execute("select * from adoxyz order by id");
|
||||
|
||||
$i = 0;
|
||||
foreach($rs as $k => $v) {
|
||||
$i += 1;
|
||||
echo $k; adodb_pr($v);
|
||||
flush();
|
||||
}
|
||||
|
||||
if ($i != $cnt) die("actual cnt is $i, cnt should be $cnt\n");
|
||||
|
||||
|
||||
|
||||
$rs = $db->Execute("select bad from badder");
|
||||
|
||||
} catch (exception $e) {
|
||||
adodb_pr($e);
|
||||
$e = adodb_backtrace($e->trace);
|
||||
}
|
||||
|
||||
?>
|
95
phpgwapi/inc/adodb/tests/test4.php
Normal file
95
phpgwapi/inc/adodb/tests/test4.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @version V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
* Released under both BSD license and Lesser GPL library license.
|
||||
* Whenever there is any discrepancy between the two licenses,
|
||||
* the BSD license will take precedence.
|
||||
*
|
||||
* Set tabs to 4 for best viewing.
|
||||
*
|
||||
* Latest version is available at http://php.weblogs.com
|
||||
*
|
||||
* Test GetUpdateSQL and GetInsertSQL.
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
function testsql()
|
||||
{
|
||||
|
||||
//define('ADODB_FORCE_NULLS',1);
|
||||
|
||||
include('../adodb.inc.php');
|
||||
include('../tohtml.inc.php');
|
||||
|
||||
//==========================
|
||||
// This code tests an insert
|
||||
|
||||
$sql = "
|
||||
SELECT *
|
||||
FROM ADOXYZ WHERE id = -1";
|
||||
// Select an empty record from the database
|
||||
|
||||
$conn = &ADONewConnection("mysql"); // create a connection
|
||||
$conn->PConnect("localhost", "root", "", "test"); // connect to MySQL, testdb
|
||||
|
||||
//$conn =& ADONewConnection('oci8');
|
||||
//$conn->Connect('','scott','natsoft');
|
||||
//$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
|
||||
|
||||
$conn->debug=1;
|
||||
$conn->Execute("delete from adoxyz where lastname like 'Smith%'");
|
||||
|
||||
$rs = $conn->Execute($sql); // Execute the query and get the empty recordset
|
||||
$record = array(); // Initialize an array to hold the record data to insert
|
||||
|
||||
// Set the values for the fields in the record
|
||||
$record["firstname"] = 'null';
|
||||
$record["lastname"] = "Smith\$@//";
|
||||
$record["created"] = time();
|
||||
//$record["id"] = -1;
|
||||
|
||||
// Pass the empty recordset and the array containing the data to insert
|
||||
// into the GetInsertSQL function. The function will process the data and return
|
||||
// a fully formatted insert sql statement.
|
||||
$insertSQL = $conn->GetInsertSQL($rs, $record);
|
||||
|
||||
$conn->Execute($insertSQL); // Insert the record into the database
|
||||
|
||||
$insertSQL2 = $conn->GetInsertSQL($table='ADOXYZ', $record);
|
||||
if ($insertSQL != $insertSQL2) echo "<p><b>Walt's new stuff failed</b>: $insertSQL2</p>";
|
||||
//==========================
|
||||
// This code tests an update
|
||||
|
||||
$sql = "
|
||||
SELECT *
|
||||
FROM ADOXYZ WHERE lastname=".$conn->qstr($record['lastname']). " ORDER BY 1";
|
||||
// Select a record to update
|
||||
|
||||
$rs = $conn->Execute($sql); // Execute the query and get the existing record to update
|
||||
if (!$rs) print "<p><b>No record found!</b></p>";
|
||||
|
||||
$record = array(); // Initialize an array to hold the record data to update
|
||||
|
||||
// Set the values for the fields in the record
|
||||
$record["firstName"] = "Caroline".rand();
|
||||
$record["lasTname"] = "Smithy Jones"; // Update Caroline's lastname from Miranda to Smith
|
||||
$record["creAted"] = '2002-12-'.(rand()%30+1);
|
||||
$record['num'] = 3921;
|
||||
// Pass the single record recordset and the array containing the data to update
|
||||
// into the GetUpdateSQL function. The function will process the data and return
|
||||
// a fully formatted update sql statement.
|
||||
// If the data has not changed, no recordset is returned
|
||||
$updateSQL = $conn->GetUpdateSQL($rs, $record);
|
||||
|
||||
$conn->Execute($updateSQL); // Update the record in the database
|
||||
if ($conn->Affected_Rows() != 1)print "<p><b>Error</b>: Rows Affected=".$conn->Affected_Rows().", should be 1</p>";
|
||||
|
||||
$rs = $conn->Execute("select * from adoxyz where lastname like 'Smith%'");
|
||||
adodb_pr($rs);
|
||||
rs2html($rs);
|
||||
}
|
||||
|
||||
|
||||
testsql();
|
||||
?>
|
47
phpgwapi/inc/adodb/tests/test5.php
Normal file
47
phpgwapi/inc/adodb/tests/test5.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
// Select an empty record from the database
|
||||
|
||||
include('../adodb.inc.php');
|
||||
include('../tohtml.inc.php');
|
||||
|
||||
include('../adodb-errorpear.inc.php');
|
||||
|
||||
if (0) {
|
||||
$conn = &ADONewConnection('mysql');
|
||||
$conn->debug=1;
|
||||
$conn->PConnect("localhost","root","","xphplens");
|
||||
print $conn->databaseType.':'.$conn->GenID().'<br>';
|
||||
}
|
||||
|
||||
if (0) {
|
||||
$conn = &ADONewConnection("oci8"); // create a connection
|
||||
$conn->debug=1;
|
||||
$conn->PConnect("falcon", "scott", "tiger", "juris8.ecosystem.natsoft.com.my"); // connect to MySQL, testdb
|
||||
print $conn->databaseType.':'.$conn->GenID();
|
||||
}
|
||||
|
||||
if (0) {
|
||||
$conn = &ADONewConnection("ibase"); // create a connection
|
||||
$conn->debug=1;
|
||||
$conn->Connect("localhost:c:\\Interbase\\Examples\\Database\\employee.gdb", "sysdba", "masterkey", ""); // connect to MySQL, testdb
|
||||
print $conn->databaseType.':'.$conn->GenID().'<br>';
|
||||
}
|
||||
|
||||
if (0) {
|
||||
$conn = &ADONewConnection('postgres');
|
||||
$conn->debug=1;
|
||||
@$conn->PConnect("susetikus","tester","test","test");
|
||||
print $conn->databaseType.':'.$conn->GenID().'<br>';
|
||||
}
|
||||
?>
|
29
phpgwapi/inc/adodb/tests/testcache.php
Normal file
29
phpgwapi/inc/adodb/tests/testcache.php
Normal file
@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<body>
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
|
||||
$ADODB_CACHE_DIR = dirname(tempnam('/tmp',''));
|
||||
include("../adodb.inc.php");
|
||||
|
||||
if (isset($access)) {
|
||||
$db=ADONewConnection('access');
|
||||
$db->PConnect('nwind');
|
||||
} else {
|
||||
$db = ADONewConnection('mysql');
|
||||
$db->PConnect('mangrove','root','','xphplens');
|
||||
}
|
||||
if (isset($cache)) $rs = $db->CacheExecute(120,'select * from products');
|
||||
else $rs = $db->Execute('select * from products');
|
||||
|
||||
$arr = $rs->GetArray();
|
||||
print sizeof($arr);
|
||||
?>
|
300
phpgwapi/inc/adodb/tests/testdatabases.inc.php
Normal file
300
phpgwapi/inc/adodb/tests/testdatabases.inc.php
Normal file
@ -0,0 +1,300 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
*/
|
||||
|
||||
/* this file is used by the ADODB test program: test.php */
|
||||
?>
|
||||
|
||||
<table><tr valign=top><td>
|
||||
<form method=get>
|
||||
<input type=checkbox name="testaccess" value=1 <?php echo !empty($testaccess) ? 'checked' : '' ?>> <b>Access</b><br>
|
||||
<input type=checkbox name="testibase" value=1 <?php echo !empty($testibase) ? 'checked' : '' ?>> <b>Interbase</b><br>
|
||||
<input type=checkbox name="testmssql" value=1 <?php echo !empty($testmssql) ? 'checked' : '' ?>> <b>MSSQL</b><br>
|
||||
<input type=checkbox name="testmysql" value=1 <?php echo !empty($testmysql) ? 'checked' : '' ?>> <b>MySQL</b><br>
|
||||
<input type=checkbox name="testmysqlodbc" value=1 <?php echo !empty($testmysqlodbc) ? 'checked' : '' ?>> <b>MySQL ODBC</b><br>
|
||||
<td><input type=checkbox name="testsqlite" value=1 <?php echo !empty($testsqlite) ? 'checked' : '' ?>> <b>SQLite</b><br>
|
||||
<input type=checkbox name="testproxy" value=1 <?php echo !empty($testproxy) ? 'checked' : '' ?>> <b>MySQL Proxy</b><br>
|
||||
<input type=checkbox name="testoracle" value=1 <?php echo !empty($testoracle) ? 'checked' : '' ?>> <b>Oracle (oci8)</b> <br>
|
||||
<input type=checkbox name="testpostgres" value=1 <?php echo !empty($testpostgres) ? 'checked' : '' ?>> <b>PostgreSQL</b><br>
|
||||
<input type=checkbox name="testpgodbc" value=1 <?php echo !empty($testpgodbc) ? 'checked' : '' ?>> <b>PostgreSQL ODBC</b><br>
|
||||
<td><input type=checkbox name="testdb2" value=1 <?php echo !empty($testdb2) ? 'checked' : '' ?>> DB2<br>
|
||||
<input type=checkbox name="testvfp" value=1 <?php echo !empty($testvfp) ? 'checked' : '' ?>> VFP<br>
|
||||
<input type=checkbox name="testado" value=1 <?php echo !empty($testado) ? 'checked' : '' ?>> ADO (for mssql and access)<br>
|
||||
<input type=checkbox name="nocountrecs" value=1 <?php echo !empty($nocountrecs) ? 'checked' : '' ?>> $ADODB_COUNTRECS=false<br>
|
||||
<input type=checkbox name="nolog" value=1 <?php echo !empty($nolog) ? 'checked' : '' ?>> No SQL Logging<br>
|
||||
<td><input type=submit>
|
||||
</form>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
if ($ADODB_FETCH_MODE != ADODB_FETCH_DEFAULT) print "<h3>FETCH MODE IS NOT ADODB_FETCH_DEFAULT</h3>";
|
||||
|
||||
if (isset($nocountrecs)) $ADODB_COUNTRECS = false;
|
||||
|
||||
// cannot test databases below, but we include them anyway to check
|
||||
// if they parse ok...
|
||||
|
||||
if (!strpos(PHP_VERSION,'5') === 0) {
|
||||
ADOLoadCode("sybase");
|
||||
ADOLoadCode("postgres");
|
||||
ADOLoadCode("postgres7");
|
||||
ADOLoadCode("firebird");
|
||||
ADOLoadCode("borland_ibase");
|
||||
ADOLoadCode("informix");
|
||||
ADOLoadCode("sqlanywhere");
|
||||
// ADOLoadCode('mysqli');
|
||||
}
|
||||
|
||||
|
||||
flush();
|
||||
if (!empty($testpostgres)) {
|
||||
//ADOLoadCode("postgres");
|
||||
|
||||
$db = &ADONewConnection('postgres');
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if ($db->Connect("localhost","tester","test","test")) {
|
||||
testdb($db,"create table ADOXYZ (id integer, firstname char(24), lastname varchar,created date)");
|
||||
}else
|
||||
print "ERROR: PostgreSQL requires a database called test on server, user tester, password test.<BR>".$db->ErrorMsg();
|
||||
}
|
||||
|
||||
if (!empty($testpgodbc)) {
|
||||
|
||||
$db = &ADONewConnection('odbc');
|
||||
$db->hasTransactions = false;
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
|
||||
if ($db->PConnect('Postgresql')) {
|
||||
$db->hasTransactions = true;
|
||||
testdb($db,
|
||||
"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date) type=innodb");
|
||||
} else print "ERROR: PostgreSQL requires a database called test on server, user tester, password test.<BR>".$db->ErrorMsg();
|
||||
}
|
||||
|
||||
if (!empty($testibase)) {
|
||||
//$_GET['nolog'] = true;
|
||||
$db = &ADONewConnection('firebird');
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if ($db->PConnect("localhost:d:\\firebird\\10\\examples\\employee.gdb", "sysdba", "masterkey", ""))
|
||||
testdb($db,"create table ADOXYZ (id integer, firstname char(24), lastname char(24),price numeric(12,2),created date)");
|
||||
else print "ERROR: Interbase test requires a database called employee.gdb".'<BR>'.$db->ErrorMsg();
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!empty($testsqlite)) {
|
||||
$db = &ADONewConnection('sqlite');
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
|
||||
if ($db->PConnect("d:\\inetpub\\adodb\\sqlite.db", "", "", ""))
|
||||
testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
|
||||
else print "ERROR: SQLite";
|
||||
|
||||
}
|
||||
|
||||
// REQUIRES ODBC DSN CALLED nwind
|
||||
if (!empty($testaccess)) {
|
||||
$db = &ADONewConnection('access');
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
$access = 'd:\inetpub\wwwroot\php\NWIND.MDB';
|
||||
$dsn = "nwind";
|
||||
$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=$access;Uid=Admin;Pwd=;";
|
||||
|
||||
//$dsn = 'Provider=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=' . $access . ';';
|
||||
if ($db->PConnect($dsn, "", "", ""))
|
||||
testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
|
||||
else print "ERROR: Access test requires a Windows ODBC DSN=nwind, Access driver";
|
||||
|
||||
}
|
||||
|
||||
if (!empty($testaccess) && !empty($testado)) { // ADO ACCESS
|
||||
|
||||
$db = &ADONewConnection("ado_access");
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
|
||||
$access = 'd:\inetpub\wwwroot\php\NWIND.MDB';
|
||||
$myDSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;'
|
||||
. 'DATA SOURCE=' . $access . ';';
|
||||
//. 'USER ID=;PASSWORD=;';
|
||||
|
||||
if ($db->PConnect($myDSN, "", "", "")) {
|
||||
print "ADO version=".$db->_connectionID->version."<br>";
|
||||
testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
|
||||
} else print "ERROR: Access test requires a Access database $access".'<BR>'.$db->ErrorMsg();
|
||||
|
||||
}
|
||||
|
||||
if (!empty($testvfp)) { // ODBC
|
||||
$db = &ADONewConnection('vfp');
|
||||
print "<h1>Connecting $db->databaseType...</h1>";flush();
|
||||
|
||||
if ( $db->PConnect("vfp-adoxyz")) {
|
||||
testdb($db,"create table d:\\inetpub\\adodb\\ADOXYZ (id int, firstname char(24), lastname char(24),created date)");
|
||||
} else print "ERROR: Visual FoxPro test requires a Windows ODBC DSN=vfp-adoxyz, VFP driver";
|
||||
|
||||
}
|
||||
|
||||
|
||||
// REQUIRES MySQL server at localhost with database 'test'
|
||||
if (!empty($testmysql)) { // MYSQL
|
||||
|
||||
|
||||
if (PHP_VERSION >= 5 || $HTTP_SERVER_VARS['HTTP_HOST'] == 'localhost') $server = 'localhost';
|
||||
else $server = "mangrove";
|
||||
$user = 'root'; $password = ''; $database = 'northwind';
|
||||
$db = &ADONewConnection("mysql://$user:$password@$server/$database?persist");
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
|
||||
if (true || $db->PConnect($server, "root", "", "northwind")) {
|
||||
//$db->debug=1;$db->Execute('drop table ADOXYZ');
|
||||
testdb($db,
|
||||
"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
|
||||
} else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
|
||||
}
|
||||
|
||||
// REQUIRES MySQL server at localhost with database 'test'
|
||||
if (!empty($testmysqli)) { // MYSQL
|
||||
|
||||
$db = &ADONewConnection('mysqli');
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if (PHP_VERSION >= 5 || $HTTP_SERVER_VARS['HTTP_HOST'] == 'localhost') $server = 'localhost';
|
||||
else $server = "mangrove";
|
||||
if ($db->PConnect($server, "root", "", "northwind")) {
|
||||
//$db->debug=1;$db->Execute('drop table ADOXYZ');
|
||||
testdb($db,
|
||||
"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date)");
|
||||
} else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
|
||||
}
|
||||
|
||||
|
||||
// REQUIRES MySQL server at localhost with database 'test'
|
||||
if (!empty($testmysqlodbc)) { // MYSQL
|
||||
|
||||
$db = &ADONewConnection('odbc');
|
||||
$db->hasTransactions = false;
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if ($HTTP_SERVER_VARS['HTTP_HOST'] == 'localhost') $server = 'localhost';
|
||||
else $server = "mangrove";
|
||||
if ($db->PConnect('mysql', "root", ""))
|
||||
testdb($db,
|
||||
"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date) type=innodb");
|
||||
else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
|
||||
}
|
||||
|
||||
if (!empty($testproxy)){
|
||||
$db = &ADONewConnection('proxy');
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if ($HTTP_SERVER_VARS['HTTP_HOST'] == 'localhost') $server = 'localhost';
|
||||
|
||||
if ($db->PConnect('http://localhost/php/phplens/adodb/server.php'))
|
||||
testdb($db,
|
||||
"create table ADOXYZ (id int, firstname char(24), lastname char(24), created date) type=innodb");
|
||||
else print "ERROR: MySQL test requires a MySQL server on localhost, userid='admin', password='', database='test'".'<BR>'.$db->ErrorMsg();
|
||||
|
||||
}
|
||||
|
||||
ADOLoadCode('oci805');
|
||||
ADOLoadCode("oci8po");
|
||||
if (!empty($testoracle)) {
|
||||
$dsn = "oci8po://scott:natsoft@panther?persist";
|
||||
$db = ADONewConnection($dsn);
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if (true || $db->Connect('', "scott", "natsoft",''))
|
||||
testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
|
||||
else print "ERROR: Oracle test requires an Oracle server setup with scott/natsoft".'<BR>'.$db->ErrorMsg();
|
||||
|
||||
}
|
||||
ADOLoadCode("oracle"); // no longer supported
|
||||
if (false && !empty($testoracle)) {
|
||||
|
||||
$db = ADONewConnection();
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if ($db->PConnect("", "scott", "tiger", "natsoft.domain"))
|
||||
testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
|
||||
else print "ERROR: Oracle test requires an Oracle server setup with scott/tiger".'<BR>'.$db->ErrorMsg();
|
||||
|
||||
}
|
||||
|
||||
ADOLoadCode("db2"); // no longer supported
|
||||
if (!empty($testdb2)) {
|
||||
|
||||
$db = ADONewConnection();
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
if ($db->Connect("db2_sample", "root", "natsoft", ""))
|
||||
testdb($db,"create table ADOXYZ (id int, firstname varchar(24), lastname varchar(24),created date)");
|
||||
else print "ERROR: DB2 test requires an server setup with odbc data source db2_sample".'<BR>'.$db->ErrorMsg();
|
||||
|
||||
}
|
||||
|
||||
|
||||
ADOLoadCode('odbc_mssql');
|
||||
if (!empty($testmssql)) { // MS SQL Server via ODBC
|
||||
$db = ADONewConnection();
|
||||
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
|
||||
$dsn = "PROVIDER=MSDASQL;Driver={SQL Server};Server=localhost;Database=northwind;";
|
||||
|
||||
if ($db->PConnect($dsn, "adodb", "natsoft", "")) {
|
||||
testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
|
||||
}
|
||||
else print "ERROR: MSSQL test 1 requires a MS SQL 7 server setup with DSN setup";
|
||||
|
||||
}
|
||||
|
||||
ADOLoadCode("ado_mssql");
|
||||
|
||||
if (!empty($testmssql) && !empty($testado) ) { // ADO ACCESS MSSQL -- thru ODBC -- DSN-less
|
||||
|
||||
$db = &ADONewConnection("ado_mssql");
|
||||
//$db->debug=1;
|
||||
print "<h1>Connecting DSN-less $db->databaseType...</h1>";
|
||||
|
||||
$myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"
|
||||
. "SERVER=tigress;DATABASE=NorthWind;UID=adodb;PWD=natsoft;Trusted_Connection=No" ;
|
||||
|
||||
|
||||
if ($db->PConnect($myDSN, "", "", ""))
|
||||
testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
|
||||
else print "ERROR: MSSQL test 2 requires MS SQL 7";
|
||||
|
||||
}
|
||||
|
||||
|
||||
ADOLoadCode("mssqlpo");
|
||||
if (!empty($testmssql)) { // MS SQL Server -- the extension is buggy -- probably better to use ODBC
|
||||
$db = ADONewConnection("mssqlpo");
|
||||
//$db->debug=1;
|
||||
print "<h1>Connecting $db->databaseType...</h1>";
|
||||
|
||||
$ok = $db->PConnect('tigress','adodb','natsoft','northwind');
|
||||
|
||||
if ($ok or $db->PConnect("mangrove", "sa", "natsoft", "ai")) {
|
||||
AutoDetect_MSSQL_Date_Order($db);
|
||||
// $db->Execute('drop table adoxyz');
|
||||
testdb($db,"create table ADOXYZ (id int, firstname char(24) null, lastname char(24) null,created datetime null)");
|
||||
} else print "ERROR: MSSQL test 2 requires a MS SQL 7 on a server='192.168.0.1', userid='sa', password='natsoft', database='ai'".'<BR>'.$db->ErrorMsg();
|
||||
|
||||
}
|
||||
|
||||
if (!empty($testmssql) && !empty($testado)) { // ADO ACCESS MSSQL with OLEDB provider
|
||||
|
||||
$db = &ADONewConnection("ado_mssql");
|
||||
print "<h1>Connecting DSN-less OLEDB Provider $db->databaseType...</h1>";
|
||||
//$db->debug=1;
|
||||
$myDSN="SERVER=tigress;DATABASE=northwind;Trusted_Connection=yes";
|
||||
if ($db->PConnect($myDSN, "adodb", "natsoft", 'SQLOLEDB'))
|
||||
testdb($db,"create table ADOXYZ (id int, firstname char(24), lastname char(24),created datetime)");
|
||||
else print "ERROR: MSSQL test 2 requires a MS SQL 7 on a server='mangrove', userid='sa', password='', database='ai'";
|
||||
|
||||
}
|
||||
|
||||
|
||||
print "<h3>Tests Completed</h3>";
|
||||
|
||||
?>
|
83
phpgwapi/inc/adodb/tests/testoci8.php
Normal file
83
phpgwapi/inc/adodb/tests/testoci8.php
Normal file
@ -0,0 +1,83 @@
|
||||
<html>
|
||||
<body>
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
error_reporting(63);
|
||||
include("../adodb.inc.php");
|
||||
include("../tohtml.inc.php");
|
||||
|
||||
if (0) {
|
||||
$db = ADONewConnection('oci8po');
|
||||
|
||||
$db->PConnect('','scott','natsoft');
|
||||
if (!empty($testblob)) {
|
||||
$varHoldingBlob = 'ABC DEF GEF John TEST';
|
||||
$num = time()%10240;
|
||||
// create table atable (id integer, ablob blob);
|
||||
$db->Execute('insert into ATABLE (id,ablob) values('.$num.',empty_blob())');
|
||||
$db->UpdateBlob('ATABLE', 'ablob', $varHoldingBlob, 'id='.$num, 'BLOB');
|
||||
|
||||
$rs = &$db->Execute('select * from atable');
|
||||
|
||||
if (!$rs) die("Empty RS");
|
||||
if ($rs->EOF) die("EOF RS");
|
||||
rs2html($rs);
|
||||
}
|
||||
$stmt = $db->Prepare('select * from adoxyz where id=?');
|
||||
for ($i = 1; $i <= 10; $i++) {
|
||||
$rs = &$db->Execute(
|
||||
$stmt,
|
||||
array($i));
|
||||
|
||||
if (!$rs) die("Empty RS");
|
||||
if ($rs->EOF) die("EOF RS");
|
||||
rs2html($rs);
|
||||
}
|
||||
}
|
||||
if (1) {
|
||||
$db = ADONewConnection('oci8');
|
||||
$db->PConnect('','scott','natsoft');
|
||||
$db->debug = true;
|
||||
$db->Execute("delete from emp where ename='John'");
|
||||
print $db->Affected_Rows().'<BR>';
|
||||
$stmt = &$db->Prepare('insert into emp (empno, ename) values (:empno, :ename)');
|
||||
$rs = $db->Execute($stmt,array('empno'=>4321,'ename'=>'John'));
|
||||
// prepare not quite ready for prime time
|
||||
//$rs = $db->Execute($stmt,array('empno'=>3775,'ename'=>'John'));
|
||||
if (!$rs) die("Empty RS");
|
||||
|
||||
$db->setfetchmode(ADODB_FETCH_NUM);
|
||||
|
||||
$vv = 'A%';
|
||||
$stmt = $db->PrepareSP("BEGIN adodb.open_tab2(:rs,:tt); END;",true);
|
||||
$db->OutParameter($stmt, $cur, 'rs', -1, OCI_B_CURSOR);
|
||||
$db->OutParameter($stmt, $vv, 'tt');
|
||||
$rs = $db->Execute($stmt);
|
||||
while (!$rs->EOF) {
|
||||
adodb_pr($rs->fields);
|
||||
$rs->MoveNext();
|
||||
}
|
||||
echo " val = $vv";
|
||||
|
||||
}
|
||||
|
||||
if (0) {
|
||||
$db = ADONewConnection('odbc_oracle');
|
||||
if (!$db->PConnect('local_oracle','scott','tiger')) die('fail connect');
|
||||
$db->debug = true;
|
||||
$rs = &$db->Execute(
|
||||
'select * from adoxyz where firstname=? and trim(lastname)=?',
|
||||
array('first'=>'Caroline','last'=>'Miranda'));
|
||||
if (!$rs) die("Empty RS");
|
||||
if ($rs->EOF) die("EOF RS");
|
||||
rs2html($rs);
|
||||
}
|
||||
?>
|
111
phpgwapi/inc/adodb/tests/testoci8cursor.php
Normal file
111
phpgwapi/inc/adodb/tests/testoci8cursor.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
|
||||
/*
|
||||
Test for Oracle Variable Cursors, which are treated as ADOdb recordsets.
|
||||
|
||||
We have 2 examples. The first shows us using the Parameter statement.
|
||||
The second shows us using the new ExecuteCursor($sql, $cursorName)
|
||||
function.
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- TEST PACKAGE YOU NEED TO INSTALL ON ORACLE - run from sql*plus
|
||||
------------------------------------------------------------------
|
||||
|
||||
|
||||
-- TEST PACKAGE
|
||||
CREATE OR REPLACE PACKAGE adodb AS
|
||||
TYPE TabType IS REF CURSOR RETURN tab%ROWTYPE;
|
||||
PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar);
|
||||
PROCEDURE data_out(input IN varchar, output OUT varchar);
|
||||
|
||||
procedure myproc (p1 in number, p2 out number);
|
||||
END adodb;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE BODY adodb AS
|
||||
PROCEDURE open_tab (tabcursor IN OUT TabType,tablenames in varchar) IS
|
||||
BEGIN
|
||||
OPEN tabcursor FOR SELECT * FROM tab where tname like tablenames;
|
||||
END open_tab;
|
||||
|
||||
PROCEDURE data_out(input IN varchar, output OUT varchar) IS
|
||||
BEGIN
|
||||
output := 'Cinta Hati '||input;
|
||||
END;
|
||||
|
||||
procedure myproc (p1 in number, p2 out number) as
|
||||
begin
|
||||
p2 := p1;
|
||||
end;
|
||||
END adodb;
|
||||
/
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- END PACKAGE
|
||||
------------------------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
include('../adodb.inc.php');
|
||||
include('../tohtml.inc.php');
|
||||
|
||||
error_reporting(E_ALL);
|
||||
$db = ADONewConnection('oci8');
|
||||
$db->PConnect('','scott','natsoft');
|
||||
$db->debug = 99;
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
define('MYNUM',5);
|
||||
|
||||
|
||||
$rs = $db->ExecuteCursor("BEGIN adodb.open_tab(:RS,'A%'); END;");
|
||||
|
||||
if ($rs && !$rs->EOF) {
|
||||
print "Test 1 RowCount: ".$rs->RecordCount()."<p>";
|
||||
} else {
|
||||
print "<b>Error in using Cursor Variables 1</b><p>";
|
||||
}
|
||||
|
||||
print "<h4>Testing Stored Procedures for oci8</h4>";
|
||||
|
||||
$stid = $db->PrepareSP('BEGIN adodb.myproc('.MYNUM.', :myov); END;');
|
||||
$db->OutParameter($stid, $myov, 'myov');
|
||||
$db->Execute($stid);
|
||||
if ($myov != MYNUM) print "<p><b>Error with myproc</b></p>";
|
||||
|
||||
|
||||
$stmt = $db->PrepareSP("BEGIN adodb.data_out(:a1, :a2); END;",true);
|
||||
$a1 = 'Malaysia';
|
||||
//$a2 = ''; # a2 doesn't even need to be defined!
|
||||
$db->InParameter($stmt,$a1,'a1');
|
||||
$db->OutParameter($stmt,$a2,'a2');
|
||||
$rs = $db->Execute($stmt);
|
||||
if ($rs) {
|
||||
if ($a2 !== 'Cinta Hati Malaysia') print "<b>Stored Procedure Error: a2 = $a2</b><p>";
|
||||
else echo "OK: a2=$a2<p>";
|
||||
} else {
|
||||
print "<b>Error in using Stored Procedure IN/Out Variables</b><p>";
|
||||
}
|
||||
|
||||
|
||||
$tname = 'A%';
|
||||
|
||||
$stmt = $db->PrepareSP('select * from tab where tname like :tablename');
|
||||
$db->Parameter($stmt,$tname,'tablename');
|
||||
$rs = $db->Execute($stmt);
|
||||
rs2html($rs);
|
||||
|
||||
|
||||
?>
|
83
phpgwapi/inc/adodb/tests/testpaging.php
Normal file
83
phpgwapi/inc/adodb/tests/testpaging.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
|
||||
include_once('../adodb.inc.php');
|
||||
include_once('../adodb-pager.inc.php');
|
||||
|
||||
$driver = 'oci8';
|
||||
$sql = 'select ID, firstname as "First Name", lastname as "Last Name" from adoxyz order by id';
|
||||
//$sql = 'select count(*),firstname from adoxyz group by firstname order by 2 ';
|
||||
$sql = 'select distinct firstname, lastname from adoxyz order by firstname';
|
||||
|
||||
if ($driver == 'postgres') {
|
||||
$db = NewADOConnection('postgres');
|
||||
$db->PConnect('localhost','tester','test','test');
|
||||
}
|
||||
|
||||
if ($driver == 'access') {
|
||||
$db = NewADOConnection('access');
|
||||
$db->PConnect("nwind", "", "", "");
|
||||
}
|
||||
|
||||
if ($driver == 'ibase') {
|
||||
$db = NewADOConnection('ibase');
|
||||
$db->PConnect("localhost:e:\\firebird\\examples\\employee.gdb", "sysdba", "masterkey", "");
|
||||
$sql = 'select distinct firstname, lastname from adoxyz order by firstname';
|
||||
|
||||
}
|
||||
if ($driver == 'mssql') {
|
||||
$db = NewADOConnection('mssql');
|
||||
$db->Connect('JAGUAR\vsdotnet','adodb','natsoft','northwind');
|
||||
}
|
||||
if ($driver == 'oci8') {
|
||||
$db = NewADOConnection('oci8');
|
||||
$db->Connect('','scott','natsoft');
|
||||
}
|
||||
|
||||
if ($driver == 'access') {
|
||||
$db = NewADOConnection('access');
|
||||
$db->Connect('nwind');
|
||||
}
|
||||
|
||||
if (empty($driver) or $driver == 'mysql') {
|
||||
$db = NewADOConnection('mysql');
|
||||
$db->Connect('localhost','root','','xphplens');
|
||||
}
|
||||
|
||||
//$db->pageExecuteCountRows = false;
|
||||
|
||||
$db->debug = true;
|
||||
|
||||
if (0) {
|
||||
$rs = &$db->Execute($sql);
|
||||
include_once('../toexport.inc.php');
|
||||
print "<pre>";
|
||||
print rs2csv($rs); # return a string
|
||||
|
||||
print '<hr>';
|
||||
$rs->MoveFirst(); # note, some databases do not support MoveFirst
|
||||
print rs2tab($rs); # return a string
|
||||
|
||||
print '<hr>';
|
||||
$rs->MoveFirst();
|
||||
rs2tabout($rs); # send to stdout directly
|
||||
print "</pre>";
|
||||
}
|
||||
|
||||
$pager = new ADODB_Pager($db,$sql);
|
||||
$pager->showPageLinks = true;
|
||||
$pager->linksPerPage = 3;
|
||||
$pager->cache = 60;
|
||||
$pager->Render($rows=7);
|
||||
?>
|
34
phpgwapi/inc/adodb/tests/testpear.php
Normal file
34
phpgwapi/inc/adodb/tests/testpear.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
include_once('../adodb-pear.inc.php');
|
||||
$username = 'root';
|
||||
$password = '';
|
||||
$hostname = 'localhost';
|
||||
$databasename = 'xphplens';
|
||||
$driver = 'mysql';
|
||||
|
||||
$dsn = "$driver://$username:$password@$hostname/$databasename";
|
||||
|
||||
$db = DB::Connect($dsn);
|
||||
$db->setFetchMode(ADODB_FETCH_ASSOC);
|
||||
$rs = $db->Query('select firstname,lastname from adoxyz');
|
||||
$cnt = 0;
|
||||
while ($arr = $rs->FetchRow()) {
|
||||
print_r($arr);
|
||||
print "<br>";
|
||||
$cnt += 1;
|
||||
}
|
||||
|
||||
if ($cnt != 50) print "<b>Error in \$cnt = $cnt</b>";
|
||||
?>
|
73
phpgwapi/inc/adodb/tests/testsessions.php
Normal file
73
phpgwapi/inc/adodb/tests/testsessions.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
Set tabs to 4 for best viewing.
|
||||
|
||||
Latest version is available at http://adodb.sourceforge.net
|
||||
*/
|
||||
|
||||
function NotifyExpire($ref,$key)
|
||||
{
|
||||
print "<p><b>Notify Expiring=$ref, sessionkey=$key</b></p>";
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
#### CONNECTION
|
||||
if (1) {
|
||||
$ADODB_SESSION_DRIVER='oci8';
|
||||
$ADODB_SESSION_CONNECT='';
|
||||
$ADODB_SESSION_USER ='scott';
|
||||
$ADODB_SESSION_PWD ='natsoft';
|
||||
$ADODB_SESSION_DB ='';
|
||||
} else {
|
||||
$ADODB_SESSION_DRIVER='mysql';
|
||||
$ADODB_SESSION_CONNECT='localhost';
|
||||
$ADODB_SESSION_USER ='root';
|
||||
$ADODB_SESSION_PWD ='';
|
||||
$ADODB_SESSION_DB ='xphplens_2';
|
||||
}
|
||||
|
||||
### TURN DEBUGGING ON
|
||||
$ADODB_SESS_DEBUG = true;
|
||||
|
||||
|
||||
#### SETUP NOTIFICATION
|
||||
$USER = 'JLIM'.rand();
|
||||
$ADODB_SESSION_EXPIRE_NOTIFY = array('USER','NotifyExpire');
|
||||
|
||||
|
||||
#### INIT
|
||||
ob_start();
|
||||
error_reporting(E_ALL);
|
||||
include('../session/adodb-cryptsession.php');
|
||||
session_start();
|
||||
|
||||
|
||||
### SETUP SESSION VARIABLES
|
||||
$HTTP_SESSION_VARS['MONKEY'] = array('1','abc',44.41);
|
||||
if (!isset($HTTP_GET_VARS['nochange'])) @$HTTP_SESSION_VARS['AVAR'] += 1;
|
||||
|
||||
|
||||
### START DISPLAY
|
||||
print "<h3>PHP ".PHP_VERSION."</h3>";
|
||||
print "<p><b>\$HTTP_SESSION_VARS['AVAR']={$HTTP_SESSION_VARS['AVAR']}</b></p>";
|
||||
|
||||
print "<hr> <b>Cookies</b>: ";
|
||||
print_r($HTTP_COOKIE_VARS);
|
||||
|
||||
### RANDOMLY PERFORM Garbage Collection
|
||||
if (rand() % 10 == 0) {
|
||||
|
||||
print "<hr><p><b>Garbage Collection</b></p>";
|
||||
adodb_sess_gc(10);
|
||||
|
||||
print "<p>Random session destroy</p>";
|
||||
session_destroy();
|
||||
}
|
||||
?>
|
181
phpgwapi/inc/adodb/tohtml.inc.php
Normal file
181
phpgwapi/inc/adodb/tohtml.inc.php
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/*
|
||||
V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
|
||||
Released under both BSD license and Lesser GPL library license.
|
||||
Whenever there is any discrepancy between the two licenses,
|
||||
the BSD license will take precedence.
|
||||
|
||||
Some pretty-printing by Chris Oxenreider <oxenreid@state.net>
|
||||
*/
|
||||
|
||||
// specific code for tohtml
|
||||
GLOBAL $gSQLMaxRows,$gSQLBlockRows;
|
||||
|
||||
$gSQLMaxRows = 1000; // max no of rows to download
|
||||
$gSQLBlockRows=20; // max no of rows per table block
|
||||
|
||||
// RecordSet to HTML Table
|
||||
//------------------------------------------------------------
|
||||
// Convert a recordset to a html table. Multiple tables are generated
|
||||
// if the number of rows is > $gSQLBlockRows. This is because
|
||||
// web browsers normally require the whole table to be downloaded
|
||||
// before it can be rendered, so we break the output into several
|
||||
// smaller faster rendering tables.
|
||||
//
|
||||
// $rs: the recordset
|
||||
// $ztabhtml: the table tag attributes (optional)
|
||||
// $zheaderarray: contains the replacement strings for the headers (optional)
|
||||
//
|
||||
// USAGE:
|
||||
// include('adodb.inc.php');
|
||||
// $db = ADONewConnection('mysql');
|
||||
// $db->Connect('mysql','userid','password','database');
|
||||
// $rs = $db->Execute('select col1,col2,col3 from table');
|
||||
// rs2html($rs, 'BORDER=2', array('Title1', 'Title2', 'Title3'));
|
||||
// $rs->Close();
|
||||
//
|
||||
// RETURNS: number of rows displayed
|
||||
function rs2html(&$rs,$ztabhtml=false,$zheaderarray=false,$htmlspecialchars=true,$echo = true)
|
||||
{
|
||||
$s ='';$rows=0;$docnt = false;
|
||||
GLOBAL $gSQLMaxRows,$gSQLBlockRows;
|
||||
|
||||
if (!$rs) {
|
||||
printf(ADODB_BAD_RS,'rs2html');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $ztabhtml) $ztabhtml = "BORDER='1' WIDTH='98%'";
|
||||
//else $docnt = true;
|
||||
$typearr = array();
|
||||
$ncols = $rs->FieldCount();
|
||||
$hdr = "<TABLE COLS=$ncols $ztabhtml><tr>\n\n";
|
||||
for ($i=0; $i < $ncols; $i++) {
|
||||
$field = $rs->FetchField($i);
|
||||
if ($zheaderarray) $fname = $zheaderarray[$i];
|
||||
else $fname = htmlspecialchars($field->name);
|
||||
$typearr[$i] = $rs->MetaType($field->type,$field->max_length);
|
||||
//print " $field->name $field->type $typearr[$i] ";
|
||||
|
||||
if (strlen($fname)==0) $fname = ' ';
|
||||
$hdr .= "<TH>$fname</TH>";
|
||||
}
|
||||
$hdr .= "\n</tr>";
|
||||
if ($echo) print $hdr."\n\n";
|
||||
else $html = $hdr;
|
||||
|
||||
// smart algorithm - handles ADODB_FETCH_MODE's correctly by probing...
|
||||
$numoffset = isset($rs->fields[0]) ||isset($rs->fields[1]) || isset($rs->fields[2]);
|
||||
while (!$rs->EOF) {
|
||||
|
||||
$s .= "<TR valign=top>\n";
|
||||
|
||||
for ($i=0; $i < $ncols; $i++) {
|
||||
if ($i===0) $v=($numoffset) ? $rs->fields[0] : reset($rs->fields);
|
||||
else $v = ($numoffset) ? $rs->fields[$i] : next($rs->fields);
|
||||
|
||||
$type = $typearr[$i];
|
||||
switch($type) {
|
||||
case 'D':
|
||||
if (!strpos($v,':')) {
|
||||
$s .= " <TD>".$rs->UserDate($v,"D d, M Y") ." </TD>\n";
|
||||
break;
|
||||
}
|
||||
case 'T':
|
||||
$s .= " <TD>".$rs->UserTimeStamp($v,"D d, M Y, h:i:s") ." </TD>\n";
|
||||
break;
|
||||
case 'I':
|
||||
case 'N':
|
||||
$s .= " <TD align=right>".stripslashes((trim($v))) ." </TD>\n";
|
||||
|
||||
break;
|
||||
/*
|
||||
case 'B':
|
||||
if (substr($v,8,2)=="BM" ) $v = substr($v,8);
|
||||
$mtime = substr(str_replace(' ','_',microtime()),2);
|
||||
$tmpname = "tmp/".uniqid($mtime).getmypid();
|
||||
$fd = @fopen($tmpname,'a');
|
||||
@ftruncate($fd,0);
|
||||
@fwrite($fd,$v);
|
||||
@fclose($fd);
|
||||
if (!function_exists ("mime_content_type")) {
|
||||
function mime_content_type ($file) {
|
||||
return exec("file -bi ".escapeshellarg($file));
|
||||
}
|
||||
}
|
||||
$t = mime_content_type($tmpname);
|
||||
$s .= (substr($t,0,5)=="image") ? " <td><img src='$tmpname' alt='$t'></td>\\n" : " <td><a
|
||||
href='$tmpname'>$t</a></td>\\n";
|
||||
break;
|
||||
*/
|
||||
|
||||
default:
|
||||
if ($htmlspecialchars) $v = htmlspecialchars(trim($v));
|
||||
$v = trim($v);
|
||||
if (strlen($v) == 0) $v = ' ';
|
||||
$s .= " <TD>". str_replace("\n",'<br>',stripslashes($v)) ."</TD>\n";
|
||||
|
||||
}
|
||||
} // for
|
||||
$s .= "</TR>\n\n";
|
||||
|
||||
$rows += 1;
|
||||
if ($rows >= $gSQLMaxRows) {
|
||||
$rows = "<p>Truncated at $gSQLMaxRows</p>";
|
||||
break;
|
||||
} // switch
|
||||
|
||||
$rs->MoveNext();
|
||||
|
||||
// additional EOF check to prevent a widow header
|
||||
if (!$rs->EOF && $rows % $gSQLBlockRows == 0) {
|
||||
|
||||
//if (connection_aborted()) break;// not needed as PHP aborts script, unlike ASP
|
||||
if ($echo) print $s . "</TABLE>\n\n";
|
||||
else $html .= $s ."</TABLE>\n\n";
|
||||
$s = $hdr;
|
||||
}
|
||||
} // while
|
||||
|
||||
if ($echo) print $s."</TABLE>\n\n";
|
||||
else $html .= $s."</TABLE>\n\n";
|
||||
|
||||
if ($docnt) if ($echo) print "<H2>".$rows." Rows</H2>";
|
||||
|
||||
return ($echo) ? $rows : $html;
|
||||
}
|
||||
|
||||
// pass in 2 dimensional array
|
||||
function arr2html(&$arr,$ztabhtml='',$zheaderarray='')
|
||||
{
|
||||
if (!$ztabhtml) $ztabhtml = 'BORDER=1';
|
||||
|
||||
$s = "<TABLE $ztabhtml>";//';print_r($arr);
|
||||
|
||||
if ($zheaderarray) {
|
||||
$s .= '<TR>';
|
||||
for ($i=0; $i<sizeof($zheaderarray); $i++) {
|
||||
$s .= " <TH>{$zheaderarray[$i]}</TH>\n";
|
||||
}
|
||||
$s .= "\n</TR>";
|
||||
}
|
||||
|
||||
for ($i=0; $i<sizeof($arr); $i++) {
|
||||
$s .= '<TR>';
|
||||
$a = &$arr[$i];
|
||||
if (is_array($a))
|
||||
for ($j=0; $j<sizeof($a); $j++) {
|
||||
$val = $a[$j];
|
||||
if (empty($val)) $val = ' ';
|
||||
$s .= " <TD>$val</TD>\n";
|
||||
}
|
||||
else if ($a) {
|
||||
$s .= ' <TD>'.$a."</TD>\n";
|
||||
} else $s .= " <TD> </TD>\n";
|
||||
$s .= "\n</TR>\n";
|
||||
}
|
||||
$s .= '</TABLE>';
|
||||
print $s;
|
||||
}
|
||||
|
||||
?>
|
38
phpgwapi/inc/adodb/xmlschema.dtd
Normal file
38
phpgwapi/inc/adodb/xmlschema.dtd
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE adodb_schema [
|
||||
<!ELEMENT schema (table*, sql*)>
|
||||
<!ATTLIST schema version CDATA #REQUIRED>
|
||||
<!ELEMENT table ((field+|DROP), constraint*, descr?, index*, data*)>
|
||||
<!ELEMENT field ((NOTNULL|KEY|PRIMARY)?, (AUTO|AUTOINCREMENT)?, (DEFAULT|DEFDATE|DEFTIMESTAMP)?, NOQUOTE, constraint, descr?)>
|
||||
<!ELEMENT data (row+)>
|
||||
<!ELEMENT row (f+)>
|
||||
<!ELEMENT f (#CDATA)>
|
||||
<!ELEMENT descr (#CDATA)>
|
||||
<!ELEMENT NOTNULL EMPTY>
|
||||
<!ELEMENT KEY EMPTY>
|
||||
<!ELEMENT PRIMARY EMPTY>
|
||||
<!ELEMENT AUTO EMPTY>
|
||||
<!ELEMENT AUTOINCREMENT EMPTY>
|
||||
<!ELEMENT DEFAULT EMPTY>
|
||||
<!ELEMENT DEFDATE EMPTY>
|
||||
<!ELEMENT DEFTIMESTAMP EMPTY>
|
||||
<!ELEMENT NOQUOTE EMPTY>
|
||||
<!ELEMENT DROP EMPTY>
|
||||
<!ELEMENT constraint (#CDATA)>
|
||||
<!ATTLIST table name CDATA #REQUIRED platform CDATA #IMPLIED version CDATA #IMPLIED>
|
||||
<!ATTLIST field name CDATA #REQUIRED type (C|C2|X|X2|B|D|T|L|I|F|N) #REQUIRED size CDATA #IMPLIED>
|
||||
<!ATTLIST data platform CDATA #IMPLIED>
|
||||
<!ATTLIST f name CDATA #IMPLIED>
|
||||
<!ATTLIST DEFAULT value CDATA #REQUIRED>
|
||||
<!ELEMENT index ((col+|DROP), CLUSTERED?, BITMAP?, UNIQUE?, FULLTEXT?, HASH?, descr?)>
|
||||
<!ELEMENT col (#CDATA)>
|
||||
<!ELEMENT CLUSTERED EMPTY>
|
||||
<!ELEMENT BITMAP EMPTY>
|
||||
<!ELEMENT UNIQUE EMPTY>
|
||||
<!ELEMENT FULLTEXT EMPTY>
|
||||
<!ELEMENT HASH EMPTY>
|
||||
<!ATTLIST index name CDATA #REQUIRED platform CDATA #IMPLIED>
|
||||
<!ELEMENT sql (query+, descr?)>
|
||||
<!ELEMENT query (#CDATA)>
|
||||
<!ATTLIST sql name CDATA #IMPLIED platform CDATA #IMPLIED, key CDATA, prefixmethod (AUTO|MANUAL|NONE) >
|
||||
] >
|
54
phpgwapi/inc/adodb/xsl/remove-0.2.xsl
Normal file
54
phpgwapi/inc/adodb/xsl/remove-0.2.xsl
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
>
|
||||
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/>
|
||||
|
||||
<!-- Schema -->
|
||||
<xsl:template match="/">
|
||||
<xsl:comment>
|
||||
ADODB XMLSchema
|
||||
http://adodb-xmlschema.sourceforge.net
|
||||
</xsl:comment>
|
||||
|
||||
<xsl:comment>
|
||||
Uninstallation Schema
|
||||
</xsl:comment>
|
||||
|
||||
<xsl:element name="schema">
|
||||
<xsl:attribute name="version">0.2</xsl:attribute>
|
||||
|
||||
<xsl:apply-templates select="schema/table">
|
||||
<xsl:sort select="position()" data-type="number" order="descending"/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Table -->
|
||||
<xsl:template match="table">
|
||||
<xsl:if test="count(DROP) = 0">
|
||||
<xsl:element name="table">
|
||||
<xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
|
||||
|
||||
<xsl:if test="string-length(@platform) > 0">
|
||||
<xsl:attribute name="platform"><xsl:value-of select="@platform"/></xsl:attribute>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:if test="string-length(@version) > 0">
|
||||
<xsl:attribute name="version"><xsl:value-of select="@version"/></xsl:attribute>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:apply-templates select="descr[1]"/>
|
||||
|
||||
<xsl:element name="DROP"/>
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Description -->
|
||||
<xsl:template match="descr">
|
||||
<xsl:element name="descr">
|
||||
<xsl:value-of select="normalize-space(text())"/>
|
||||
</xsl:element>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
Loading…
Reference in New Issue
Block a user