From b3d517a98c1ec03c04f5301d8f600838cff8afff Mon Sep 17 00:00:00 2001
From: Ralf Becker Error=".$this->ErrorNo().' ';
@@ -96,7 +98,7 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
}
}
$insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
- $rs = $zthis->Execute($insert);
+ $rs = $zthis->_Execute($insert);
return ($rs) ? 2 : 0;
}
@@ -216,7 +218,7 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
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);
+ $rstest = &$zthis->_Execute($rewritesql,$inputarr);
if ($rstest) {
$qryRecs = $rstest->RecordCount();
if ($qryRecs == -1) {
@@ -266,11 +268,7 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
$lastpageno = (int) ceil($qryRecs / $nrows);
$zthis->_maxRecordCount = $qryRecs;
- // If page number <= 1, then we are at the first page
- if (!isset($page) || $page <= 1) {
- $page = 1;
- $atfirstpage = true;
- }
+
// ***** Here we check whether $page is the last page or
// whether we are trying to retrieve
@@ -280,6 +278,12 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
$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)
@@ -372,7 +376,7 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
// If the recordset field is one
// of the fields passed in then process.
$upperfname = strtoupper($field->name);
- if (adodb_key_exists($upperfname,$arrFields)) {
+ if (adodb_key_exists($upperfname,$arrFields,$forcenulls)) {
// If the existing field value in the recordset
// is different from the value passed in then
@@ -392,31 +396,32 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
// 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';
+ $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 (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) {
@@ -429,9 +434,10 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
$discard = false;
// not a good hack, improvements?
- if ($whereClause)
- preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard);
- else
+ 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)
@@ -503,7 +509,7 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$forcenulls=f
// Loop through all of the fields in the recordset
foreach( $columns as $field ) {
$upperfname = strtoupper($field->name);
- if (adodb_key_exists($upperfname,$arrFields)) {
+ if (adodb_key_exists($upperfname,$arrFields,$forcenulls)) {
// Set the counter for the number of fields that will be inserted.
$fieldInsertedCount++;
@@ -539,8 +545,10 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$forcenulls=f
// Get the table name from the existing query.
if (!$tableName) {
- preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $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
@@ -693,4 +701,105 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
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( " Passed ! Failed :-( ADONewConnection: Unable to load database driver '$db' ADONewConnection: Unable to load database driver '$db' At this point, you are not connected to the database. You will first need to decide
+ At this point, you are not connected to the database (no longer true if you pass in a dsn). You will first need to decide
whether to use persistent or non-persistent connections. The advantage of persistent
connections is that they are faster, as the database connection is never closed (even
when you call Close()). Non-persistent connections take up much fewer resources though,
reducing the risk of your database and your web-server becoming overloaded.
For persistent connections,
-use $conn->PConnect(),
- or $conn->Connect() for non-persistent connections.
-Some database drivers also support NConnect(), which forces
+use $conn->PConnect(),
+ or $conn->Connect() for non-persistent connections.
+Some database drivers also support NConnect(), which forces
the creation of a new connection.
+
- Connection Gotcha: If you create two connections, but both use the same userid and password,
+ Connection Gotcha: If you create two connections, but both use the same userid and password,
PHP will share the same connection. This can cause problems if the connections are meant to
different databases. The solution is to always use different userid's for different databases,
or use NConnect().
+
+ Since ADOdb 4.51, you can connect to a database by passing a dsn to NewADOConnection() (or ADONewConnection, which is
+ the same function). The dsn format is:
+
+NewADOConnection() calls Connect() or PConnect() internally for you. If the connection fails, false is returned.
+
+If you have special characters such as /:? in your dsn, then you need to rawurlencode them first:
+
+Legal options are:
+
+
+For all drivers, when the options persist or persistent are set, a persistent connection is forced.
+The debug option enables debugging. The fetchmode calls SetFetchMode().
+If no value is defined for an option, then the value is set to 1.
+
+ADOdb DSN's are compatible with version 1.0 of PEAR DB's DSN format.
Most other database drivers use a similar convention: Connect($server, $user, $password, $database). Exceptions are listed below.
+ For most drivers, you can use the standard function: Connect($server, $user, $password, $database), or
+a DSN since ADOdb 4.51. Exceptions to this are listed below.
PostgreSQL accepts connections using: a. the standard connection string: b. the classical 4 parameters: c. dsn:
+ Here is an example of querying a LDAP server. Thanks to Josh Eldridge for the driver and this example:
Or dsn:
+ Or dsn:
+ With oci8, you can connect in multiple ways. Note that oci8 works fine with
newer versions of the Oracle, eg. 9i and 10g. f. ADOdb dsn:
+ ODBC DSN's can be created in the ODBC control panel, or you can use a DSN-less
@@ -395,16 +493,27 @@ using the ADOdb library and Microsoft's ADO:
qstr, Affected_Rows, Insert_ID The fastest way to access the fields is by accessing the array $recordset->fields
+ The fastest way to access the field data is by accessing the array $recordset->fields
directly. Also set the global variables $ADODB_FETCH_MODE
= ADODB_FETCH_NUM, and (for oci8, ibase/firebird and odbc) $ADODB_COUNTRECS = false
before you connect to your database. Consider using bind parameters if your database supports it, as it improves
query plan reuse. Use ADOdb's performance tuning system to identify bottlenecks
quickly. At the time of writing (Dec 2003), this means oci8 and odbc drivers. Lastly make sure you have a PHP accelerator cache installed such as APC, Turck
+ Lastly make sure you have a PHP accelerator cache installed such as APC, Turck
MMCache, Zend Accelerator or ionCube. Informix tips: Disable scrollable cursors with $db->cursorType = 0.
+ Advanced Tips
+ If you have the ADOdb C extension installed,
+ you can replace your calls to $rs->MoveNext() with adodb_movenext($rs).
+ This doubles the speed of this operation. For retrieving entire recordsets at once,
+use GetArray(), which uses the high speed extension function adodb_getall($rs) internally.
+ Execute() is the default way to run queries. You can use the low-level functions _Execute() and _query()
+to reduce query overhead. Both these functions share the same parameters as Execute().
+ If you do not have any bind parameters or your database supports binding (without emulation),
+then you can call _Execute() directly. Calling this function bypasses bind emulation. Debugging is still supported in _Execute().
+ If you do not require debugging facilities nor emulated binding, and do not require a recordset to be returned, then you can call _query. This is great for inserts, updates and deletes. Calling this function
+bypasses emulated binding, debugging, and recordset handling. Either the resultid, true or false are returned by _query().
+ For Informix, you can disable scrollable cursors with $db->cursorType = 0.
You might want to modify ADOdb for your own purposes. Luckily you can
@@ -416,7 +525,7 @@ the function-name stored in this variable if it is defined.
is placed in the hack_mysql and hack_postgres7 classes. The recordset class naming convention
can be controlled using $rsPrefix. Here we set it to 'hack_rs_', which will make ADOdb use
hack_rs_mysql and hack_rs_postgres7 as the recordset classes.
-If you want to use the default ADOdb drivers return false.
+
Don't forget to call the constructor of the parent class.
+ Don't forget to call the constructor of the parent class in your constructor. If you want to use the default ADOdb drivers return false in the above hack_factory() function.
Note that reaching EOF is not considered an error nor an exception.
+If you want to use the default ADOdb drivers return false.
We now support connecting using PEAR style DSN's. A DSN is a connection string
of the form: $dsn = "$driver://$username:$password@$hostname/$databasename"; You pass the DSN to the static class function DB::Connect. An example: An example: This requires PEAR to be installed and in the default include path in php.ini.
\n");
+ $ok = false;
+ }
+
+ return $ok;
+ }
?>
\ No newline at end of file
diff --git a/phpgwapi/inc/adodb/adodb-datadict.inc.php b/phpgwapi/inc/adodb/adodb-datadict.inc.php
index 80e77767a3..6aa7a151de 100644
--- a/phpgwapi/inc/adodb/adodb-datadict.inc.php
+++ b/phpgwapi/inc/adodb/adodb-datadict.inc.php
@@ -1,7 +1,7 @@
rs, $func), $params);
}
-
- function __toString()
- {
- if (isset($rs->databaseType)) $s = ' for '.$rs->databaseType;
- else $s = '';
-
- return 'ADODB Iterator'.$s;
- }
+
function hasMore()
{
@@ -79,6 +72,12 @@ 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);
+ }
}
?>
\ No newline at end of file
diff --git a/phpgwapi/inc/adodb/adodb-lib.inc.php b/phpgwapi/inc/adodb/adodb-lib.inc.php
index f6046b5ca3..26051bb5c9 100644
--- a/phpgwapi/inc/adodb/adodb-lib.inc.php
+++ b/phpgwapi/inc/adodb/adodb-lib.inc.php
@@ -63,7 +63,7 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
if ($uSet && $where) {
$update = "UPDATE $table SET $uSet WHERE $where";
- $rs = $zthis->Execute($update);
+ $rs = $zthis->_Execute($update);
if ($rs) {
if ($zthis->poorAffectedRows) {
/*
@@ -77,8 +77,10 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
$cnt = $zthis->GetOne("select count(*) from $table where $where");
if ($cnt > 0) return 1; // record already exists
- } else
- if (($zthis->Affected_Rows()>0)) return 1;
+ } else {
+
+ if (($zthis->Affected_Rows()>0)) return 1;
+ }
}
}
// print "
\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." $ss
\n
\n",false);
+ else
+ ADOConnection::outp( "
\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." $ss
\n
\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) ? " %% line %4d, file: %s" : "%% line %4d, file: %s";
+
+ $MAXSTRLEN = 64;
+
+ $s = ($html) ? '' : '';
+
+ if (is_array($printOrArr)) $traceArr = $printOrArr;
+ else $traceArr = debug_backtrace();
+ array_shift($traceArr);
+ array_shift($traceArr);
+ $tabs = sizeof($traceArr)-2;
+
+ foreach ($traceArr as $arr) {
+ $levels -= 1;
+ if ($levels < 0) break;
+
+ $args = array();
+ for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' ' : "\t";
+ $tabs -= 1;
+ if ($html) $s .= '';
+ if (isset($arr['class'])) $s .= $arr['class'].'.';
+ if (isset($arr['args']))
+ foreach($arr['args'] as $v) {
+ if (is_null($v)) $args[] = 'null';
+ else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
+ else if (is_object($v)) $args[] = 'Object:'.get_class($v);
+ else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
+ else {
+ $v = (string) @$v;
+ $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
+ if (strlen($v) > $MAXSTRLEN) $str .= '...';
+ $args[] = $str;
+ }
+ }
+ $s .= $arr['function'].'('.implode(', ',$args).')';
+
+
+ $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
+
+ $s .= "\n";
+ }
+ if ($html) $s .= '
';
+ if ($printOrArr) print $s;
+
+ return $s;
+}
+
?>
\ No newline at end of file
diff --git a/phpgwapi/inc/adodb/adodb-pager.inc.php b/phpgwapi/inc/adodb/adodb-pager.inc.php
index f4d2525eb4..9715f834af 100644
--- a/phpgwapi/inc/adodb/adodb-pager.inc.php
+++ b/phpgwapi/inc/adodb/adodb-pager.inc.php
@@ -1,7 +1,7 @@
db->pageExecuteCountRows) return '';
$lastPage = $this->rs->LastPageNo();
if ($lastPage == -1) $lastPage = 1; // check for empty rs.
+ if ($this->curr_page > $lastPage) $this->curr_page = 1;
return "$this->page ".$this->curr_page."/".$lastPage."";
}
diff --git a/phpgwapi/inc/adodb/adodb-perf.inc.php b/phpgwapi/inc/adodb/adodb-perf.inc.php
index e5c0961cf0..a2f92402c4 100644
--- a/phpgwapi/inc/adodb/adodb-perf.inc.php
+++ b/phpgwapi/inc/adodb/adodb-perf.inc.php
@@ -1,6 +1,6 @@
- ADOdb Performance Monitor for $app
+ ADOdb Performance Monitor for $app
-
Performance Stats View SQL
View Tables Poll Stats",
$allowsql ? ' Run SQL' : '',
diff --git a/phpgwapi/inc/adodb/adodb-php4.inc.php b/phpgwapi/inc/adodb/adodb-php4.inc.php
index efc8f85e58..8f47417e2f 100644
--- a/phpgwapi/inc/adodb/adodb-php4.inc.php
+++ b/phpgwapi/inc/adodb/adodb-php4.inc.php
@@ -1,7 +1,7 @@
';
+
$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).'
';
@@ -428,7 +435,7 @@ function adodb_date_test()
// 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);
@@ -443,8 +450,9 @@ function adodb_date_test()
$fail = true;
break;
}
+ $cnt += 1;
}
-
+ echo "Tested $cnt dates
";
if (!$fail) print "';
if( isset( $title ) ) {
diff --git a/phpgwapi/inc/adodb/adodb.inc.php b/phpgwapi/inc/adodb/adodb.inc.php
index 8466ab0124..1067cce274 100644
--- a/phpgwapi/inc/adodb/adodb.inc.php
+++ b/phpgwapi/inc/adodb/adodb.inc.php
@@ -224,7 +224,7 @@
var $substr = 'substr'; /// substring operator
var $length = 'length'; /// string length operator
var $random = 'rand()'; /// random function
- var $upperCase = false; /// uppercase function
+ var $upperCase = 'upper'; /// uppercase function
var $fmtDate = "'Y-m-d'"; /// used by DBDate() as the default date format used by the database
var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; /// used by DBTimeStamp as the default timestamp fmt.
var $true = '1'; /// string that represents TRUE for a database
@@ -348,15 +348,17 @@
if ($newline) $msg .= "
\n";
- if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) echo $msg;
+ if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) || !$newline) echo $msg;
else echo strip_tags($msg);
+
+
if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan
}
function Time()
{
- $rs =& $this->Execute("select $this->sysTimeStamp");
+ $rs =& $this->_Execute("select $this->sysTimeStamp");
if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
return false;
@@ -617,7 +619,7 @@
For databases that require positioned params, eg $1, $2, $3 for postgresql,
pass in Param(false) before setting the first parameter.
*/
- function Param($name)
+ function Param($name,$type='C')
{
return '?';
}
@@ -754,7 +756,9 @@
$ret =& $fn($this,$sql,$inputarr);
if (isset($ret)) return $ret;
}
- if ($inputarr && is_array($inputarr)) {
+ if ($inputarr) {
+ if (!is_array($inputarr)) $inputarr = array($inputarr);
+
$element0 = reset($inputarr);
# is_object check because oci8 descriptors can be passed in
$array_2d = is_array($element0) && !is_object(reset($element0));
@@ -782,7 +786,7 @@
if ($i+1 != sizeof($sqlarr))
ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql));
- $ret =& $this->_Execute($sql,false);
+ $ret =& $this->_Execute($sql);
if (!$ret) return $ret;
}
} else {
@@ -803,60 +807,23 @@
return $ret;
}
+
function& _Execute($sql,$inputarr=false)
{
if ($this->debug) {
- 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) {
- if ($this->debug === -1)
- ADOConnection::outp( "
\n($this->databaseType): ".htmlspecialchars($sqlTxt)." $ss
\n
\n",false);
- else
- ADOConnection::outp( "
\n($this->databaseType): ".htmlspecialchars($sqlTxt)." $ss
\n
\n",false);
- } else {
- ADOConnection::outp("-----\n($this->databaseType): ".($sqlTxt)." \n-----\n",false);
- }
- $this->_queryID = $this->_query($sql,$inputarr);
- /*
- Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
- because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
- */
- if ($this->databaseType == 'mssql') {
- // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
- if($emsg = $this->ErrorMsg()) {
- if ($err = $this->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
- }
- } else if (!$this->_queryID) {
- ADOConnection::outp($this->ErrorNo() .': '. $this->ErrorMsg());
- }
+ global $ADODB_INCLUDED_LIB;
+ if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
+ $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr);
} else {
- //****************************
- // non-debug version of query
- //****************************
-
- $this->_queryID =@$this->_query($sql,$inputarr);
+ $this->_queryID = @$this->_query($sql,$inputarr);
}
/************************
// OK, query executed
*************************/
- if ($this->_queryID === false) {
- // error handling if query fails
+ if ($this->_queryID === false) { // error handling if query fails
if ($this->debug == 99) adodb_backtrace(true,5);
$fn = $this->raiseErrorFn;
if ($fn) {
@@ -866,12 +833,8 @@
return false;
}
-
- if ($this->_queryID === true) {
- // return simplified empty recordset for inserts/updates/deletes with lower overhead
+ if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead
$rs =& new ADORecordSet_empty();
- #if (is_array($sql)) $rs->sql = $sql[0];
- #else $rs->sql = $sql;
return $rs;
}
@@ -885,7 +848,7 @@
if ($rs->_numOfRows <= 0) {
global $ADODB_COUNTRECS;
if ($ADODB_COUNTRECS) {
- if (!$rs->EOF){
+ if (!$rs->EOF) {
$rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql));
$rs->_queryID = $this->_queryID;
} else
@@ -1241,7 +1204,7 @@
if ($rs) {
if (!$rs->EOF) $ret = reset($rs->fields);
$rs->Close();
- }
+ }
$ADODB_COUNTRECS = $crecs;
return $ret;
}
@@ -1481,6 +1444,10 @@
}
return;
}
+
+ global $ADODB_INCLUDED_CSV;
+ if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
+
$f = $this->_gencachename($sql.serialize($inputarr),false);
adodb_write_file($f,''); // is adodb_write_file needed?
if (!@unlink($f)) {
@@ -1631,7 +1598,7 @@
$forcenulls = defined('ADODB_FORCE_NULLS') ? true : false;
}
if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
- return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq);
+ return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$forcenulls);
}
@@ -1650,7 +1617,7 @@
$forcenulls = defined('ADODB_FORCE_NULLS') ? true : false;
}
if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
- return _adodb_getinsertsql($this,$rs,$arrFields,$magicq);
+ return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$forcenulls);
}
@@ -2505,7 +2472,10 @@
* @return an associative array indexed by the first column of the array,
* or false if the data has less than 2 cols.
*/
- function &GetAssoc($force_array = false, $first2cols = false) {
+ function &GetAssoc($force_array = false, $first2cols = false)
+ {
+ global $ADODB_EXTENSION;
+
$cols = $this->_numOfFields;
if ($cols < 2) {
return false;
@@ -2514,32 +2484,64 @@
$results = array();
if (!$first2cols && ($cols > 2 || $force_array)) {
- if ($numIndex) {
- while (!$this->EOF) {
- $results[trim($this->fields[0])] = array_slice($this->fields, 1);
- $this->MoveNext();
+ if ($ADODB_EXTENSION) {
+ if ($numIndex) {
+ while (!$this->EOF) {
+ $results[trim($this->fields[0])] = array_slice($this->fields, 1);
+ adodb_movenext($this);
+ }
+ } else {
+ while (!$this->EOF) {
+ $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
+ adodb_movenext($this);
+ }
}
} else {
- while (!$this->EOF) {
- $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
- $this->MoveNext();
+ if ($numIndex) {
+ while (!$this->EOF) {
+ $results[trim($this->fields[0])] = array_slice($this->fields, 1);
+ $this->MoveNext();
+ }
+ } else {
+ while (!$this->EOF) {
+ $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
+ $this->MoveNext();
+ }
}
}
} else {
- // return scalar values
- if ($numIndex) {
- while (!$this->EOF) {
- // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
- $results[trim(($this->fields[0]))] = $this->fields[1];
- $this->MoveNext();
+ if ($ADODB_EXTENSION) {
+ // return scalar values
+ if ($numIndex) {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $results[trim(($this->fields[0]))] = $this->fields[1];
+ adodb_movenext($this);
+ }
+ } else {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $v1 = trim(reset($this->fields));
+ $v2 = ''.next($this->fields);
+ $results[$v1] = $v2;
+ adodb_movenext($this);
+ }
}
} else {
- while (!$this->EOF) {
- // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
- $v1 = trim(reset($this->fields));
- $v2 = ''.next($this->fields);
- $results[$v1] = $v2;
- $this->MoveNext();
+ if ($numIndex) {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $results[trim(($this->fields[0]))] = $this->fields[1];
+ $this->MoveNext();
+ }
+ } else {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $v1 = trim(reset($this->fields));
+ $v2 = ''.next($this->fields);
+ $results[$v1] = $v2;
+ $this->MoveNext();
+ }
}
}
}
@@ -2728,7 +2730,8 @@
}
*/
return false;
- }
+ }
+
/**
* Random access to a specific row in the recordset. Some databases do not support
@@ -2989,7 +2992,8 @@
*/
function &FetchNextObj()
{
- return $this->FetchNextObject(false);
+ $o = $this->FetchNextObject(false);
+ return $o;
}
@@ -3415,6 +3419,7 @@
if (!$dbType) return false;
$db = strtolower($dbType);
switch ($db) {
+ case 'ifx':
case 'maxsql': $db = 'mysqlt'; break;
case 'postgres':
case 'pgsql': $db = 'postgres7'; break;
@@ -3456,44 +3461,111 @@
if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
$errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
+ if (strpos($db,'://')) {
+ $origdsn = $db;
+ $dsna = @parse_url($db);
+ if (!$dsna) {
+ // special handling of oracle, which might not have host
+ $db = str_replace('@/','@adodb-fakehost/',$db);
+ $dsna = parse_url($db);
+ if (!$dsna) return false;
+ $dsna['host'] = '';
+ }
+ $db = @$dsna['scheme'];
+ if (!$db) return false;
+ $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
+ $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : '';
+ $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : '';
+ $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : '';
+
+ if (isset($dsna['query'])) {
+ $opt1 = explode('&',$dsna['query']);
+ foreach($opt1 as $k => $v) {
+ $arr = explode('=',$v);
+ $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1;
+ }
+ } else $opt = array();
+ }
+
+ /*
+ * phptype: Database backend used in PHP (mysql, odbc etc.)
+ * dbsyntax: Database used with regards to SQL syntax etc.
+ * protocol: Communication protocol to use (tcp, unix etc.)
+ * hostspec: Host specification (hostname[:port])
+ * database: Database to use on the DBMS server
+ * username: User name for login
+ * password: Password for login
+ */
if (!empty($ADODB_NEWCONNECTION)) {
$obj = $ADODB_NEWCONNECTION($db);
- if ($obj) {
- if ($errorfn) $obj->raiseErrorFn = $errorfn;
- return $obj;
+
+ } else {
+
+ if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = '';
+ if (empty($db)) $db = $ADODB_LASTDB;
+
+ if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db);
+
+ if (!$db) {
+ if (isset($origdsn)) $db = $origdsn;
+ if ($errorfn) {
+ // raise an error
+ $ignore = false;
+ $errorfn('ADONewConnection', 'ADONewConnection', -998,
+ "could not load the database driver for '$db'",
+ $db,false,$ignore);
+ } else
+ ADOConnection::outp( "
\n");
- $ok = false;
- }
-
- return $ok;
- }
/*
Perform a print_r, with pre tags for better formatting.
@@ -3631,54 +3651,9 @@
*/
function adodb_backtrace($printOrArr=true,$levels=9999)
{
- $s = '';
- if (PHPVERSION() < 4.3) return;
-
- $html = (isset($_SERVER['HTTP_USER_AGENT']));
- $fmt = ($html) ? " %% line %4d, file: %s" : "%% line %4d, file: %s";
-
- $MAXSTRLEN = 64;
-
- $s = ($html) ? '' : '';
-
- if (is_array($printOrArr)) $traceArr = $printOrArr;
- else $traceArr = debug_backtrace();
- array_shift($traceArr);
- $tabs = sizeof($traceArr)-1;
-
- 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 .= '';
- if (isset($arr['class'])) $s .= $arr['class'].'.';
- if (isset($arr['args']))
- foreach($arr['args'] as $v) {
- if (is_null($v)) $args[] = 'null';
- else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
- else if (is_object($v)) $args[] = 'Object:'.get_class($v);
- else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
- else {
- $v = (string) @$v;
- $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
- if (strlen($v) > $MAXSTRLEN) $str .= '...';
- $args[] = $str;
- }
- }
- $s .= $arr['function'].'('.implode(', ',$args).')';
-
-
- $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
-
- $s .= "\n";
- }
- if ($html) $s .= '
';
- if ($printOrArr) print $s;
-
- return $s;
+ global $ADODB_INCLUDED_LIB;
+ if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
+ return _adodb_backtrace($printOrArr,$levels);
}
} // defined
diff --git a/phpgwapi/inc/adodb/datadict/datadict-access.inc.php b/phpgwapi/inc/adodb/datadict/datadict-access.inc.php
index b1908b1b1d..d281be7e1e 100644
--- a/phpgwapi/inc/adodb/datadict/datadict-access.inc.php
+++ b/phpgwapi/inc/adodb/datadict/datadict-access.inc.php
@@ -1,7 +1,7 @@
Installation
Minimum Install
- Initializing Code and Connection Examples
- ADONewConnection
- NewADOConnection
- High Speed ADOdb - tuning tips
+ Initializing Code and Connectioning to Databases
+ Data Source Name (DSN) Support Connection Examples
+ High Speed ADOdb - tuning tips
Hacking and Modifying ADOdb Safely
PHP5 Features
foreach iterators exceptions
@@ -232,22 +236,73 @@ $conn = &ADONewConnection('mysql');
using the ADONewConnection($driver) function.
NewADOConnection($driver) is an alternative name for the same function.
-Data Source Name (DSN) Support
+
+ $driver://$username:$password@hostname/$database?options[=value]
+
+ # non-persistent connection
+ $dsn = 'mysql://root:pwd@localhost/mydb';
+ $db = NewADOConnection($dsn);
+ if (!$db) die("Connection failed");
+
+ # no need to call connect/pconnect!
+ $arr = $db->GetArray("select * from table");
+
+ # persistent connection
+ $dsn2 = 'mysql://root:pwd@localhost/mydb?persist';
+
+
+ $pwd = rawurlencode($pwd);
+ $dsn = "mysql://root:$pwd@localhost/mydb";
+
+
+For all drivers
+ 'persist', 'persistent', 'debug', 'fetchmode'
+ Interbase/Firebird
+
+ 'dialect',
+ 'charset',
+ 'buffers'
+ M'soft ADO
+ 'charpage'
+
+ MySQL
+ 'clientflags'
+ MySQLi
+ 'port', 'socket', 'clientflags'
+ Examples of Connecting to Databases
MySQL and Most Other Database Drivers
@@ -256,8 +311,23 @@ different databases. The solution is to always use different userid's for differ
$conn = &ADONewConnection('mysql');
$conn->PConnect('localhost','userid','password','database');
+
+ # or dsn
+ $dsn = 'mysql://user:pwd@localhost/mydb';
+ $conn = ADONewConnection($dsn); # no need for Connect()
+
+ # or persistent dsn
+ $dsn = 'mysql://user:pwd@localhost/mydb?persist';
+ $conn = ADONewConnection($dsn); # no need for PConnect()
+
+ # a more complex example:
+ $pwd = urlencode($pwd);
+ $flags = MYSQL_CLIENT_COMPRESS;
+ $dsn = "mysql://user:$pwd@localhost/mydb?persist&clientflags=$flags";
+ $conn = ADONewConnection($dsn); # no need for PConnect()
-PostgreSQL
$conn->PConnect('localhost','userid','password','database');
-
+
+
+ $dsn = 'postgres7://user:pwd@localhost/mydb?persist'; # persist is optional
+ $conn = ADONewConnection($dsn); # no need for Connect/PConnect
+
+
+
LDAP
@@ -313,12 +390,22 @@ You define the database in the $host parameter:
$conn = &ADONewConnection('ibase');
$conn->PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey');
+
+ $dsn = 'firebird://user:pwd@localhost/mydb?persist&dialect=3'; # persist is optional
+ $conn = ADONewConnection($dsn); # no need for Connect/PConnect
+
SQLite
Sqlite will create the database file if it does not exist.
$conn = &ADONewConnection('sqlite');
$conn->PConnect('c:\path\to\sqlite.db'); # sqlite will create if does not exist
+
+ $dsn = 'sqlite://user:pwd@localhost/mydb?persist'; # persist is optional
+ $conn = ADONewConnection($dsn); # no need for Connect/PConnect
+
Oracle (oci8)
+ $dsn = 'oci8://user:pwd@tnsname?persist'; # persist is optional
+ $conn = ADONewConnection($dsn); # no need for Connect/PConnect
+
+ $dsn = 'oci8://user:pwd@host/sid';
+ $conn = ADONewConnection($dsn);
+
+ $dsn = 'oci8://user:pwd@/'; # oracle on local machine
+ $conn = ADONewConnection($dsn);
+
DSN-less ODBC (access and mssql examples)
Hacking ADOdb Safely
class hack_mysql extends adodb_mysql {
@@ -425,7 +534,7 @@ var $rsPrefix = 'hack_rs_';
}
class hack_rs_mysql extends ADORecordSet_mysql {
- /* Your mods here */
+ /* Your mods here */
}
class hack_postgres7 extends adodb_postgres7 {
@@ -449,9 +558,8 @@ function& hack_factory($driver)
}
include_once('adodb.inc.php');
-
-PHP5 Features
ADOdb 4.02 or later will transparently determine which version of PHP you are using.
@@ -481,6 +589,7 @@ catch exceptions on errors as they occur.
}
Databases Supported
The name below is the value you pass to NewADOConnection($name) to create a connection object for that database.
@@ -1391,20 +1500,24 @@ PEAR::setErrorHandling('PEAR_ERROR_DIE');
include_once('../adodb/adodb-pear.inc.php');
+
$username = 'root';
$password = '';
$hostname = 'localhost';
$databasename = 'xphplens';
$driver = 'mysql';
- $dsn = "$driver://$username:$password@$hostname/$databasename";
- $db = DB::Connect($dsn);
-
$rs = $db->query('select firstname,lastname from adoxyz');
+ $dsn = "$driver://$username:$password@$hostname/$databasename"
+ $db = NewADOConnection();
+ # DB::Connect($dsn) also works if you include 'adodb/adodb-pear.inc.php' at the top
+ $rs = $db->query('select firstname,lastname from adoxyz');
$cnt = 0;
while ($arr = $rs->fetchRow()) {
print_r($arr); print "<br>";
}
More info and connection examples on the DSN format. +
@@ -1465,7 +1578,7 @@ $rs = $conn->CacheExecSince ADOdb 2.30, we support the generation of SQL to create pivot tables, also known as cross-tabulations. For further explanation read this DevShed Cross-Tabulation -tutorial. We assume that your database supports the SQL case-when expression.
+tutorial. We assume that your database supports the SQL case-when expression.In this example, we will use the Northwind database from Microsoft. In the database, we have a products table, and we want to analyze this table by suppliers @@ -1892,9 +2005,30 @@ only with SELECT statements. # $rs is now just like any other ADOdb recordset object
rs2html($rs);
ExecuteCursor() is a helper function that does the following internally:
- $stmt = $db->Prepare("BEGIN :RS := SP_FOO(); END;", true); - $db->Parameter($stmt, $cur, 'RS', false, -1, OCI_B_CURSOR); - $rs = $db->Execute($stmt);+ $stmt = $db->Prepare("begin :cursorvar := getdata(:param1); end;", true); + $db->Parameter($stmt, $cur, 'cursorvar', false, -1, OCI_B_CURSOR); + $rs = $db->Execute($stmt,$bindarr); + +
ExecuteCursor only accepts 1 out parameter. So if you have 2 out parameters, use: +
+ $vv = 'A%'; + $stmt = $db->PrepareSP("BEGIN list_tabs(:crsr,:tt); END;"); + $db->OutParameter($stmt, $cur, 'crsr', -1, OCI_B_CURSOR); + $db->OutParameter($stmt, $vv, 'tt', 32); # return varchar(32) + $arr = $db->GetArray($stmt); + print_r($arr); + echo " val = $vv"; ## outputs 'TEST' ++for the following PL/SQL: +
+ TYPE TabType IS REF CURSOR RETURN TAB%ROWTYPE; + + PROCEDURE list_tabs(tabcursor IN OUT TabType,tablenames IN OUT VARCHAR) IS + BEGIN + OPEN tabcursor FOR SELECT * FROM TAB WHERE tname LIKE tablenames; + tablenames := 'TEST'; + END list_tabs; +
SelectLimit($sql,$numrows=-1,$offset=-1,$inputarr=false)
Returns a recordset if successful. Returns false otherwise. Performs a select statement, simulating PostgreSQL's SELECT statement, LIMIT $numrows OFFSET @@ -3144,8 +3278,32 @@ $rs = $conn->Execute PHP.
Added adodb-xmlschema 1.0.2. Thx dan and richard. +
Added new adorecordset_ext_* classes. If ADOdb extension installed for mysql, mysqlt and oci8 +(but not oci8po), we use the superfast ADOdb extension code for movenext. +
Added schema support to mssql and odbc_mssql MetaPrimaryKeys(). +
Patched MSSQL driver to support PHP NULL and Boolean values +while binding the input array parameters in the _query() function. By Stephen Farmer. +
Added support for clob's for mssql, UpdateBlob(). Thx to gfran#directa.com.br +
Added normalize support for postgresql (true=lowercase table name, or false=case-sensitive table names) +to MetaColumns($table, $normalize=true). +
PHP5 variant dates in ADO not working. Fixed in adodb-ado.inc.php. +
Constant ADODB_FORCE_NULLS was not working properly for many releases (for GetUpdateSQL). Fixed. +Also GetUpdateSQL strips off ORDER BY now - thx Elieser Leão. +
Perf Monitor for oci8 now dynamically highlights optimizer_* params if too high/low. +
Added dsn support to NewADOConnection/ADONewConnection. +
Fixed out of page bounds bug in _adodb_pageexecute_all_rows() Thx to "Sergio Strampelli" sergio#rir.it +
Speedup of movenext for mysql and oci8 drivers. +
Moved debugging code _adodb_debug_execute() to adodb-lib.inc.php. +
Fixed postgresql bytea detection bug. See http://phplens.com/lens/lensforum/msgs.php?id=9849. +
Fixed ibase datetimestamp typo in PHP5. Thx stefan. +
Removed whitespace at end of odbtp drivers. +
Added db2 metaprimarykeys fix. +
Optimizations to MoveNext() for mysql and oci8. Misc speedups to Get* functions.
Bumped it to 4.50 to avoid confusion with PHP 4.3.x series. +
Added db2 metatables and metacolumns extensions.
Added alpha PDO driver. Very buggy, only works with odbc.
Tested mysqli. Set poorAffectedRows = true. Cleaned up movenext() and _fetch().
PageExecute does not work properly with php5 (return val not a variable). Reported Dmytro Sychevsky sych#php.com.ua. Fixed. diff --git a/phpgwapi/inc/adodb/docs/docs-datadict.htm b/phpgwapi/inc/adodb/docs/docs-datadict.htm index a815749dbb..a575f4dde8 100644 --- a/phpgwapi/inc/adodb/docs/docs-datadict.htm +++ b/phpgwapi/inc/adodb/docs/docs-datadict.htm @@ -1,553 +1,276 @@ + -
-V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my).
AXMLS (c) 2004 ars Cognita, Inc
This software is dual licensed using BSD-Style and LGPL. This means you can use it in compiled proprietary and commercial products.
-Kindly note that the ADOdb home page has moved to http://adodb.sourceforge.net/ because of the persistent - unreliability of http://php.weblogs.com. Please change your links! |
Useful ADOdb links: Download Other Docs - -
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 AXMLS, an XML schema system for defining databases.
- -Currently the following databases are supported:
-
- Well-tested: PostgreSQL, MySQL, Oracle, MSSQL.
- Beta-quality: DB2, Informix, Sybase, Interbase, Firebird.
- Alpha-quality: MS Access (does not support DEFAULT values) and generic ODBC.
+
V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my).
+AXMLS (c) 2004 ars Cognita, Inc
This software is dual licensed using BSD-Style and +LGPL. This means you can use it in compiled proprietary and commercial +products.
+Kindly note that the ADOdb home page has +moved to http://adodb.sourceforge.net/ +because of the persistent unreliability of http://php.weblogs.com. Please +change your links! | +
Useful ADOdb links: Download + Other Docs +
+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 AXMLS, an XML schema +system for defining databases. You can contact them at +dcech#phpwerx.net and richtl#arscognita.com.
+Currently the following databases are supported:
+ Well-tested: PostgreSQL, MySQL, Oracle, MSSQL.
+Beta-quality: DB2, Informix, Sybase, Interbase, Firebird.
+Alpha-quality: MS Access (does not support DEFAULT values) and
+generic ODBC.
- include_once('adodb.inc.php'); - # First create a normal connection - $db->NewADOConnection('mysql'); - $db->Connect(...); - - # Then create a data dictionary object, using this connection - $dict = NewDataDictionary($db); - - # We have a portable declarative data dictionary format in ADOdb, similar to SQL. - # Field types use 1 character codes, and fields are separated by commas. - # The following example creates three fields: "col1", "col2" and "col3": - $flds = " - col1 C(32) NOTNULL DEFAULT 'abc', - col2 I DEFAULT 0, - col3 N(12.2) - "; - - # We demonstrate creating tables and indexes - $sqlarray = $dict->CreateTableSQL($tabname, $flds, $taboptarray); - $dict->ExecuteSQLArray($sqlarray);- +
- $idxflds = 'co11, col2'; - $sqlarray = $dict->CreateIndexSQL($idxname, $tabname, $idxflds); - $dict->ExecuteSQLArray($sqlarray); -
include_once('adodb.inc.php');
# First create a normal connection
$db->NewADOConnection('mysql');
$db->Connect(...);
# Then create a data dictionary object, using this connection
$dict = NewDataDictionary($db);
# We have a portable declarative data dictionary format in ADOdb, similar to SQL.
# Field types use 1 character codes, and fields are separated by commas.
# The following example creates three fields: "col1", "col2" and "col3":
$flds = "
col1 C(32) NOTNULL DEFAULT 'abc',
col2 I DEFAULT 0,
col3 N(12.2)
";
# We demonstrate creating tables and indexes
$sqlarray = $dict->CreateTableSQL($tabname, $flds, $taboptarray);
$dict->ExecuteSQLArray($sqlarray);
$idxflds = 'co11, col2';
$sqlarray = $dict->CreateIndexSQL($idxname, $tabname, $idxflds);
$dict->ExecuteSQLArray($sqlarray);
Create a database with the name $dbname;
-- RETURNS: an array of strings, the sql to be executed, or false - $tabname: name of table - $fldarray: string (or array) containing field info - $taboptarray: array containing table options --
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 +
RETURNS: an array of strings, the sql to be executed, or false+
$tabname: name of table
$fldarray: string (or array) containing field info
$taboptarray: array containing table options
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:
"$fieldname $type $colsize $otheroptions"-
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:
+The older (and still supported) format of $fldarray is a +2-dimensional array, where each row in the 1st dimension represents one +field. Each row has this format:
array($fieldname, $type, [,$colsize] [,$otheroptions]*)- -
The first 2 fields must be the field name and the field type. The field type can be a portable type codes or the actual type for that database.
+The first 2 fields must be the field name and the field type. The +field type can be a portable type codes or the actual type for that +database.
Legal portable type codes include:
-- C: varchar - X: Largest varchar size - XL: For Oracle, returns CLOB, otherwise same as 'X' above - - C2: Multibyte varchar - X2: Multibyte varchar (largest size) - - B: BLOB (binary large object) - - D: Date (some databases do not support this, and we return a datetime type) - T: Datetime or Timestamp - L: Integer field suitable for storing booleans (0 or 1) - I: Integer (mapped to I4) - I1: 1-byte integer - I2: 2-byte integer - I4: 4-byte integer - I8: 8-byte integer - F: Floating point number - N: Numeric or decimal number --
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.
+C: varchar+
X: Largest varchar size
XL: For Oracle, returns CLOB, otherwise same as 'X' above
C2: Multibyte varchar
X2: Multibyte varchar (largest size)
B: BLOB (binary large object)
D: Date (some databases do not support this, and we return a datetime type)
T: Datetime or Timestamp
L: Integer field suitable for storing booleans (0 or 1)
I: Integer (mapped to I4)
I1: 1-byte integer
I2: 2-byte integer
I4: 4-byte integer
I8: 8-byte integer
F: Floating point number
N: Numeric or decimal number
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.
The $otheroptions include the following keywords (case-insensitive):
-- AUTO For autoincrement number. Emulated with triggers if not available. - Sets NOTNULL also. - AUTOINCREMENT Same as auto. - KEY Primary key field. Sets NOTNULL also. Compound keys are supported. - PRIMARY Same as KEY. - DEF Synonym for DEFAULT for lazy typists. - DEFAULT The default value. Character strings are auto-quoted unless - the string begins and ends with spaces, eg ' SYSDATE '. - NOTNULL If field is not null. - DEFDATE Set default value to call function to get today's date. - DEFTIMESTAMP Set default to call function to get today's datetime. - NOQUOTE Prevents autoquoting of default string values. - CONSTRAINTS Additional constraints defined at the end of the field - definition. --
The Data Dictonary accepts two formats, the older array specification:
-- $flds = array( - array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NOTNULL'), - array('id', 'I' , 'AUTO'), - array('`MY DATE`', 'D' , 'DEFDATE'), - array('NAME', 'C' , '32', 'CONSTRAINTS' => 'FOREIGN KEY REFERENCES reftable') - ); -+
AUTO For autoincrement number. Emulated with triggers if not available.+
Sets NOTNULL also.
AUTOINCREMENT Same as auto.
KEY Primary key field. Sets NOTNULL also. Compound keys are supported.
PRIMARY Same as KEY.
DEF Synonym for DEFAULT for lazy typists.
DEFAULT The default value. Character strings are auto-quoted unless
the string begins and ends with spaces, eg ' SYSDATE '.
NOTNULL If field is not null.
DEFDATE Set default value to call function to get today's date.
DEFTIMESTAMP Set default to call function to get today's datetime.
NOQUOTE Prevents autoquoting of default string values.
CONSTRAINTS Additional constraints defined at the end of the field
definition.
The Data Dictonary accepts two formats, the older array +specification:
+$flds = array(
array('COLNAME', 'DECIMAL', '8.4', 'DEFAULT' => 0, 'NOTNULL'),
array('id', 'I' , 'AUTO'),
array('`MY DATE`', 'D' , 'DEFDATE'),
array('NAME', 'C' , '32', 'CONSTRAINTS' => 'FOREIGN KEY REFERENCES reftable')
);
Or the simpler declarative format:
-- $flds = " - COLNAME DECIMAL(8.4) DEFAULT 0 NOTNULL, - id I AUTO, - `MY DATE` D DEFDATE, - NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable' - "; --
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.
- -The $taboptarray is the 3rd parameter of the CreateTableSQL function. This contains table specific settings. Legal keywords include:
+$flds = "+
COLNAME DECIMAL(8.4) DEFAULT 0 NOTNULL,
id I AUTO,
`MY DATE` D DEFDATE,
NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable'
";
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.
+The $taboptarray is the 3rd parameter of the CreateTableSQL +function. This contains table specific settings. Legal keywords include:
Database specific table options can be defined also using the name of the database type as the array key. In the following example, create the table as ISAM with MySQL, and store the table in the "users" tablespace if using Oracle. And because we specified REPLACE, drop the table first.
-$taboptarray = array('mysql' => 'TYPE=ISAM', 'oci8' => 'tablespace users', 'REPLACE');- -
You can also define foreignkey constraints. The following is syntax for postgresql: -
$taboptarray = array('constraints' => ', FOREIGN KEY (col1) REFERENCES reftable (refcol)');- +
Database specific table options can be defined also using the name +of the database type as the array key. In the following example, create +the table as ISAM with MySQL, and store the table in the "users" +tablespace if using Oracle. And because we specified REPLACE, drop +the table first.
+$taboptarray = array('mysql' => 'TYPE=ISAM', 'oci8' => 'tablespace users', 'REPLACE');+
You can also define foreignkey constraints. The following is syntax +for postgresql: +
+$taboptarray = array('constraints' => ', FOREIGN KEY (col1) REFERENCES reftable (refcol)');
Returns the SQL to drop the specified table.
-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.
-The class must be connected to the database for ChangeTableSQL to detect the - existence of the table. Idea and code contributed by Florian Buzin.
- -- RETURNS: an array of strings, the sql to be executed, or false - $idxname: name of index - $tabname: name of table - $flds: list of fields as a comma delimited string or an array of strings - $idxoptarray: array of index creation options --
$idxoptarray is similar to $taboptarray in that index specific information can be embedded in the array. Other options include:
-- CLUSTERED Create clustered index (only mssql) - BITMAP Create bitmap index (only oci8) - UNIQUE Make unique index - FULLTEXT Make fulltext index (only mysql) - HASH Create hash index (only postgres) - DROP Drop legacy index -- +
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.
+The class must be connected to the database for ChangeTableSQL to +detect the existence of the table. Idea and code contributed by Florian +Buzin.
+RETURNS: an array of strings, the sql to be executed, or false+
$idxname: name of index
$tabname: name of table
$flds: list of fields as a comma delimited string or an array of strings
$idxoptarray: array of index creation options
$idxoptarray is similar to $taboptarray in that index specific +information can be embedded in the array. Other options include:
+CLUSTERED Create clustered index (only mssql)
BITMAP Create bitmap index (only oci8)
UNIQUE Make unique index
FULLTEXT Make fulltext index (only mysql)
HASH Create hash index (only postgres)
DROP Drop legacy index
Returns the SQL to drop the specified index.
-Add one or more columns. Not guaranteed to work under all situations.
-Warning, not all databases support this feature.
-Drop 1 or more columns.
-Set the schema.
-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.
- +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.
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.
- +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.
The same as NameQuote, but will prepend the current schema if specified
- +The same as NameQuote, but will prepend the current schema if +specified
Convert between database-independent 'Meta' and database-specific 'Actual' type codes.
- +Convert between database-independent 'Meta' and database-specific +'Actual' type codes.
- RETURNS: 0 if failed, 1 if executed all but with errors, 2 if executed successfully - $sqlarray: an array of strings with sql code (no semicolon at the end of string) - $contOnError: if true, then continue executing even if error occurs --
Executes an array of SQL strings returned by CreateTableSQL or CreateIndexSQL.
- -RETURNS: 0 if failed, 1 if executed all but with errors, 2 if executed successfully+
$sqlarray: an array of strings with sql code (no semicolon at the end of string)
$contOnError: if true, then continue executing even if error occurs
Executes an array of SQL strings returned by CreateTableSQL or +CreateIndexSQL.
+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 download the latest version of AXMLS here.
- +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 download +the latest version of AXMLS here.
First, create an XML database schema. Let's call it "schema.xml:"
-- <?xml version="1.0"?> - <schema version="0.2"> - <table name="mytable"> - <field name="row1" type="I"> - <descr>An integer row that's a primary key and autoincrements</descr> - <KEY/> - <AUTOINCREMENT/> - </field> - <field name="row2" type="C" size="16"> - <descr>A 16 character varchar row that can't be null</descr> - <NOTNULL/> - </field> - <index name="myindex"> - <col>row1</col> - <col>row2</col> - </index> - </table> - <sql> - <descr>SQL to be executed only on specific platforms</descr> - <query platform="postgres|postgres7"> - insert into mytable ( row1, row2 ) values ( 12, 'stuff' ) - </query> - <query platform="mysql"> - insert into mytable ( row1, row2 ) values ( 12, 'different stuff' ) - </query> - </sql> - </schema> -- -
Create a new database using the appropriate tool for your platform.
-Executing the following PHP code will create the a mytable and myindex
-in the database and insert one row into mytable if the platform is postgres or mysql.
- include_once('/path/to/adodb.inc.php'); - include_once('/path/to/adodb-xmlschema.inc.php'); - - // To build the schema, start by creating a normal ADOdb connection: - $db->NewADOConnection( 'mysql' ); - $db->Connect( ... ); - - // Create the schema object and build the query array. - $schema = new adoSchema( $db ); - - // Optionally, set a prefix for newly-created tables. In this example - // the prefix "myprefix_" will result in a table named "myprefix_tablename". - $schema->SetPrefix( 'myprefix_' ); - - // Build the SQL array - $schema->ParseSchema( 'schema.xml' ); - - // Execute the SQL on the database - $result = $schema->ExecuteSchema(); - - // Finally, clean up after the XML parser - // (PHP won't do this for you!) - $schema->Destroy(); -- - -
-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.
-Let's begin with a schema that describes a typical, if simplistic - user management table for an application.
---<?xml version="1.0"?> -<schema version="0.2"> - - <table name="users"> - <desc>A typical users table for our application.</desc> - <field name="userId" type="I"> - <descr>A unique ID assigned to each user.</descr> - <KEY/> - <AUTOINCREMENT/> - </field> - - <field name="userName" type="C" size="16"><NOTNULL/></field> - - <index name="userName"> - <descr>Put a unique index on the user name</descr> - <col>userName</col> - <UNIQUE/> - </index> - </table> - - <sql> - <descr>Insert some data into the users table.</descr> - <query>insert into users (userName) values ( 'admin' )</query> - <query>insert into users (userName) values ( 'Joe' )</query> - </sql> -</schema> -
Let's take a detailed look at this schema.
-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 - the version of the AXMLS DTD used by the XML - schema.
All versions of AXMLS prior - to version 1.0 have a schema version of "0.1". The current - schema version is "0.2".
---<?xml version="1.0"?> -<schema version="0.2"> - ... -</schema> -
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.
---<table name="users"> - - <desc>A typical users table for our application.</desc> - <field name="userId" type="I"> - <descr>A unique ID assigned to each user.</descr> - <KEY/> - <AUTOINCREMENT/> - </field> - - <field name="userName" type="C" size="16"><NOTNULL/></field> - -</table> -
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.
-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.
-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.
-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.
---<table name="users"> - ... - - <index name="userName"> - <descr>Put a unique index on the user name</descr> - <col>userName</col> - <UNIQUE/> - </index> - -</table> -
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.
-Finally, AXMLS allows you to include arbitrary SQL that - will be applied to the database when the schema is - executed.
---<sql> - <descr>Insert some data into the users table.</descr> - <query>insert into users (userName) values ( 'admin' )</query> - <query>insert into users (userName) values ( 'Joe' )</query> -</sql> -
The <sql> tag encloses any number - of SQL queries that you define for your own use.
-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.
---<?PHP -/* You must tell the script where to find the ADOdb and - * the AXMLS libraries. - */ -require( "path_to_adodb/adodb.inc.php"); -require( "path_to_adodb/adodb-xmlschema.inc.php" ); - -/* Configuration information. Define the schema filename, - * RDBMS platform (see the ADODB documentation for valid - * platform names), and database connection information here. - */ -$schemaFile = 'example.xml'; -$platform = 'mysql'; -$dbHost = 'localhost'; -$dbName = 'database'; -$dbUser = 'username'; -$dbPassword = 'password'; - -/* Start by creating a normal ADODB connection. - */ -$db = ADONewConnection( $platform ); -$db->Connect( $dbHost, $dbUser, $dbPassword, $dbName ); - -/* Use the database connection to create a new adoSchema object. - */ -$schema = new adoSchema( $db ); - -/* Call ParseSchema() to build SQL from the XML schema file. - * Then call ExecuteSchema() to apply the resulting SQL to - * the database. - */ -$sql = $schema->ParseSchema( $schemaFile ); -$result = $schema->ExecuteSchema(); -?> -
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.
-First, create a normal ADOdb connection. The variables - and values here should be those required to connect to your - database.
---$db = ADONewConnection( 'mysql' ); -$db->Connect( 'host', 'user', 'password', 'database' ); -
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.
---$schema = new adoSchema( $db ); -
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.
---$schema->ParseSchema( $schemaFile ); -$schema->ExecuteSchema(); -
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.
-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.
- -(See xmlschema.dtd for the full specification)
-- <?xml version="1.0"?> - <schema version="0.2"> - <table name="tablename" platform="platform1|platform2|..."> - <descr>Optional description</descr> - <field name="fieldname" type="datadict_type" size="size"> - <KEY/> - <NOTNULL/> - <AUTOINCREMENT/> - <DEFAULT value="value"/> - </field> - ... more fields - <index name="indexname" platform="platform1|platform2|..."> - <descr>Optional description</descr> - <col>fieldname</col> - ... more columns - </index> - ... more indexes - </table> - ... more tables - - <sql platform="platform1|platform2|..."> - <descr>Optional description</descr> - <query platform="platform1|platform2|...">SQL query</query> - ... more queries - </sql> - ... more SQL - </schema> -- +
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.
+ Installing axmls +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.
+ Using AXMLS in Your Application +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.
+Let's begin with a schema that describes a typical, if simplistic +user management table for an application.
++<?xml version="1.0"?>
<schema version="0.2">
<table name="users">
<desc>A typical users table for our application.</desc>
<field name="userId" type="I">
<descr>A unique ID assigned to each user.</descr>
<KEY/>
<AUTOINCREMENT/>
</field>
<field name="userName" type="C" size="16"><NOTNULL/></field>
<index name="userName">
<descr>Put a unique index on the user name</descr>
<col>userName</col>
<UNIQUE/>
</index>
</table>
<sql>
<descr>Insert some data into the users table.</descr>
<query>insert into users (userName) values ( 'admin' )</query>
<query>insert into users (userName) values ( 'Joe' )</query>
</sql>
</schema>
Let's take a detailed look at this schema.
+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 the version of the +AXMLS DTD used by the XML schema.
+All versions of AXMLS prior to version 1.0 have a schema version of +"0.1". The current schema version is "0.2".
++<?xml version="1.0"?>
<schema version="0.2">
...
</schema>
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.
++<table name="users">
<desc>A typical users table for our application.</desc>
<field name="userId" type="I">
<descr>A unique ID assigned to each user.</descr>
<KEY/>
<AUTOINCREMENT/>
</field>
<field name="userName" type="C" size="16"><NOTNULL/></field>
</table>
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.
+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.
+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.
+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.
++<table name="users">
...
<index name="userName">
<descr>Put a unique index on the user name</descr>
<col>userName</col>
<UNIQUE/>
</index>
</table>
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.
+Finally, AXMLS allows you to include arbitrary SQL that will be +applied to the database when the schema is executed.
++<sql>
<descr>Insert some data into the users table.</descr>
<query>insert into users (userName) values ( 'admin' )</query>
<query>insert into users (userName) values ( 'Joe' )</query>
</sql>
The <sql> tag encloses any number of SQL queries that you +define for your own use.
+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.
++<?PHP
/* You must tell the script where to find the ADOdb and
* the AXMLS libraries.
*/
require( "path_to_adodb/adodb.inc.php");
require( "path_to_adodb/adodb-xmlschema.inc.php" );
/* Configuration information. Define the schema filename,
* RDBMS platform (see the ADODB documentation for valid
* platform names), and database connection information here.
*/
$schemaFile = 'example.xml';
$platform = 'mysql';
$dbHost = 'localhost';
$dbName = 'database';
$dbUser = 'username';
$dbPassword = 'password';
/* Start by creating a normal ADODB connection.
*/
$db = ADONewConnection( $platform );
$db->Connect( $dbHost, $dbUser, $dbPassword, $dbName );
/* Use the database connection to create a new adoSchema object.
*/
$schema = new adoSchema( $db );
/* Call ParseSchema() to build SQL from the XML schema file.
* Then call ExecuteSchema() to apply the resulting SQL to
* the database.
*/
$sql = $schema->ParseSchema( $schemaFile );
$result = $schema->ExecuteSchema();
?>
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.
+First, create a normal ADOdb connection. The variables and values +here should be those required to connect to your database.
++$db = ADONewConnection( 'mysql' );
$db->Connect( 'host', 'user', 'password', 'database' );
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.
++$schema = new adoSchema( $db );
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.
++
$schema->ParseSchema( $schemaFile );
$schema->ExecuteSchema();
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.
+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.
V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my)
-This software is dual licensed using BSD-Style and LGPL. This - means you can use it in compiled proprietary and commercial products.
-Kindly note that the ADOdb home page has moved to http://adodb.sourceforge.net/ because of the persistent - unreliability of http://php.weblogs.com. Please change your links! |
Useful ADOdb links: Download Other Docs +
This software is dual licensed using BSD-Style and +LGPL. This means you can use it in compiled proprietary and commercial +products.
+Kindly note that the ADOdb home page has +moved to http://adodb.sourceforge.net/ +because of the persistent unreliability of http://php.weblogs.com. Please +change your links! | +
Useful ADOdb links: Download + Other Docs +
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: +
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:
$perf->HealthCheck()
- or $perf->HealthCheckCLI()
.
- $perf->UI()
.
- This UI displays:
+ $perf->HealthCheck()
+or $perf->HealthCheckCLI()
. $perf->UI()
.
+This UI displays:
$perf->DBParameter('data cache hit ratio')
returns
- this very important statistic in a database independant manner.
+ $perf->DBParameter('data cache hit
+ratio')
returns this very important statistic in a database
+independant manner. ADOdb also has the ability to log all SQL executed, using LogSQL. - All SQL logged can be analyzed through the performance monitor UI. - In the View SQL mode, we categorize the SQL into 3 types: +
ADOdb also has the ability to log all SQL executed, using LogSQL. All SQL logged can be +analyzed through the performance monitor UI. In the View +SQL mode, we categorize the SQL into 3 types: +
Each query is hyperlinked to a description of the query plan, and every PHP - script that executed that query is also shown.
-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:
+Each query is hyperlinked to a description of the query plan, and +every PHP script that executed that query is also shown.
+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:
You will need to connect to the database as an administrator to view most of - the parameters.
-Code improvements as very welcome, particularly adding new database parameters - and automated tuning hints.
+You will need to connect to the database as an administrator to view +most of the parameters.
+Code improvements as very welcome, particularly adding new database +parameters and automated tuning hints.
+Currently, the following drivers: mysql, postgres, oci8, - mssql, informix and db2 are supported. To create a - new performance monitor, call NewPerfMonitor( ) as demonstrated below:
--<?php -include_once('adodb.inc.php'); -session_start(); # session variables required for monitoring -$conn = ADONewConnection($driver); -$conn->Connect($server,$user,$pwd,$db); -$perf =& NewPerfMonitor($conn); -$perf->UI($pollsecs=5); -?> -+
Currently, the following drivers: mysql, postgres, +oci8, mssql, informix and db2 are +supported. To create a new performance monitor, call NewPerfMonitor( ) +as demonstrated below:
+<?php
include_once('adodb.inc.php');
session_start(); # session variables required for monitoring
$conn = ADONewConnection($driver);
$conn->Connect($server,$user,$pwd,$db);
$perf =& NewPerfMonitor($conn);
$perf->UI($pollsecs=5);
?>
It is also possible to retrieve a single database parameter:
-$size = $perf->DBParameter('data cache size'); -+
$size = $perf->DBParameter('data cache size');
-Thx to Fernando Ortiz for the informix module. -
function UI($pollsecs=5)
-Creates a web-based user interface for performance monitoring. When you click on Poll, -server statistics will be displayed every $pollsecs seconds. See Usage - above. -
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(). -
-
define('ADODB_PERF_NO_RUN_SQL',1);- -
Sample output follows below:
- - ADOdb Performance
- Monitor for localhost, db=test - PostgreSQL 7.3.2 on i686-pc-cygwin, compiled by GCC gcc (GCC) - 3.2 20020927 (prerelease) |
- Performance Stats View SQL - View Tables Poll Stats |
postgres7 | ||
Parameter | Value | Description |
Ratios | ||
statistics collector | TRUE | Value must be TRUE to enable hit ratio statistics (stats_start_collector,stats_row_level and stats_block_level must be set to true in postgresql.conf) |
data cache hit ratio | 99.7967555299239 | |
IO | ||
data reads | 125 | |
data writes | 21.78125000000000000 | Count of inserts/updates/deletes * coef |
Data Cache | ||
data cache buffers | 640 | Number of cache buffers. Tuning |
cache blocksize | 8192 | (estimate) |
data cache size | 5M | |
operating system cache size | 80M | (effective cache size) |
Memory Usage | ||
sort buffer size | 1M | Size of sort buffer (per query) |
Connections | ||
current connections | 0 | |
max connections | 32 | |
Parameters | ||
rollback buffers | 8 | WAL buffers |
random page cost | 4 | Cost of doing a seek (default=4). See random_page_cost |
ADOdb
+Performance Monitor for localhost, db=test + PostgreSQL 7.3.2 on i686-pc-cygwin, compiled by +GCC gcc (GCC) 3.2 20020927 (prerelease) |
+
Performance Stats View +SQL View Tables Poll +Stats | +
function HealthCheck()
-Returns database health check parameters as a HTML table. You will need to - echo or print the output of this function,
+
+ postgres7+ |
+ ||
Parameter | +Value | +Description | +
Ratios | +||
statistics collector | +TRUE | +Value must be TRUE to enable hit ratio statistics (stats_start_collector,stats_row_level +and stats_block_level must be set to true in postgresql.conf) | +
data cache hit ratio | +99.7967555299239 | ++ |
IO | +||
data reads | +125 | ++ |
data writes | +21.78125000000000000 | +Count of inserts/updates/deletes * coef | +
Data Cache | +||
data cache buffers | +640 | +Number of cache buffers. Tuning | +
cache blocksize | +8192 | +(estimate) | +
data cache size | +5M | ++ |
operating system cache size | +80M | +(effective cache size) | +
Memory Usage | +||
sort buffer size | +1M | +Size of sort buffer (per query) | +
Connections | +||
current connections | +0 | ++ |
max connections | +32 | ++ |
Parameters | +||
rollback buffers | +8 | +WAL buffers | +
random page cost | +4 | +Cost of doing a seek (default=4). See random_page_cost | +
function HealthCheck()
+Returns database health check parameters as a HTML table. You will +need to echo or print the output of this function,
function HealthCheckCLI()
-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:
---- Ratios -- - MyISAM cache hit ratio => 56.5635738832 - InnoDB cache hit ratio => 0 - sql cache hit ratio => 0 - -- IO -- - data reads => 2622 - data writes => 2415.5 - -- Data Cache -- - MyISAM data cache size => 512K - BDB data cache size => 8388600 - InnoDB data cache size => 8M - -- Memory Pools -- - read buffer size => 131072 - sort buffer size => 65528 - table cache => 4 - -- Connections -- - current connections => 3 - max connections => 100-
function Poll($pollSecs=5) - -
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: -
-Accumulating statistics... - Time WS-CPU% Hit% Sess Reads/s Writes/s -11:08:30 0.7 56.56 1 0.0000 0.0000 -11:08:33 1.8 56.56 2 0.0000 0.0000 -11:08:36 11.1 56.55 3 2.5000 0.0000 -11:08:39 9.8 56.55 2 3.1121 0.0000 -11:08:42 2.8 56.55 1 0.0000 0.0000 -11:08:45 7.4 56.55 2 0.0000 1.5000 --
WS-CPU% is the Web Server CPU load of the server that PHP is running - from (eg. the database client), and not the database. The Hit% is the - data cache hit ratio. Sess is the current number of sessions connected - to the database. If you are using persistent connections, this should not change - much. The Reads/s and Writes/s are synthetic values to give the - viewer a rough guide to I/O, and are not to be taken literally. +
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:
+-- Ratios --+
MyISAM cache hit ratio => 56.5635738832
InnoDB cache hit ratio => 0
sql cache hit ratio => 0
-- IO --
data reads => 2622
data writes => 2415.5
-- Data Cache --
MyISAM data cache size => 512K
BDB data cache size => 8388600
InnoDB data cache size => 8M
-- Memory Pools --
read buffer size => 131072
sort buffer size => 65528
table cache => 4
-- Connections --
current connections => 3
max connections => 100
function Poll($pollSecs=5) +
+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: +
+Accumulating statistics...+
Time WS-CPU% Hit% Sess Reads/s Writes/s
11:08:30 0.7 56.56 1 0.0000 0.0000
11:08:33 1.8 56.56 2 0.0000 0.0000
11:08:36 11.1 56.55 3 2.5000 0.0000
11:08:39 9.8 56.55 2 3.1121 0.0000
11:08:42 2.8 56.55 1 0.0000 0.0000
11:08:45 7.4 56.55 2 0.0000 1.5000
WS-CPU% is the Web Server CPU load of the server that PHP is +running from (eg. the database client), and not the database. The Hit% +is the data cache hit ratio. Sess is the current number of +sessions connected to the database. If you are using persistent +connections, this should not change much. The Reads/s and Writes/s +are synthetic values to give the viewer a rough guide to I/O, and are +not to be taken literally.
function SuspiciousSQL($numsql=10)
-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. -
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 $conn->LogSQL. -
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. - +
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. +
+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 $conn->LogSQL. +
+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.
function ExpensiveSQL($numsql=10)
-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. -
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 $conn->LogSQL. - -
For Oracle, Ixora Expensive SQL returns a list of SQL statements that are taking the most CPU load -when run. +
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. +
+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 $conn->LogSQL. +
+For Oracle, Ixora Expensive SQL returns a list of SQL statements +that are taking the most CPU load when run. +
function InvalidSQL($numsql=10)
Returns a list of invalid SQL as an HTML table. -
Data is taken from the adodb_logsql table, where the sql statements are logged when -$connection->LogSQL(true) is enabled. +
+Data is taken from the adodb_logsql table, where the sql statements +are logged when +$connection->LogSQL(true) is enabled. +
function Tables($orderby=1)
-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 vacuum. Not supported currently for db2.
+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 vacuum. +Not supported currently for db2.
Raw functions return values without any formatting.
function DBParameter($paramname)
-Returns the value of a database parameter, such as $this->DBParameter("data - cache size").
+Returns the value of a database parameter, such as +$this->DBParameter("data cache size").
function CPULoad()
-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.
+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.
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!
-Each database parameter is itself an array consisting of the following elements:
+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!
+Each database parameter is itself an array consisting of the +following elements:
Example from MySQL, table_cache database parameter:
-'table cache' => array('CACHE', # category code - array("show variables", 'table_cache'), # array (type 1b) - 'Number of tables to keep open'), # description+
'table cache' => array('CACHE', # category code
array("show variables", 'table_cache'), # array (type 1b)
'Number of tables to keep open'), # description
db2 informix mysql mssql - oci8 postgres
- - db2 |
- ||
Parameter | -Value | -Description | -
Ratios | -||
data cache hit ratio | -0 | -- |
Data Cache | -||
data cache buffers | -250 | -See tuning - reference. | -
cache blocksize | -4096 | -- |
data cache size | -1000K | -- |
Connections | -||
current connections | -2 | -- |
informix | ||
Parameter | Val -ue | Description |
Ratios | ||
data cache hit -ratio | 95.89 | |
IO | ||
data -reads | 1883884 | Page reads |
data writes | 1716724 | Page writes |
Connections - | ||
current connections | 263.0 | Number of -sessions |
-
mysql | ||
Parameter | Value | Description |
Ratios | ||
MyISAM cache hit ratio | 56.5658301822 | Cache ratio should be at least 90% |
InnoDB cache hit ratio | 0 | Cache ratio should be at least 90% |
sql cache hit ratio | 0 | |
IO | ||
data reads | 2622 | Number of selects (Key_reads is not accurate) |
data writes | 2415.5 | Number of inserts/updates/deletes * coef (Key_writes is not accurate) |
Data Cache | ||
MyISAM data cache size | 512K | |
BDB data cache size | 8388600 | |
InnoDB data cache size | 8M | |
Memory Pools | ||
read buffer size | 131072 | (per session) |
sort buffer size | 65528 | Size of sort buffer (per session) |
table cache | 4 | Number of tables to keep open |
Connections | ||
current connections | 3 | |
max connections | 100 |
+ db2+ |
+ ||
Parameter | +Value | +Description | +
Ratios | +||
data cache hit ratio | +0 | ++ |
Data Cache | +||
data cache buffers | +250 | +See tuning +reference. | +
cache blocksize | +4096 | ++ |
data cache size | +1000K | ++ |
Connections | +||
current connections | +2 | ++ |
- - -
mssql | ||
Parameter | Value | Description |
Ratios | ||
data cache hit ratio | 99.9999694824 | |
prepared sql hit ratio | 99.7738579828 | |
adhoc sql hit ratio | 98.4540169133 | |
IO | ||
data reads | 2858 | |
data writes | 1438 | |
Data Cache | ||
data cache size | 4362 | in K |
Connections | ||
current connections | 14 | |
max connections | 32767 |
+ informix+ |
+ ||
Parameter | +Val +ue | +Description | +
Ratios | +||
data cache hit +ratio | +95.89 | ++ |
IO | +||
data +reads | +1883884 | +Page reads | +
data writes | +1716724 | +Page writes | +
Connections + | +||
current connections | +263.0 | +Number of +sessions | +
- -
oci8 | ||
Parameter | Value | Description |
Ratios | ||
data cache hit ratio | 96.98 | |
sql cache hit ratio | 99.96 | |
IO | ||
data reads | 842938 | |
data writes | 16852 | |
Data Cache | ||
data cache buffers | 3072 | Number of cache buffers |
data cache blocksize | 8192 | |
data cache size | 48M | shared_pool_size |
Memory Pools | ||
java pool size | 0 | java_pool_size |
sort buffer size | 512K | sort_area_size (per query) |
user session buffer size | 8M | large_pool_size |
Connections | ||
current connections | 1 | |
max connections | 170 | |
data cache utilization ratio | 88.46 | Percentage of data cache actually in use |
user cache utilization ratio | 91.76 | Percentage of user cache (large_pool) actually in use |
rollback segments | 11 | |
Transactions | ||
peak transactions | 24 | Taken from high-water-mark |
max transactions | 187 | max transactions / rollback segments < 3.5 (or transactions_per_rollback_segment) |
Parameters | ||
cursor sharing | EXACT | Cursor reuse strategy. Recommended is FORCE (8i+) or SIMILAR (9i+). See cursor_sharing. |
index cache cost | 0 | % of indexed data blocks expected in the cache. - Recommended is 20-80. Default is 0. See optimizer_index_caching. |
random page cost | 100 | Recommended is 10-50 for TP, and 50 for data warehouses. Default is 100. See optimizer_index_cost_adj. |
+ mysql+ |
+ ||
Parameter | +Value | +Description | +
Ratios | +||
MyISAM cache hit ratio | +56.5658301822 | +Cache ratio should be at least 90% | +
InnoDB cache hit ratio | +0 | +Cache ratio should be at least 90% | +
sql cache hit ratio | +0 | ++ |
IO | +||
data reads | +2622 | +Number of selects (Key_reads is not accurate) | +
data writes | +2415.5 | +Number of inserts/updates/deletes * coef (Key_writes is not +accurate) | +
Data Cache | +||
MyISAM data cache size | +512K | ++ |
BDB data cache size | +8388600 | ++ |
InnoDB data cache size | +8M | ++ |
Memory Pools | +||
read buffer size | +131072 | +(per session) | +
sort buffer size | +65528 | +Size of sort buffer (per session) | +
table cache | +4 | +Number of tables to keep open | +
Connections | +||
current connections | +3 | ++ |
max connections | +100 | ++ |
+ +
+ mssql+ |
+ ||
Parameter | +Value | +Description | +
Ratios | +||
data cache hit ratio | +99.9999694824 | ++ |
prepared sql hit ratio | +99.7738579828 | ++ |
adhoc sql hit ratio | +98.4540169133 | ++ |
IO | +||
data reads | +2858 | ++ |
data writes | +1438 | ++ |
Data Cache | +||
data cache size | +4362 | +in K | +
Connections | +||
current connections | +14 | ++ |
max connections | +32767 | ++ |
+ +
+ oci8+ |
+ ||
Parameter | +Value | +Description | +
Ratios | +||
data cache hit ratio | +96.98 | ++ |
sql cache hit ratio | +99.96 | ++ |
IO | +||
data reads | +842938 | ++ |
data writes | +16852 | ++ |
Data Cache | +||
data cache buffers | +3072 | +Number of cache buffers | +
data cache blocksize | +8192 | ++ |
data cache size | +48M | +shared_pool_size | +
Memory Pools | +||
java pool size | +0 | +java_pool_size | +
sort buffer size | +512K | +sort_area_size (per query) | +
user session buffer size | +8M | +large_pool_size | +
Connections | +||
current connections | +1 | ++ |
max connections | +170 | ++ |
data cache utilization ratio | +88.46 | +Percentage of data cache actually in use | +
user cache utilization ratio | +91.76 | +Percentage of user cache (large_pool) actually in use | +
rollback segments | +11 | ++ |
Transactions | +||
peak transactions | +24 | +Taken from high-water-mark | +
max transactions | +187 | +max transactions / rollback segments < 3.5 (or +transactions_per_rollback_segment) | +
Parameters | +||
cursor sharing | +EXACT | +Cursor reuse strategy. Recommended is FORCE (8i+) or SIMILAR +(9i+). See cursor_sharing. | +
index cache cost | +0 | +% of indexed data blocks expected in the cache. Recommended +is 20-80. Default is 0. See optimizer_index_caching. | +
random page cost | +100 | +Recommended is 10-50 for TP, and 50 for data warehouses. +Default is 100. See optimizer_index_cost_adj. + | +
LOAD | EXECUTES | SQL_TEXT |
.73% | 89 | 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# |
.84% | 3 | 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 |
3.95% | 6 | 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' |
4.50% | 6 | 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 |
57.34% | 9267 | 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 |
LOAD | EXECUTES | SQL_TEXT |
5.24% | 1 | select round(sum(bytes)/1048576) from dba_segments |
6.89% | 6 | 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' |
7.85% | 6 | 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 |
33.69% | 89 | 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# |
36.44% | 89 | 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# |
postgres7 | ||
Parameter | Value | Description |
Ratios | ||
statistics collector | FALSE | Must be set to TRUE to enable hit ratio statistics (stats_start_collector,stats_row_level and stats_block_level must be set to true in postgresql.conf) |
data cache hit ratio | 99.9666031916603 | |
IO | ||
data reads | 15 | |
data writes | 0.000000000000000000 | Count of inserts/updates/deletes * coef |
Data Cache | ||
data cache buffers | 1280 | Number of cache buffers. Tuning |
cache blocksize | 8192 | (estimate) |
data cache size | 10M | |
operating system cache size | 80000K | (effective cache size) |
Memory Pools | ||
sort buffer size | 1M | Size of sort buffer (per query) |
Connections | ||
current connections | 13 | |
max connections | 32 | |
Parameters | ||
rollback buffers | 8 | WAL buffers |
random page cost | 4 | Cost of doing a seek (default=4). See random_page_cost |
LOAD | +EXECUTES | +SQL_TEXT | +
.73% | +89 | +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# | +
.84% | +3 | +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 | +
3.95% | +6 | +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' | +
4.50% | +6 | +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 | +
57.34% | +9267 | +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 | +
LOAD | +EXECUTES | +SQL_TEXT | +
5.24% | +1 | +select round(sum(bytes)/1048576) from dba_segments | +
6.89% | +6 | +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' | +
7.85% | +6 | +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 | +
33.69% | +89 | +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# | +
36.44% | +89 | +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# | +
+ postgres7+ |
+ ||
Parameter | +Value | +Description | +
Ratios | +||
statistics collector | +FALSE | +Must be set to TRUE to enable hit ratio statistics (stats_start_collector,stats_row_level +and stats_block_level must be set to true in postgresql.conf) | +
data cache hit ratio | +99.9666031916603 | ++ |
IO | +||
data reads | +15 | ++ |
data writes | +0.000000000000000000 | +Count of inserts/updates/deletes * coef | +
Data Cache | +||
data cache buffers | +1280 | +Number of cache buffers. Tuning | +
cache blocksize | +8192 | +(estimate) | +
data cache size | +10M | ++ |
operating system cache size | +80000K | +(effective cache size) | +
Memory Pools | +||
sort buffer size | +1M | +Size of sort buffer (per query) | +
Connections | +||
current connections | +13 | ++ |
max connections | +32 | ++ |
Parameters | +||
rollback buffers | +8 | +WAL buffers | +
random page cost | +4 | +Cost of doing a seek (default=4). See random_page_cost | +
V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my) -
This software is dual licensed using BSD-Style and LGPL. This - means you can use it in compiled proprietary and commercial products. -
Kindly note that the ADOdb home page has moved to http://adodb.sourceforge.net/ because of the persistent - unreliability of http://php.weblogs.com. Please change your links! |
Useful ADOdb links: Download Other Docs - +
+This software is dual licensed using BSD-Style and +LGPL. This means you can use it in compiled proprietary and commercial +products. +
Kindly note that the ADOdb home page has +moved to http://adodb.sourceforge.net/ +because of the persistent unreliability of http://php.weblogs.com. Please +change your links! | +
Useful ADOdb links: Download + Other Docs +
-We store state information specific to a user or web client in session variables. These session variables - persist throughout a session, as the user moves from page to page. -
-To use session variables, call session_start() at the beginning of your web page, -before your HTTP headers are sent. Then for every variable you want to keep alive -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. -
The default method of storing sessions is to store it in a file. However if - you have special needs such as you: +
We store state information specific to a user or web client in +session variables. These session variables persist throughout a +session, as the user moves from page to page.
+To use session variables, call session_start() at the beginning of +your web page, before your HTTP headers are sent. Then for every +variable you want to keep alive 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. +
+The default method of storing sessions is to store it in a file. +However if you have special needs such as you: +
Then the ADOdb session handler provides you with the above additional capabilities - by storing the session information as records in a database table that can be - shared across multiple servers. -
Important Upgrade Notice: Since ADOdb 4.05, the session files have been moved to its own folder, adodb/session. This is a rewrite -of the session code by Ross Smith. The old session code is in adodb/session/old. +
Then the ADOdb session handler provides you with the above +additional capabilities by storing the session information as records +in a database table that can be shared across multiple servers.
+Important Upgrade Notice: Since ADOdb 4.05, the session files +have been moved to its own folder, adodb/session. This is a rewrite +of the session code by Ross Smith. The old session code is in +adodb/session/old.
There are 3 session management files that you can use: -
-adodb-session.php : The default -adodb-session-clob.php : Use this if you are storing DATA in clobs -adodb-cryptsession.php : Use this if you want to store encrypted session data in the database - -Examples - - include('adodb/adodb.inc.php'); - - $ADODB_SESSION_DRIVER='mysql'; - $ADODB_SESSION_CONNECT='localhost'; - $ADODB_SESSION_USER ='scott'; - $ADODB_SESSION_PWD ='tiger'; - $ADODB_SESSION_DB ='sessiondb'; - - include('adodb/session/adodb-session.php'); - session_start(); - - # - # Test session vars, the following should increment on refresh - # - $_SESSION['AVAR'] += 1; - print "<p>\$_SESSION['AVAR']={$_SESSION['AVAR']}</p>"; - -To force non-persistent connections, call adodb_session_open first before session_start(): - - include('adodb/adodb.inc.php'); - - $ADODB_SESSION_DRIVER='mysql'; - $ADODB_SESSION_CONNECT='localhost'; - $ADODB_SESSION_USER ='scott'; - $ADODB_SESSION_PWD ='tiger'; - $ADODB_SESSION_DB ='sessiondb'; - - include('adodb/session/adodb-session.php'); - adodb_sess_open(false,false,false); - session_start(); - -To use a encrypted sessions, simply replace the file: - - include('adodb/adodb.inc.php'); - - $ADODB_SESSION_DRIVER='mysql'; - $ADODB_SESSION_CONNECT='localhost'; - $ADODB_SESSION_USER ='scott'; - $ADODB_SESSION_PWD ='tiger'; - $ADODB_SESSION_DB ='sessiondb'; - - include('adodb/session/adodb-cryptsession.php'); - session_start(); - -And the same technique for adodb-session-clob.php: - - include('adodb/adodb.inc.php'); - - $ADODB_SESSION_DRIVER='mysql'; - $ADODB_SESSION_CONNECT='localhost'; - $ADODB_SESSION_USER ='scott'; - $ADODB_SESSION_PWD ='tiger'; - $ADODB_SESSION_DB ='sessiondb'; - - include('adodb/session/adodb-session-clob.php'); - session_start(); - + +adodb-session.php : The default+
adodb-session-clob.php : Use this if you are storing DATA in clobs
adodb-cryptsession.php : Use this if you want to store encrypted session data in the database
+Examples +
+ include('adodb/adodb.inc.php');+
$ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';
include('adodb/session/adodb-session.php');
session_start();
#
# Test session vars, the following should increment on refresh
#
$_SESSION['AVAR'] += 1;
print "<p>\$_SESSION['AVAR']={$_SESSION['AVAR']}</p>";To force non-persistent connections, call adodb_session_open first before session_start():
+
++
include('adodb/adodb.inc.php');
$ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';
include('adodb/session/adodb-session.php');
adodb_sess_open(false,false,false);
session_start();
+To use a encrypted sessions, simply replace the file:
++
include('adodb/adodb.inc.php');
$ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';
include('adodb/session/adodb-cryptsession.php');
session_start();
+And the same technique for adodb-session-clob.php:
+
include('adodb/adodb.inc.php');
$ADODB_SESSION_DRIVER='mysql';
$ADODB_SESSION_CONNECT='localhost';
$ADODB_SESSION_USER ='scott';
$ADODB_SESSION_PWD ='tiger';
$ADODB_SESSION_DB ='sessiondb';
include('adodb/session/adodb-session-clob.php');
session_start(); +Installation
- 1. Create this table in your database (syntax might vary depending on your db): - - create table sessions ( - SESSKEY char(32) not null, - EXPIRY int(11) unsigned not null, - EXPIREREF varchar(64), - DATA text not null, - primary key (sesskey) - ); - - For the adodb-session-clob.php version, create this: - - create table sessions ( - SESSKEY char(32) not null, - EXPIRY int(11) unsigned not null, - EXPIREREF varchar(64), - DATA CLOB, - primary key (sesskey) - ); - - 2. Then define the following parameters. You can either modify - this file, or define them before this file is included: - - $ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase'; - $ADODB_SESSION_CONNECT='server to connect to'; - $ADODB_SESSION_USER ='user'; - $ADODB_SESSION_PWD ='password'; - $ADODB_SESSION_DB ='database'; - $ADODB_SESSION_TBL = 'sessions'; # setting this is optional - - When the session is created, $ADODB_SESS_CONN holds the connection object. - - 3. Recommended is PHP 4.0.6 or later. There are documented session bugs - in earlier versions of PHP. +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 the adodb-session-clob.php version, create this: +
++
create table sessions (
SESSKEY char(32) not null,
EXPIRY int(11) unsigned not null,
EXPIREREF varchar(64),
DATA CLOB,
primary key (sesskey)
); +2. Then define the following parameters. You can either modify this file, or define them before this file is included: +
$ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
$ADODB_SESSION_CONNECT='server to connect to';
$ADODB_SESSION_USER ='user';
$ADODB_SESSION_PWD ='password';
$ADODB_SESSION_DB ='database';
$ADODB_SESSION_TBL = 'sessions'; # setting this is optional
++ When the session is created, $ADODB_SESS_CONN holds the connection object.
3. Recommended is PHP 4.0.6 or later. There are documented session bugs
in earlier versions of PHP. +Notifications
+If you want to receive notification when a session expires, then tag +the session record with a EXPIREREF tag (see +the definition of the sessions table above). Before any session record +is deleted, ADOdb will call a notification function, passing in the +EXPIREREF. +
+When a session is first created, we check a global variable +$ADODB_SESSION_EXPIRE_NOTIFY. This is an array with 2 elements, the +first being the name of the session variable you would like to store in +the EXPIREREF field, and the 2nd is the notification function's name.
+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:
++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. +
$ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
Here is an example of a Notification function that deletes some +records in the database and temporary files:
++
function NotifyFn($expireref, $sesskey)
{
global $ADODB_SESS_CONN; # the session connection object
$user = $ADODB_SESS_CONN->qstr($expireref);
$ADODB_SESS_CONN->Execute("delete from shopping_cart where user=$user");
system("rm /work/tmpfiles/$expireref/*");
}
NOTE 1: If you have register_globals disabled in php.ini, then you +will have to manually set the EXPIREREF. E.g.
++ $GLOBALS['USERID'] =& $_SESSION['USERID']; + $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');- -Notifications
-If you want to receive notification when a session expires, then - tag the session record with a EXPIREREF tag (see the - definition of the sessions table above). Before any session record is deleted, - ADOdb will call a notification function, passing in the EXPIREREF. -
-When a session is first created, we check a global variable $ADODB_SESSION_EXPIRE_NOTIFY. - This is an array with 2 elements, the first being the name of the session variable - you would like to store in the EXPIREREF field, and the 2nd is the - notification function's name. -
- Suppose we want to be notified when a user's session - has expired, based on the userid. The user id in the global session variable $USERID. - The function name is 'NotifyFn'. So we define: -
- $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn'); -- And when the NotifyFn is called (when the session expires), we pass the $USERID - as the first parameter, eg. NotifyFn($userid, $sesskey). The session key (which is - the primary key of the record in the sessions table) is the 2nd parameter. -- Here is an example of a Notification function that deletes some records in the database - and temporary files: -
- function NotifyFn($expireref, $sesskey) - { - global $ADODB_SESS_CONN; # the session connection object - - $user = $ADODB_SESS_CONN->qstr($expireref); - $ADODB_SESS_CONN->Execute("delete from shopping_cart where user=$user"); - system("rm /work/tmpfiles/$expireref/*"); - } --- NOTE 1: If you have register_globals disabled in php.ini, then you will have to - manually set the EXPIREREF. E.g. -
- $GLOBALS['USERID'] =& $_SESSION['USERID']; - $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn'); --- 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. - +
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. +
Neat Notification Tricks
-ExpireRef normally holds the user id of the current session. -
-1. You can then write a session monitor, scanning expireref to see +
+1. You can then write a session monitor, scanning expireref to see who is currently logged on. -
-2. If you delete the sessions record for a specific user, eg. -
-delete from sessions where expireref = '$USER' -+ +2. If you delete the sessions record for a specific user, eg. +
+delete from sessions where expireref = '$USER'then the user is logged out. Useful for ejecting someone from a site. --3. You can scan the sessions table to ensure no user +
3. You can scan the sessions table to ensure no user can be logged in twice. Useful for security reasons. -
- +
Compression/Encryption Schemes
-Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and compression schemes are supported. - Currently, supported: -- MD5Crypt (crypt.inc.php) - MCrypt - Secure (Horde's emulation of MCrypt, if MCrypt module is not available.) - GZip - BZip2 --These are stackable. E.g. --ADODB_Session::filter(new ADODB_Compress_Bzip2()); -ADODB_Session::filter(new ADODB_Encrypt_MD5()); --will compress and then encrypt the record in the database. +Since ADOdb 4.05, thanks to Ross Smith, multiple encryption and +compression schemes are supported. Currently, supported are:-Also see the core ADOdb documentation. +
MD5Crypt (crypt.inc.php)+
MCrypt
Secure (Horde's emulation of MCrypt, if MCrypt module is not available.)
GZip
BZip2These are stackable. E.g. +
ADODB_Session::filter(new ADODB_Compress_Bzip2());+will compress and then encrypt the record in the database. +
ADODB_Session::filter(new ADODB_Encrypt_MD5());Also see the core ADOdb documentation. +
- \ No newline at end of file +