<?php
/*
-@version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+@version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Latest version is available at http://adodb.sourceforge.net
Released under both BSD license and Lesser GPL library license.
Active Record implementation. Superset of Zend Framework's.
- Version 0.09
+ Version 0.08
See http://www-128.ibm.com/developerworks/java/library/j-cb03076/?ca=dgr-lnxw01ActiveRecord
for info on Ruby on Rails Active Record implementation
}
$obj = new ADODB_Active_DB();
- $obj->db =& $db;
+ $obj->db = $db;
$obj->tables = array();
$_ADODB_ACTIVE_DBS[] = $obj;
var $_lasterr = false; // last error message
var $_original = false; // the original values loaded or inserted, refreshed on update
- // should be static
- function UseDefaultValues($bool=null)
+ static function UseDefaultValues($bool=null)
{
global $ADODB_ACTIVE_DEFVALS;
if (isset($bool)) $ADODB_ACTIVE_DEFVALS = $bool;
}
// should be static
- function SetDatabaseAdapter(&$db)
+ static function SetDatabaseAdapter(&$db)
{
return ADODB_SetDatabaseAdapter($db);
}
- // php4 constructor
- function ADODB_Active_Record($table = false, $pkeyarr=false, $db=false)
+
+ public function __set($name, $value)
{
- ADODB_Active_Record::__construct($table,$pkeyarr,$db);
+ $name = str_replace(' ', '_', $name);
+ $this->$name = $value;
}
// php5 constructor
global $ADODB_ASSOC_CASE,$_ADODB_ACTIVE_DBS , $ADODB_CACHE_DIR, $ADODB_ACTIVE_CACHESECS;
global $ADODB_ACTIVE_DEFVALS;
- $activedb =& $_ADODB_ACTIVE_DBS[$this->_dbat];
+ $activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
$table = $this->_table;
$tables = $activedb->tables;
$tableat = $this->_tableat;
if (!$forceUpdate && !empty($tables[$tableat])) {
- $tobj =& $tables[$tableat];
+
+ $tobj = $tables[$tableat];
foreach($tobj->flds as $name => $fld) {
- if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value))
- $this->$name = $fld->default_value;
- else
- $this->$name = null;
+ if ($ADODB_ACTIVE_DEFVALS && isset($fld->default_value))
+ $this->$name = $fld->default_value;
+ else
+ $this->$name = null;
}
return;
}
- $db =& $activedb->db;
+ $db = $activedb->db;
$fname = $ADODB_CACHE_DIR . '/adodb_' . $db->databaseType . '_active_'. $table . '.cache';
if (!$forceUpdate && $ADODB_ACTIVE_CACHESECS && $ADODB_CACHE_DIR && file_exists($fname)) {
$fp = fopen($fname,'r');
if ($this->_dbat < 0) $db = false;
else {
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
- $db =& $activedb->db;
+ $db = $activedb->db;
}
if (function_exists('adodb_throw')) {
// retrieve ADOConnection from _ADODB_Active_DBs
- function &DB()
+ function DB()
{
global $_ADODB_ACTIVE_DBS;
return $false;
}
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
- $db =& $activedb->db;
+ $db = $activedb->db;
return $db;
}
// retrieve ADODB_Active_Table
- function &TableInfo()
+ function TableInfo()
{
global $_ADODB_ACTIVE_DBS;
$activedb = $_ADODB_ACTIVE_DBS[$this->_dbat];
- $table =& $activedb->tables[$this->_tableat];
+ $table = $activedb->tables[$this->_tableat];
return $table;
}
{
global $ACTIVE_RECORD_SAFETY;
- $db =& $this->DB();
+ $db = $this->DB();
if (!$row) {
$this->_saved = false;
$this->_saved = true;
- $table =& $this->TableInfo();
+ $table = $this->TableInfo();
if ($ACTIVE_RECORD_SAFETY && sizeof($table->flds) != sizeof($row)) {
+ # <AP>
$bad_size = TRUE;
if (sizeof($row) == 2 * sizeof($table->flds)) {
// Only keep string keys
$bad_size = FALSE;
}
if ($bad_size) {
- $this->Error("Table structure of $this->_table has changed","Load");
- return false;
- }
+ $this->Error("Table structure of $this->_table has changed","Load");
+ return false;
+ }
+ # </AP>
}
else
- $keys = array_keys($row);
-
+ $keys = array_keys($row);
+ # <AP>
reset($keys);
$this->_original = array();
foreach($table->flds as $name=>$fld) {
function Load($where,$bindarr=false)
{
- $db =& $this->DB(); if (!$db) return false;
+ $db = $this->DB(); if (!$db) return false;
$this->_where = $where;
$save = $db->SetFetchMode(ADODB_FETCH_NUM);
// false on error
function Insert()
{
- $db =& $this->DB(); if (!$db) return false;
+ $db = $this->DB(); if (!$db) return false;
$cnt = 0;
- $table =& $this->TableInfo();
+ $table = $this->TableInfo();
$valarr = array();
$names = array();
function Delete()
{
- $db =& $this->DB(); if (!$db) return false;
- $table =& $this->TableInfo();
+ $db = $this->DB(); if (!$db) return false;
+ $table = $this->TableInfo();
$where = $this->GenWhere($db,$table);
$sql = 'DELETE FROM '.$this->_table.' WHERE '.$where;
}
// returns an array of active record objects
- function &Find($whereOrderBy,$bindarr=false,$pkeysArr=false)
+ function Find($whereOrderBy,$bindarr=false,$pkeysArr=false)
{
- $db =& $this->DB(); if (!$db || empty($this->_table)) return false;
- $arr =& $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr);
+ $db = $this->DB(); if (!$db || empty($this->_table)) return false;
+ $arr = $db->GetActiveRecordsClass(get_class($this),$this->_table, $whereOrderBy,$bindarr,$pkeysArr);
return $arr;
}
{
global $ADODB_ASSOC_CASE;
- $db =& $this->DB(); if (!$db) return false;
- $table =& $this->TableInfo();
+ $db = $this->DB(); if (!$db) return false;
+ $table = $this->TableInfo();
$pkey = $table->keys;
}
}
- $this->_original =& $valarr;
+ $this->_original = $valarr;
}
return $ok;
}
// returns 0 on error, 1 on update, -1 if no change in data (no update)
function Update()
{
- $db =& $this->DB(); if (!$db) return false;
- $table =& $this->TableInfo();
+ $db = $this->DB(); if (!$db) return false;
+ $table = $this->TableInfo();
$where = $this->GenWhere($db, $table);
$sql = 'UPDATE '.$this->_table." SET ".implode(",",$pairs)." WHERE ".$where;
$ok = $db->Execute($sql,$valarr);
if ($ok) {
- $this->_original =& $neworig;
+ $this->_original = $neworig;
return 1;
}
return 0;
function GetAttributeNames()
{
- $table =& $this->TableInfo();
+ $table = $this->TableInfo();
if (!$table) return false;
return array_keys($table->flds);
}
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
$line = "====1,$tt,$sql\n";
if ($rs->databaseType == 'array') {
- $rows =& $rs->_array;
+ $rows = $rs->_array;
} else {
$rows = array();
while (!$rs->EOF) {
}
for($i=0; $i < $max; $i++) {
- $o =& $rs->FetchField($i);
+ $o = $rs->FetchField($i);
$flds[] = $o;
}
* error occurred in sql INSERT/UPDATE/DELETE,
* empty recordset is returned
*/
- function &csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
+ function csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
{
$false = false;
$err = false;
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
return $this->connection->MetaIndexes($this->TableName($table), $primary, $owner);
}
-
function MetaType($t,$len=-1,$fieldobj=false)
{
static $typeMap = array(
function ExecuteSQLArray($sql, $continueOnError = true)
{
$rez = 2;
- $conn = &$this->connection;
+ $conn = $this->connection;
$saved = $conn->debug;
foreach($sql as $line) {
<?php
/**
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
<?php
/**
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
<?php
/**
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
* Returns last PEAR_Error object. This error might be for an error that
* occured several sql statements ago.
*/
-function &ADODB_PEAR_Error()
+function ADODB_PEAR_Error()
{
global $ADODB_Last_PEAR_Error;
<?php
/**
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Iterator code based on http://cvs.php.net/cvs.php/php-src/ext/spl/examples/cachingiterator.inc?login=2
- */
-
-
- class ADODB_Iterator implements Iterator {
-
- private $rs;
-
- function __construct($rs)
- {
- $this->rs = $rs;
- }
- function rewind()
- {
- $this->rs->MoveFirst();
- }
-
- function valid()
- {
- return !$this->rs->EOF;
- }
-
- function key()
- {
- return $this->rs->_currentRow;
- }
- function current()
- {
- return $this->rs->fields;
- }
- function next()
- {
- $this->rs->MoveNext();
- }
-
- function __call($func, $params)
- {
- return call_user_func_array(array($this->rs, $func), $params);
- }
-
-
- function hasMore()
- {
- return !$this->rs->EOF;
- }
-
-}
+ Moved to adodb.inc.php to improve performance.
+ */
+
-class ADODB_BASE_RS implements IteratorAggregate {
- function getIterator() {
- return new ADODB_Iterator($this);
- }
-
- /* this is experimental - i don't really know what to return... */
- function __toString()
- {
- include_once(ADODB_DIR.'/toexport.inc.php');
- return _adodb_export($this,',',',',false,true);
- }
-}
?>
\ No newline at end of file
<?php
-
+
+
+
+
// security - hide paths
if (!defined('ADODB_DIR')) die();
$ADODB_INCLUDED_LIB = 1;
/*
- @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim\@natsoft.com.my). All rights reserved.
+ @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim\@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
for ($j=0;$j < $max; $j++) {
- $row =& $array[$j];
+ $row = $array[$j];
if (!$row) break;
$i = -1;
foreach($row as $v) {
} else if (strncmp($zthis->databaseType,'postgres',8) == 0 || strncmp($zthis->databaseType,'mysql',5) == 0) {
$rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
} else {
- $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) ";
+ $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
}
- } else {
+ } else {
// now replace SELECT ... FROM with SELECT COUNT(*) FROM
$rewritesql = preg_replace(
'/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
if (isset($rewritesql) && $rewritesql != $sql) {
if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
-
+
if ($secs2cache) {
// we only use half the time of secs2cache because the count can quickly
// become inaccurate if new records are added
if (preg_match('/\sLIMIT\s+[0-9]+/i',$sql,$limitarr)) $rewritesql .= $limitarr[0];
- $rstest = &$zthis->Execute($rewritesql,$inputarr);
+ $rstest = $zthis->Execute($rewritesql,$inputarr);
if (!$rstest) $rstest = $zthis->Execute($sql,$inputarr);
if ($rstest) {
data will get out of synch. use CachePageExecute() only with tables that
rarely change.
*/
-function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
+function _adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
$inputarr=false, $secs2cache=0)
{
$atfirstpage = false;
// We get the data we want
$offset = $nrows * ($page-1);
if ($secs2cache > 0)
- $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
+ $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
else
- $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
+ $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
// Before returning the RecordSet, we set the pagination properties we need
return $rsreturn;
}
-// Iván Oliva version
-function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
+// Iv�n Oliva version
+function _adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
{
$atfirstpage = false;
// the last page number.
$pagecounter = $page + 1;
$pagecounteroffset = ($pagecounter * $nrows) - $nrows;
- if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
- else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
+ if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
+ else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
if ($rstest) {
while ($rstest && $rstest->EOF && $pagecounter>0) {
$atlastpage = true;
$pagecounter--;
$pagecounteroffset = $nrows * ($pagecounter - 1);
$rstest->Close();
- if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
- else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
+ if ($secs2cache>0) $rstest = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
+ else $rstest = $zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
}
if ($rstest) $rstest->Close();
}
// We get the data we want
$offset = $nrows * ($page-1);
- if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
- else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
+ if ($secs2cache > 0) $rsreturn = $zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
+ else $rsreturn = $zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
// Before returning the RecordSet, we set the pagination properties we need
if ($rsreturn) {
//php can't do a $rsclass::MetaType()
$rsclass = $zthis->rsPrefix.$zthis->databaseType;
$recordSet = new $rsclass(-1,$zthis->fetchMode);
- $recordSet->connection = &$zthis;
+ $recordSet->connection = $zthis;
if (is_string($cacheRS) && $cacheRS == $rs) {
- $columns =& $cacheCols;
+ $columns = $cacheCols;
} else {
$columns = $zthis->MetaColumns( $tableName );
$cacheRS = $tableName;
}
} else if (is_subclass_of($rs, 'adorecordset')) {
if (isset($rs->insertSig) && is_integer($cacheRS) && $cacheRS == $rs->insertSig) {
- $columns =& $cacheCols;
+ $columns = $cacheCols;
} else {
for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
$columns[] = $rs->FetchField($i);
$cacheCols = $columns;
$rs->insertSig = $cacheSig++;
}
- $recordSet =& $rs;
+ $recordSet = $rs;
} else {
printf(ADODB_BAD_RS,'GetInsertSQL');
case "D":
$val = $zthis->DBDate($arrFields[$fname]);
break;
-
+
case "T":
$val = $zthis->DBTimeStamp($arrFields[$fname]);
break;
case "N":
$val = $arrFields[$fname];
if (!is_numeric($val)) $val = str_replace(',', '.', (float)$val);
- break;
+ break;
case "L": //Integer field suitable for storing booleans (0 or 1) // Moodle added
case "I":
}
*/
-?>
+?>
\ No newline at end of file
*/
- function &getmemcache($key,&$err, $timeout=0, $host, $port)
+ function getmemcache($key,&$err, $timeout=0, $host, $port)
{
$false = false;
$err = false;
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
$savec = $ADODB_COUNTRECS;
if ($this->db->pageExecuteCountRows) $ADODB_COUNTRECS = true;
if ($this->cache)
- $rs = &$this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page);
+ $rs = $this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page);
else
- $rs = &$this->db->PageExecute($this->sql,$rows,$this->curr_page);
+ $rs = $this->db->PageExecute($this->sql,$rows,$this->curr_page);
$ADODB_COUNTRECS = $savec;
- $this->rs = &$rs;
+ $this->rs = $rs;
if (!$rs) {
print "<h3>Query failed: $this->sql</h3>";
return;
<?php
/**
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
* error
*/
- function &factory($type)
+ function factory($type)
{
include_once(ADODB_DIR."/drivers/adodb-$type.inc.php");
- $obj = &NewADOConnection($type);
- if (!is_object($obj)) $obj =& new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
+ $obj = NewADOConnection($type);
+ if (!is_object($obj)) $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
return $obj;
}
* @see DB::parseDSN
* @see DB::isError
*/
- function &connect($dsn, $options = false)
+ function connect($dsn, $options = false)
{
if (is_array($dsn)) {
$dsninfo = $dsn;
@include_once("adodb-$type.inc.php");
}
- @$obj =& NewADOConnection($type);
+ @$obj = NewADOConnection($type);
if (!is_object($obj)) {
- $obj =& new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
+ $obj = new PEAR_Error('Unknown Database Driver: '.$dsninfo['phptype'],-1);
return $obj;
}
if (is_array($options)) {
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
if (!defined('ADODB_DIR')) include_once(dirname(__FILE__).'/adodb.inc.php');
include_once(ADODB_DIR.'/tohtml.inc.php');
+define( 'ADODB_OPT_HIGH', 2);
+define( 'ADODB_OPT_LOW', 1);
+
global $ADODB_PERF_MIN;
$ADODB_PERF_MIN = 0.05; // log only if >= minimum number of secs to run
-define( 'ADODB_OPT_HIGH', 2);
-define( 'ADODB_OPT_LOW', 1);
// returns in K the memory of current process, or 0 if not known
function adodb_getmem()
}
/* sql code timing */
-function& adodb_log_sql(&$connx,$sql,$inputarr)
+function adodb_log_sql(&$connx,$sql,$inputarr)
{
$perf_table = adodb_perf::table();
$connx->fnExecute = false;
$t0 = microtime();
- $rs =& $connx->Execute($sql,$inputarr);
+ $rs = $connx->Execute($sql,$inputarr);
$t1 = microtime();
if (!empty($connx->_logsql) && (empty($connx->_logsqlErrors) || !$rs)) {
global $ADODB_LOG_CONN;
if (!empty($ADODB_LOG_CONN)) {
- $conn = &$ADODB_LOG_CONN;
+ $conn = $ADODB_LOG_CONN;
if ($conn->databaseType != $connx->databaseType)
$prefix = '/*dbx='.$connx->databaseType .'*/ ';
else
$prefix = '';
} else {
- $conn =& $connx;
+ $conn = $connx;
$prefix = '';
}
if ($dbT == 'db2') $arr['f'] = (float) $arr['f'];
$isql = "insert into $perf_table (created,sql0,sql1,params,tracer,timer) values( $d,?,?,?,?,?)";
}
+
global $ADODB_PERF_MIN;
if ($errN != 0 || $time >= $ADODB_PERF_MIN) {
$ok = $conn->Execute($isql,$arr);
- } else {
+ } else
$ok = true;
- }
+
$conn->debug = $saved;
if ($ok) {
} else {
$err2 = $conn->ErrorMsg();
$conn->_logsql = true; // enable logsql error simulation
- $perf =& NewPerfMonitor($conn);
+ $perf = NewPerfMonitor($conn);
if ($perf) {
if ($perf->CreateLogTable()) $ok = $conn->Execute($isql,$arr);
} else {
var $maxLength = 2000;
// Sets the tablename to be used
- function table($newtable = false)
+ static function table($newtable = false)
{
static $_table;
$saveE = $this->conn->fnExecute;
$this->conn->fnExecute = false;
$perf_table = adodb_perf::table();
- $rs =& $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
+ $rs = $this->conn->SelectLimit("select distinct count(*),sql1,tracer as error_msg from $perf_table where tracer like 'ERROR:%' group by sql1,tracer order by 1 desc",$numsql);//,$numsql);
$this->conn->fnExecute = $saveE;
if ($rs) {
$s .= rs2html($rs,false,false,false,false);
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
//$this->conn->debug=1;
- $rs =& $this->conn->SelectLimit(
+ $rs = $this->conn->SelectLimit(
"select avg(timer) as avg_timer,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
from $perf_table
where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
- $rs =& $this->conn->SelectLimit(
+ $rs = $this->conn->SelectLimit(
"select sum(timer) as total,$sql1,count(*),max(timer) as max_timer,min(timer) as min_timer
from $perf_table
where {$this->conn->upperCase}({$this->conn->substr}(sql0,1,5)) not in ('DROP ','INSER','COMMI','CREAT')
/*
Raw function returning array of poll paramters
*/
- function &PollParameters()
+ function PollParameters()
{
$arr[0] = (float)$this->DBParameter('data cache hit ratio');
$arr[1] = (float)$this->DBParameter('data reads');
$perf_table = adodb_perf::table();
$this->conn->Execute("delete from $perf_table where created<".$this->conn->sysTimeStamp);
}
-
/***********************************************************************************************/
// HIGH LEVEL UI FUNCTIONS
/***********************************************************************************************/
-
+
function UI($pollsecs=5)
{
switch ($do) {
default:
case 'stats':
-
if (empty($ADODB_LOG_CONN))
echo "<p> <a href=\"?do=viewsql&clearsql=1\">Clear SQL Log</a><br>";
echo $this->HealthCheck();
//$this->conn->debug=1;
- echo $this->CheckMemory();
- global $ADODB_LOG_CONN;
+ echo $this->CheckMemory();
break;
case 'poll':
echo "<iframe width=720 height=80%
//$this->conn->debug=1;
if ($secs <= 1) $secs = 1;
echo "Accumulating statistics, every $secs seconds...\n";flush();
- $arro =& $this->PollParameters();
+ $arro = $this->PollParameters();
$cnt = 0;
set_time_limit(0);
sleep($secs);
while (1) {
- $arr =& $this->PollParameters();
+ $arr = $this->PollParameters();
$hits = sprintf('%2.2f',$arr[0]);
$reads = sprintf('%12.4f',($arr[1]-$arro[1])/$secs);
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
$t = adodb_mktime($h,0,0,$m,$d,$y1);
$rez = adodb_date('Y-n-j H:i:s',$t);
if ($h == 0) $h = '00';
- else if ($h < 10) $h = '0'.$h;
+ else if ($h < 10) $h = '0'.$h;
if ("$y1-$m-$d $h:00:00" != $rez) {
print "<b>$y1 error, expected=$y1-$m-$d $h:00:00, adodb=$rez</b><br>";
return false;
/**
Test Suite
-*/
+*/
function adodb_date_test()
{
return $ret;
}
+
?>
\ No newline at end of file
-<?php
-// Copyright (c) 2004 ars Cognita Inc., all rights reserved
-/* ******************************************************************************
- Released under both BSD license and Lesser GPL library license.
- Whenever there is any discrepancy between the two licenses,
- the BSD license will take precedence.
-*******************************************************************************/
-/**
- * xmlschema is a class that allows the user to quickly and easily
- * build a database on any ADOdb-supported platform using a simple
- * XML schema.
- *
- * Last Editor: $Author$
- * @author Richard Tango-Lowy & Dan Cech
- * @version $Revision$
- *
- * @package axmls
- * @tutorial getting_started.pkg
- */
-
-function _file_get_contents($file)
-{
- if (function_exists('file_get_contents')) return file_get_contents($file);
-
- $f = fopen($file,'r');
- if (!$f) return '';
- $t = '';
-
- while ($s = fread($f,100000)) $t .= $s;
- fclose($f);
- return $t;
-}
-
-
-/**
-* Debug on or off
-*/
-if( !defined( 'XMLS_DEBUG' ) ) {
- define( 'XMLS_DEBUG', FALSE );
-}
-
-/**
-* Default prefix key
-*/
-if( !defined( 'XMLS_PREFIX' ) ) {
- define( 'XMLS_PREFIX', '%%P' );
-}
-
-/**
-* Maximum length allowed for object prefix
-*/
-if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
- define( 'XMLS_PREFIX_MAXLEN', 10 );
-}
-
-/**
-* Execute SQL inline as it is generated
-*/
-if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
- define( 'XMLS_EXECUTE_INLINE', FALSE );
-}
-
-/**
-* Continue SQL Execution if an error occurs?
-*/
-if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
- define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
-}
-
-/**
-* Current Schema Version
-*/
-if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
- define( 'XMLS_SCHEMA_VERSION', '0.2' );
-}
-
-/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
- define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
-}
-
-/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
- define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
-}
-
-/**
-* Include the main ADODB library
-*/
-if( !defined( '_ADODB_LAYER' ) ) {
- require( 'adodb.inc.php' );
- require( 'adodb-datadict.inc.php' );
-}
-
-/**
-* Abstract DB Object. This class provides basic methods for database objects, such
-* as tables and indexes.
-*
-* @package axmls
-* @access private
-*/
-class dbObject {
-
- /**
- * var object Parent
- */
- var $parent;
-
- /**
- * var string current element
- */
- var $currentElement;
-
- /**
- * NOP
- */
- function dbObject( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
- }
-
- /**
- * XML Callback to process start elements
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
-
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
-
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
-
- }
-
- function create() {
- return array();
- }
-
- /**
- * Destroys the object
- */
- function destroy() {
- unset( $this );
- }
-
- /**
- * Checks whether the specified RDBMS is supported by the current
- * database object or its ranking ancestor.
- *
- * @param string $platform RDBMS platform name (from ADODB platform list).
- * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
- */
- function supportedPlatform( $platform = NULL ) {
- return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
- }
-
- /**
- * Returns the prefix set by the ranking ancestor of the database object.
- *
- * @param string $name Prefix string.
- * @return string Prefix.
- */
- function prefix( $name = '' ) {
- return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
- }
-
- /**
- * Extracts a field ID from the specified field.
- *
- * @param string $field Field.
- * @return string Field ID.
- */
- function FieldID( $field ) {
- return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
- }
-}
-
-/**
-* Creates a table object in ADOdb's datadict format
-*
-* This class stores information about a database table. As charactaristics
-* of the table are loaded from the external source, methods and properties
-* of this class are used to build up the table description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbTable extends dbObject {
-
- /**
- * @var string Table name
- */
- var $name;
-
- /**
- * @var array Field specifier: Meta-information about each field
- */
- var $fields = array();
-
- /**
- * @var array List of table indexes.
- */
- var $indexes = array();
-
- /**
- * @var array Table options: Table-level options
- */
- var $opts = array();
-
- /**
- * @var string Field index: Keeps track of which field is currently being processed
- */
- var $current_field;
-
- /**
- * @var boolean Mark table for destruction
- * @access private
- */
- var $drop_table;
-
- /**
- * @var boolean Mark field for destruction (not yet implemented)
- * @access private
- */
- var $drop_field = array();
-
- /**
- * Iniitializes a new table object.
- *
- * @param string $prefix DB Object prefix
- * @param array $attributes Array of table attributes.
- */
- function dbTable( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
- $this->name = $this->prefix($attributes['NAME']);
- }
-
- /**
- * XML Callback to process start elements. Elements currently
- * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'INDEX':
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- xml_set_object( $parser, $this->addIndex( $attributes ) );
- }
- break;
- case 'DATA':
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- xml_set_object( $parser, $this->addData( $attributes ) );
- }
- break;
- case 'DROP':
- $this->drop();
- break;
- case 'FIELD':
- // Add a field
- $fieldName = $attributes['NAME'];
- $fieldType = $attributes['TYPE'];
- $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;
- $fieldOpts = isset( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;
-
- $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
- break;
- case 'KEY':
- case 'NOTNULL':
- case 'AUTOINCREMENT':
- // Add a field option
- $this->addFieldOpt( $this->current_field, $this->currentElement );
- break;
- case 'DEFAULT':
- // Add a field option to the table object
-
- // Work around ADOdb datadict issue that misinterprets empty strings.
- if( $attributes['VALUE'] == '' ) {
- $attributes['VALUE'] = " '' ";
- }
-
- $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );
- break;
- case 'DEFDATE':
- case 'DEFTIMESTAMP':
- // Add a field option to the table object
- $this->addFieldOpt( $this->current_field, $this->currentElement );
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Table constraint
- case 'CONSTRAINT':
- if( isset( $this->current_field ) ) {
- $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
- } else {
- $this->addTableOpt( $cdata );
- }
- break;
- // Table option
- case 'OPT':
- $this->addTableOpt( $cdata );
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'TABLE':
- $this->parent->addSQL( $this->create( $this->parent ) );
- xml_set_object( $parser, $this->parent );
- $this->destroy();
- break;
- case 'FIELD':
- unset($this->current_field);
- break;
-
- }
- }
-
- /**
- * Adds an index to a table object
- *
- * @param array $attributes Index attributes
- * @return object dbIndex object
- */
- function &addIndex( $attributes ) {
- $name = strtoupper( $attributes['NAME'] );
- $this->indexes[$name] =& new dbIndex( $this, $attributes );
- return $this->indexes[$name];
- }
-
- /**
- * Adds data to a table object
- *
- * @param array $attributes Data attributes
- * @return object dbData object
- */
- function &addData( $attributes ) {
- if( !isset( $this->data ) ) {
- $this->data =& new dbData( $this, $attributes );
- }
- return $this->data;
- }
-
- /**
- * Adds a field to a table object
- *
- * $name is the name of the table to which the field should be added.
- * $type is an ADODB datadict field type. The following field types
- * are supported as of ADODB 3.40:
- * - C: varchar
- * - X: CLOB (character large object) or largest varchar size
- * if CLOB is not supported
- * - C2: Multibyte varchar
- * - X2: Multibyte CLOB
- * - B: BLOB (binary large object)
- * - D: Date (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
- *
- * @param string $name Name of the table to which the field will be added.
- * @param string $type ADODB datadict field type.
- * @param string $size Field size
- * @param array $opts Field options array
- * @return array Field specifier array
- */
- function addField( $name, $type, $size = NULL, $opts = NULL ) {
- $field_id = $this->FieldID( $name );
-
- // Set the field index so we know where we are
- $this->current_field = $field_id;
-
- // Set the field name (required)
- $this->fields[$field_id]['NAME'] = $name;
-
- // Set the field type (required)
- $this->fields[$field_id]['TYPE'] = $type;
-
- // Set the field size (optional)
- if( isset( $size ) ) {
- $this->fields[$field_id]['SIZE'] = $size;
- }
-
- // Set the field options
- if( isset( $opts ) ) {
- $this->fields[$field_id]['OPTS'][] = $opts;
- }
- }
-
- /**
- * Adds a field option to the current field specifier
- *
- * This method adds a field option allowed by the ADOdb datadict
- * and appends it to the given field.
- *
- * @param string $field Field name
- * @param string $opt ADOdb field option
- * @param mixed $value Field option value
- * @return array Field specifier array
- */
- function addFieldOpt( $field, $opt, $value = NULL ) {
- if( !isset( $value ) ) {
- $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
- // Add the option and value
- } else {
- $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );
- }
- }
-
- /**
- * Adds an option to the table
- *
- * This method takes a comma-separated list of table-level options
- * and appends them to the table object.
- *
- * @param string $opt Table option
- * @return array Options
- */
- function addTableOpt( $opt ) {
- $this->opts[] = $opt;
-
- return $this->opts;
- }
-
- /**
- * Generates the SQL that will create the table in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing table creation SQL
- */
- function create( &$xmls ) {
- $sql = array();
-
- // drop any existing indexes
- if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
- foreach( $legacy_indexes as $index => $index_details ) {
- $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
- }
- }
-
- // remove fields to be dropped from table object
- foreach( $this->drop_field as $field ) {
- unset( $this->fields[$field] );
- }
-
- // if table exists
- if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
- // drop table
- if( $this->drop_table ) {
- $sql[] = $xmls->dict->DropTableSQL( $this->name );
-
- return $sql;
- }
-
- // drop any existing fields not in schema
- foreach( $legacy_fields as $field_id => $field ) {
- if( !isset( $this->fields[$field_id] ) ) {
- $sql[] = $xmls->dict->DropColumnSQL( $this->name, '`'.$field->name.'`' );
- }
- }
- // if table doesn't exist
- } else {
- if( $this->drop_table ) {
- return $sql;
- }
-
- $legacy_fields = array();
- }
-
- // Loop through the field specifier array, building the associative array for the field options
- $fldarray = array();
-
- foreach( $this->fields as $field_id => $finfo ) {
- // Set an empty size if it isn't supplied
- if( !isset( $finfo['SIZE'] ) ) {
- $finfo['SIZE'] = '';
- }
-
- // Initialize the field array with the type and size
- $fldarray[$field_id] = array(
- 'NAME' => $finfo['NAME'],
- 'TYPE' => $finfo['TYPE'],
- 'SIZE' => $finfo['SIZE']
- );
-
- // Loop through the options array and add the field options.
- if( isset( $finfo['OPTS'] ) ) {
- foreach( $finfo['OPTS'] as $opt ) {
- // Option has an argument.
- if( is_array( $opt ) ) {
- $key = key( $opt );
- $value = $opt[key( $opt )];
- @$fldarray[$field_id][$key] .= $value;
- // Option doesn't have arguments
- } else {
- $fldarray[$field_id][$opt] = $opt;
- }
- }
- }
- }
-
- if( empty( $legacy_fields ) ) {
- // Create the new table
- $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
- logMsg( end( $sql ), 'Generated CreateTableSQL' );
- } else {
- // Upgrade an existing table
- logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
- switch( $xmls->upgrade ) {
- // Use ChangeTableSQL
- case 'ALTER':
- logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
- $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
- break;
- case 'REPLACE':
- logMsg( 'Doing upgrade REPLACE (testing)' );
- $sql[] = $xmls->dict->DropTableSQL( $this->name );
- $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
- break;
- // ignore table
- default:
- return array();
- }
- }
-
- foreach( $this->indexes as $index ) {
- $sql[] = $index->create( $xmls );
- }
-
- if( isset( $this->data ) ) {
- $sql[] = $this->data->create( $xmls );
- }
-
- return $sql;
- }
-
- /**
- * Marks a field or table for destruction
- */
- function drop() {
- if( isset( $this->current_field ) ) {
- // Drop the current field
- logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );
- // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );
- $this->drop_field[$this->current_field] = $this->current_field;
- } else {
- // Drop the current table
- logMsg( "Dropping table '{$this->name}'" );
- // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );
- $this->drop_table = TRUE;
- }
- }
-}
-
-/**
-* Creates an index object in ADOdb's datadict format
-*
-* This class stores information about a database index. As charactaristics
-* of the index are loaded from the external source, methods and properties
-* of this class are used to build up the index description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbIndex extends dbObject {
-
- /**
- * @var string Index name
- */
- var $name;
-
- /**
- * @var array Index options: Index-level options
- */
- var $opts = array();
-
- /**
- * @var array Indexed fields: Table columns included in this index
- */
- var $columns = array();
-
- /**
- * @var boolean Mark index for destruction
- * @access private
- */
- var $drop = FALSE;
-
- /**
- * Initializes the new dbIndex object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function dbIndex( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
-
- $this->name = $this->prefix ($attributes['NAME']);
- }
-
- /**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'DROP':
- $this->drop();
- break;
- case 'CLUSTERED':
- case 'BITMAP':
- case 'UNIQUE':
- case 'FULLTEXT':
- case 'HASH':
- // Add index Option
- $this->addIndexOpt( $this->currentElement );
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Index field name
- case 'COL':
- $this->addField( $cdata );
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'INDEX':
- xml_set_object( $parser, $this->parent );
- break;
- }
- }
-
- /**
- * Adds a field to the index
- *
- * @param string $name Field name
- * @return string Field list
- */
- function addField( $name ) {
- $this->columns[$this->FieldID( $name )] = $name;
-
- // Return the field list
- return $this->columns;
- }
-
- /**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
- function addIndexOpt( $opt ) {
- $this->opts[] = $opt;
-
- // Return the options list
- return $this->opts;
- }
-
- /**
- * Generates the SQL that will create the index in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
- function create( &$xmls ) {
- if( $this->drop ) {
- return NULL;
- }
-
- // eliminate any columns that aren't in the table
- foreach( $this->columns as $id => $col ) {
- if( !isset( $this->parent->fields[$id] ) ) {
- unset( $this->columns[$id] );
- }
- }
-
- return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
- }
-
- /**
- * Marks an index for destruction
- */
- function drop() {
- $this->drop = TRUE;
- }
-}
-
-/**
-* Creates a data object in ADOdb's datadict format
-*
-* This class stores information about table data.
-*
-* @package axmls
-* @access private
-*/
-class dbData extends dbObject {
-
- var $data = array();
-
- var $row;
-
- /**
- * Initializes the new dbIndex object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function dbData( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
- }
-
- /**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'ROW':
- $this->row = count( $this->data );
- $this->data[$this->row] = array();
- break;
- case 'F':
- $this->addField($attributes);
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Index field name
- case 'F':
- $this->addData( $cdata );
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'DATA':
- xml_set_object( $parser, $this->parent );
- break;
- }
- }
-
- /**
- * Adds a field to the index
- *
- * @param string $name Field name
- * @return string Field list
- */
- function addField( $attributes ) {
- if( isset( $attributes['NAME'] ) ) {
- $name = $attributes['NAME'];
- } else {
- $name = count($this->data[$this->row]);
- }
-
- // Set the field index so we know where we are
- $this->current_field = $this->FieldID( $name );
- }
-
- /**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
- function addData( $cdata ) {
- if( !isset( $this->data[$this->row] ) ) {
- $this->data[$this->row] = array();
- }
-
- if( !isset( $this->data[$this->row][$this->current_field] ) ) {
- $this->data[$this->row][$this->current_field] = '';
- }
-
- $this->data[$this->row][$this->current_field] .= $cdata;
- }
-
- /**
- * Generates the SQL that will create the index in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
- function create( &$xmls ) {
- $table = $xmls->dict->TableName($this->parent->name);
- $table_field_count = count($this->parent->fields);
- $sql = array();
-
- // eliminate any columns that aren't in the table
- foreach( $this->data as $row ) {
- $table_fields = $this->parent->fields;
- $fields = array();
-
- foreach( $row as $field_id => $field_data ) {
- if( !array_key_exists( $field_id, $table_fields ) ) {
- if( is_numeric( $field_id ) ) {
- $field_id = reset( array_keys( $table_fields ) );
- } else {
- continue;
- }
- }
-
- $name = $table_fields[$field_id]['NAME'];
-
- switch( $table_fields[$field_id]['TYPE'] ) {
- case 'C':
- case 'C2':
- case 'X':
- case 'X2':
- $fields[$name] = $xmls->db->qstr( $field_data );
- break;
- case 'I':
- case 'I1':
- case 'I2':
- case 'I4':
- case 'I8':
- $fields[$name] = intval($field_data);
- break;
- default:
- $fields[$name] = $field_data;
- }
-
- unset($table_fields[$field_id]);
- }
-
- // check that at least 1 column is specified
- if( empty( $fields ) ) {
- continue;
- }
-
- // check that no required columns are missing
- if( count( $fields ) < $table_field_count ) {
- foreach( $table_fields as $field ) {
- if (isset( $field['OPTS'] ))
- if( ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {
- continue(2);
- }
- }
- }
-
- $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
- }
-
- return $sql;
- }
-}
-
-/**
-* Creates the SQL to execute a list of provided SQL queries
-*
-* @package axmls
-* @access private
-*/
-class dbQuerySet extends dbObject {
-
- /**
- * @var array List of SQL queries
- */
- var $queries = array();
-
- /**
- * @var string String used to build of a query line by line
- */
- var $query;
-
- /**
- * @var string Query prefix key
- */
- var $prefixKey = '';
-
- /**
- * @var boolean Auto prefix enable (TRUE)
- */
- var $prefixMethod = 'AUTO';
-
- /**
- * Initializes the query set.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- */
- function dbQuerySet( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
-
- // Overrides the manual prefix key
- if( isset( $attributes['KEY'] ) ) {
- $this->prefixKey = $attributes['KEY'];
- }
-
- $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';
-
- // Enables or disables automatic prefix prepending
- switch( $prefixMethod ) {
- case 'AUTO':
- $this->prefixMethod = 'AUTO';
- break;
- case 'MANUAL':
- $this->prefixMethod = 'MANUAL';
- break;
- case 'NONE':
- $this->prefixMethod = 'NONE';
- break;
- }
- }
-
- /**
- * XML Callback to process start elements. Elements currently
- * processed are: QUERY.
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'QUERY':
- // Create a new query in a SQL queryset.
- // Ignore this query set if a platform is specified and it's different than the
- // current connection platform.
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- $this->newQuery();
- } else {
- $this->discardQuery();
- }
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Line of queryset SQL data
- case 'QUERY':
- $this->buildQuery( $cdata );
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'QUERY':
- // Add the finished query to the open query set.
- $this->addQuery();
- break;
- case 'SQL':
- $this->parent->addSQL( $this->create( $this->parent ) );
- xml_set_object( $parser, $this->parent );
- $this->destroy();
- break;
- default:
-
- }
- }
-
- /**
- * Re-initializes the query.
- *
- * @return boolean TRUE
- */
- function newQuery() {
- $this->query = '';
-
- return TRUE;
- }
-
- /**
- * Discards the existing query.
- *
- * @return boolean TRUE
- */
- function discardQuery() {
- unset( $this->query );
-
- return TRUE;
- }
-
- /**
- * Appends a line to a query that is being built line by line
- *
- * @param string $data Line of SQL data or NULL to initialize a new query
- * @return string SQL query string.
- */
- function buildQuery( $sql = NULL ) {
- if( !isset( $this->query ) OR empty( $sql ) ) {
- return FALSE;
- }
-
- $this->query .= $sql;
-
- return $this->query;
- }
-
- /**
- * Adds a completed query to the query list
- *
- * @return string SQL of added query
- */
- function addQuery() {
- if( !isset( $this->query ) ) {
- return FALSE;
- }
-
- $this->queries[] = $return = trim($this->query);
-
- unset( $this->query );
-
- return $return;
- }
-
- /**
- * Creates and returns the current query set
- *
- * @param object $xmls adoSchema object
- * @return array Query set
- */
- function create( &$xmls ) {
- foreach( $this->queries as $id => $query ) {
- switch( $this->prefixMethod ) {
- case 'AUTO':
- // Enable auto prefix replacement
-
- // Process object prefix.
- // Evaluate SQL statements to prepend prefix to objects
- $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
- $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
- $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-
- // SELECT statements aren't working yet
- #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
-
- case 'MANUAL':
- // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
- // If prefixKey is not set, we use the default constant XMLS_PREFIX
- if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
- // Enable prefix override
- $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
- } else {
- // Use default replacement
- $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
- }
- }
-
- $this->queries[$id] = trim( $query );
- }
-
- // Return the query set array
- return $this->queries;
- }
-
- /**
- * Rebuilds the query with the prefix attached to any objects
- *
- * @param string $regex Regex used to add prefix
- * @param string $query SQL query string
- * @param string $prefix Prefix to be appended to tables, indices, etc.
- * @return string Prefixed SQL query string.
- */
- function prefixQuery( $regex, $query, $prefix = NULL ) {
- if( !isset( $prefix ) ) {
- return $query;
- }
-
- if( preg_match( $regex, $query, $match ) ) {
- $preamble = $match[1];
- $postamble = $match[5];
- $objectList = explode( ',', $match[3] );
- // $prefix = $prefix . '_';
-
- $prefixedList = '';
-
- foreach( $objectList as $object ) {
- if( $prefixedList !== '' ) {
- $prefixedList .= ', ';
- }
-
- $prefixedList .= $prefix . trim( $object );
- }
-
- $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
- }
-
- return $query;
- }
-}
-
-/**
-* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
-*
-* This class is used to load and parse the XML file, to create an array of SQL statements
-* that can be used to build a database, and to build the database using the SQL array.
-*
-* @tutorial getting_started.pkg
-*
-* @author Richard Tango-Lowy & Dan Cech
-* @version $Revision$
-*
-* @package axmls
-*/
-class adoSchema {
-
- /**
- * @var array Array containing SQL queries to generate all objects
- * @access private
- */
- var $sqlArray;
-
- /**
- * @var object ADOdb connection object
- * @access private
- */
- var $db;
-
- /**
- * @var object ADOdb Data Dictionary
- * @access private
- */
- var $dict;
-
- /**
- * @var string Current XML element
- * @access private
- */
- var $currentElement = '';
-
- /**
- * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
- * @access private
- */
- var $upgrade = '';
-
- /**
- * @var string Optional object prefix
- * @access private
- */
- var $objectPrefix = '';
-
- /**
- * @var long Original Magic Quotes Runtime value
- * @access private
- */
- var $mgq;
-
- /**
- * @var long System debug
- * @access private
- */
- var $debug;
-
- /**
- * @var string Regular expression to find schema version
- * @access private
- */
- var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
-
- /**
- * @var string Current schema version
- * @access private
- */
- var $schemaVersion;
-
- /**
- * @var int Success of last Schema execution
- */
- var $success;
-
- /**
- * @var bool Execute SQL inline as it is generated
- */
- var $executeInline;
-
- /**
- * @var bool Continue SQL execution if errors occur
- */
- var $continueOnError;
-
- /**
- * Creates an adoSchema object
- *
- * Creating an adoSchema object is the first step in processing an XML schema.
- * The only parameter is an ADOdb database connection object, which must already
- * have been created.
- *
- * @param object $db ADOdb database connection object.
- */
- function adoSchema( &$db ) {
- // Initialize the environment
- $this->mgq = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
-
- $this->db =& $db;
- $this->debug = $this->db->debug;
- $this->dict = NewDataDictionary( $this->db );
- $this->sqlArray = array();
- $this->schemaVersion = XMLS_SCHEMA_VERSION;
- $this->executeInline( XMLS_EXECUTE_INLINE );
- $this->continueOnError( XMLS_CONTINUE_ON_ERROR );
- $this->setUpgradeMethod();
- }
-
- /**
- * Sets the method to be used for upgrading an existing database
- *
- * Use this method to specify how existing database objects should be upgraded.
- * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
- * alter each database object directly, REPLACE attempts to rebuild each object
- * from scratch, BEST attempts to determine the best upgrade method for each
- * object, and NONE disables upgrading.
- *
- * This method is not yet used by AXMLS, but exists for backward compatibility.
- * The ALTER method is automatically assumed when the adoSchema object is
- * instantiated; other upgrade methods are not currently supported.
- *
- * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
- * @returns string Upgrade method used
- */
- function SetUpgradeMethod( $method = '' ) {
- if( !is_string( $method ) ) {
- return FALSE;
- }
-
- $method = strtoupper( $method );
-
- // Handle the upgrade methods
- switch( $method ) {
- case 'ALTER':
- $this->upgrade = $method;
- break;
- case 'REPLACE':
- $this->upgrade = $method;
- break;
- case 'BEST':
- $this->upgrade = 'ALTER';
- break;
- case 'NONE':
- $this->upgrade = 'NONE';
- break;
- default:
- // Use default if no legitimate method is passed.
- $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
- }
-
- return $this->upgrade;
- }
-
- /**
- * Enables/disables inline SQL execution.
- *
- * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
- * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
- * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
- * to apply the schema to the database.
- *
- * @param bool $mode execute
- * @return bool current execution mode
- *
- * @see ParseSchema(), ExecuteSchema()
- */
- function ExecuteInline( $mode = NULL ) {
- if( is_bool( $mode ) ) {
- $this->executeInline = $mode;
- }
-
- return $this->executeInline;
- }
-
- /**
- * Enables/disables SQL continue on error.
- *
- * Call this method to enable or disable continuation of SQL execution if an error occurs.
- * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
- * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
- * of the schema will continue.
- *
- * @param bool $mode execute
- * @return bool current continueOnError mode
- *
- * @see addSQL(), ExecuteSchema()
- */
- function ContinueOnError( $mode = NULL ) {
- if( is_bool( $mode ) ) {
- $this->continueOnError = $mode;
- }
-
- return $this->continueOnError;
- }
-
- /**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to create the database described.
- * @see ParseSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
- function ParseSchema( $filename, $returnSchema = FALSE ) {
- return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
- }
-
- /**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema from a file (see the DTD for the proper format)
- * and generate the SQL necessary to create the database described by the schema.
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- *
- * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
- * @see ParseSchema(), ParseSchemaString()
- */
- function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
- // Open the file
- if( !($fp = fopen( $filename, 'r' )) ) {
- // die( 'Unable to open file' );
- return FALSE;
- }
-
- // do version detection here
- if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
- return FALSE;
- }
-
- if ( $returnSchema )
- {
- $xmlstring = '';
- while( $data = fread( $fp, 100000 ) ) {
- $xmlstring .= $data;
- }
- return $xmlstring;
- }
-
- $this->success = 2;
-
- $xmlParser = $this->create_parser();
-
- // Process the file
- while( $data = fread( $fp, 4096 ) ) {
- if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
- die( sprintf(
- "XML error: %s at line %d",
- xml_error_string( xml_get_error_code( $xmlParser) ),
- xml_get_current_line_number( $xmlParser)
- ) );
- }
- }
-
- xml_parser_free( $xmlParser );
-
- return $this->sqlArray;
- }
-
- /**
- * Converts an XML schema string to SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to create the database described by the schema.
- * @see ParseSchema()
- *
- * @param string $xmlstring XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
- function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
- if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
- return FALSE;
- }
-
- // do version detection here
- if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
- return FALSE;
- }
-
- if ( $returnSchema )
- {
- return $xmlstring;
- }
-
- $this->success = 2;
-
- $xmlParser = $this->create_parser();
-
- if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
- die( sprintf(
- "XML error: %s at line %d",
- xml_error_string( xml_get_error_code( $xmlParser) ),
- xml_get_current_line_number( $xmlParser)
- ) );
- }
-
- xml_parser_free( $xmlParser );
-
- return $this->sqlArray;
- }
-
- /**
- * Loads an XML schema from a file and converts it to uninstallation SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to remove the database described.
- * @see RemoveSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
- function RemoveSchema( $filename, $returnSchema = FALSE ) {
- return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
- }
-
- /**
- * Converts an XML schema string to uninstallation SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to uninstall the database described by the schema.
- * @see RemoveSchema()
- *
- * @param string $schema XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
- function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
-
- // grab current version
- if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
- return FALSE;
- }
-
- return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
- }
-
- /**
- * Applies the current XML schema to the database (post execution).
- *
- * Call this method to apply the current schema (generally created by calling
- * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
- * and executing other SQL specified in the schema) after parsing.
- * @see ParseSchema(), ParseSchemaString(), ExecuteInline()
- *
- * @param array $sqlArray Array of SQL statements that will be applied rather than
- * the current schema.
- * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
- * @returns integer 0 if failure, 1 if errors, 2 if successful.
- */
- function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
- if( !is_bool( $continueOnErr ) ) {
- $continueOnErr = $this->ContinueOnError();
- }
-
- if( !isset( $sqlArray ) ) {
- $sqlArray = $this->sqlArray;
- }
-
- if( !is_array( $sqlArray ) ) {
- $this->success = 0;
- } else {
- $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
- }
-
- return $this->success;
- }
-
- /**
- * Returns the current SQL array.
- *
- * Call this method to fetch the array of SQL queries resulting from
- * ParseSchema() or ParseSchemaString().
- *
- * @param string $format Format: HTML, TEXT, or NONE (PHP array)
- * @return array Array of SQL statements or FALSE if an error occurs
- */
- function PrintSQL( $format = 'NONE' ) {
- $sqlArray = null;
- return $this->getSQL( $format, $sqlArray );
- }
-
- /**
- * Saves the current SQL array to the local filesystem as a list of SQL queries.
- *
- * Call this method to save the array of SQL queries (generally resulting from a
- * parsed XML schema) to the filesystem.
- *
- * @param string $filename Path and name where the file should be saved.
- * @return boolean TRUE if save is successful, else FALSE.
- */
- function SaveSQL( $filename = './schema.sql' ) {
-
- if( !isset( $sqlArray ) ) {
- $sqlArray = $this->sqlArray;
- }
- if( !isset( $sqlArray ) ) {
- return FALSE;
- }
-
- $fp = fopen( $filename, "w" );
-
- foreach( $sqlArray as $key => $query ) {
- fwrite( $fp, $query . ";\n" );
- }
- fclose( $fp );
- }
-
- /**
- * Create an xml parser
- *
- * @return object PHP XML parser object
- *
- * @access private
- */
- function &create_parser() {
- // Create the parser
- $xmlParser = xml_parser_create();
- xml_set_object( $xmlParser, $this );
-
- // Initialize the XML callback functions
- xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
- xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
-
- return $xmlParser;
- }
-
- /**
- * XML Callback to process start elements
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- switch( strtoupper( $tag ) ) {
- case 'TABLE':
- $this->obj = new dbTable( $this, $attributes );
- xml_set_object( $parser, $this->obj );
- break;
- case 'SQL':
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- $this->obj = new dbQuerySet( $this, $attributes );
- xml_set_object( $parser, $this->obj );
- }
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
-
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- * @internal
- */
- function _tag_close( &$parser, $tag ) {
-
- }
-
- /**
- * Converts an XML schema string to the specified DTD version.
- *
- * Call this method to convert a string containing an XML schema to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see ConvertSchemaFile()
- *
- * @param string $schema String containing XML schema that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
- function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
-
- // grab current version
- if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
- return FALSE;
- }
-
- if( !isset ($newVersion) ) {
- $newVersion = $this->schemaVersion;
- }
-
- if( $version == $newVersion ) {
- $result = $schema;
- } else {
- $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
- }
-
- if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
- fwrite( $fp, $result );
- fclose( $fp );
- }
-
- return $result;
- }
-
- // compat for pre-4.3 - jlim
- function _file_get_contents($path)
- {
- if (function_exists('file_get_contents')) return file_get_contents($path);
- return join('',file($path));
- }
-
- /**
- * Converts an XML schema file to the specified DTD version.
- *
- * Call this method to convert the specified XML schema file to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see ConvertSchemaString()
- *
- * @param string $filename Name of XML schema file that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
- function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
-
- // grab current version
- if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
- return FALSE;
- }
-
- if( !isset ($newVersion) ) {
- $newVersion = $this->schemaVersion;
- }
-
- if( $version == $newVersion ) {
- $result = _file_get_contents( $filename );
-
- // remove unicode BOM if present
- if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
- $result = substr( $result, 3 );
- }
- } else {
- $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
- }
-
- if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
- fwrite( $fp, $result );
- fclose( $fp );
- }
-
- return $result;
- }
-
- function TransformSchema( $schema, $xsl, $schematype='string' )
- {
- // Fail if XSLT extension is not available
- if( ! function_exists( 'xslt_create' ) ) {
- return FALSE;
- }
-
- $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
-
- // look for xsl
- if( !is_readable( $xsl_file ) ) {
- return FALSE;
- }
-
- switch( $schematype )
- {
- case 'file':
- if( !is_readable( $schema ) ) {
- return FALSE;
- }
-
- $schema = _file_get_contents( $schema );
- break;
- case 'string':
- default:
- if( !is_string( $schema ) ) {
- return FALSE;
- }
- }
-
- $arguments = array (
- '/_xml' => $schema,
- '/_xsl' => _file_get_contents( $xsl_file )
- );
-
- // create an XSLT processor
- $xh = xslt_create ();
-
- // set error handler
- xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
-
- // process the schema
- $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
-
- xslt_free ($xh);
-
- return $result;
- }
-
- /**
- * Processes XSLT transformation errors
- *
- * @param object $parser XML parser object
- * @param integer $errno Error number
- * @param integer $level Error level
- * @param array $fields Error information fields
- *
- * @access private
- */
- function xslt_error_handler( $parser, $errno, $level, $fields ) {
- if( is_array( $fields ) ) {
- $msg = array(
- 'Message Type' => ucfirst( $fields['msgtype'] ),
- 'Message Code' => $fields['code'],
- 'Message' => $fields['msg'],
- 'Error Number' => $errno,
- 'Level' => $level
- );
-
- switch( $fields['URI'] ) {
- case 'arg:/_xml':
- $msg['Input'] = 'XML';
- break;
- case 'arg:/_xsl':
- $msg['Input'] = 'XSL';
- break;
- default:
- $msg['Input'] = $fields['URI'];
- }
-
- $msg['Line'] = $fields['line'];
- } else {
- $msg = array(
- 'Message Type' => 'Error',
- 'Error Number' => $errno,
- 'Level' => $level,
- 'Fields' => var_export( $fields, TRUE )
- );
- }
-
- $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
- . '<table>' . "\n";
-
- foreach( $msg as $label => $details ) {
- $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
- }
-
- $error_details .= '</table>';
-
- trigger_error( $error_details, E_USER_ERROR );
- }
-
- /**
- * Returns the AXMLS Schema Version of the requested XML schema file.
- *
- * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
- * @see SchemaStringVersion()
- *
- * @param string $filename AXMLS schema file
- * @return string Schema version number or FALSE on error
- */
- function SchemaFileVersion( $filename ) {
- // Open the file
- if( !($fp = fopen( $filename, 'r' )) ) {
- // die( 'Unable to open file' );
- return FALSE;
- }
-
- // Process the file
- while( $data = fread( $fp, 4096 ) ) {
- if( preg_match( $this->versionRegex, $data, $matches ) ) {
- return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
- }
- }
-
- return FALSE;
- }
-
- /**
- * Returns the AXMLS Schema Version of the provided XML schema string.
- *
- * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
- * @see SchemaFileVersion()
- *
- * @param string $xmlstring XML schema string
- * @return string Schema version number or FALSE on error
- */
- function SchemaStringVersion( $xmlstring ) {
- if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
- return FALSE;
- }
-
- if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
- return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
- }
-
- return FALSE;
- }
-
- /**
- * Extracts an XML schema from an existing database.
- *
- * Call this method to create an XML schema string from an existing database.
- * If the data parameter is set to TRUE, AXMLS will include the data from the database
- * in the schema.
- *
- * @param boolean $data Include data in schema dump
- * @return string Generated XML schema
- */
- function ExtractSchema( $data = FALSE ) {
- $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
-
- $schema = '<?xml version="1.0"?>' . "\n"
- . '<schema version="' . $this->schemaVersion . '">' . "\n";
-
- if( is_array( $tables = $this->db->MetaTables( 'TABLES' ) ) ) {
- foreach( $tables as $table ) {
- $schema .= ' <table name="' . $table . '">' . "\n";
-
- // grab details from database
- $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' );
- $fields = $this->db->MetaColumns( $table );
- $indexes = $this->db->MetaIndexes( $table );
-
- if( is_array( $fields ) ) {
- foreach( $fields as $details ) {
- $extra = '';
- $content = array();
-
- if( $details->max_length > 0 ) {
- $extra .= ' size="' . $details->max_length . '"';
- }
-
- if( $details->primary_key ) {
- $content[] = '<KEY/>';
- } elseif( $details->not_null ) {
- $content[] = '<NOTNULL/>';
- }
-
- if( $details->has_default ) {
- $content[] = '<DEFAULT value="' . $details->default_value . '"/>';
- }
-
- if( $details->auto_increment ) {
- $content[] = '<AUTOINCREMENT/>';
- }
-
- // this stops the creation of 'R' columns,
- // AUTOINCREMENT is used to create auto columns
- $details->primary_key = 0;
- $type = $rs->MetaType( $details );
-
- $schema .= ' <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>';
-
- if( !empty( $content ) ) {
- $schema .= "\n " . implode( "\n ", $content ) . "\n ";
- }
-
- $schema .= '</field>' . "\n";
- }
- }
-
- if( is_array( $indexes ) ) {
- foreach( $indexes as $index => $details ) {
- $schema .= ' <index name="' . $index . '">' . "\n";
-
- if( $details['unique'] ) {
- $schema .= ' <UNIQUE/>' . "\n";
- }
-
- foreach( $details['columns'] as $column ) {
- $schema .= ' <col>' . $column . '</col>' . "\n";
- }
-
- $schema .= ' </index>' . "\n";
- }
- }
-
- if( $data ) {
- $rs = $this->db->Execute( 'SELECT * FROM ' . $table );
-
- if( is_object( $rs ) ) {
- $schema .= ' <data>' . "\n";
-
- while( $row = $rs->FetchRow() ) {
- foreach( $row as $key => $val ) {
- $row[$key] = htmlentities($val);
- }
-
- $schema .= ' <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";
- }
-
- $schema .= ' </data>' . "\n";
- }
- }
-
- $schema .= ' </table>' . "\n";
- }
- }
-
- $this->db->SetFetchMode( $old_mode );
-
- $schema .= '</schema>';
- return $schema;
- }
-
- /**
- * Sets a prefix for database objects
- *
- * Call this method to set a standard prefix that will be prepended to all database tables
- * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
- *
- * @param string $prefix Prefix that will be prepended.
- * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
- * @return boolean TRUE if successful, else FALSE
- */
- function SetPrefix( $prefix = '', $underscore = TRUE ) {
- switch( TRUE ) {
- // clear prefix
- case empty( $prefix ):
- logMsg( 'Cleared prefix' );
- $this->objectPrefix = '';
- return TRUE;
- // prefix too long
- case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
- // prefix contains invalid characters
- case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
- logMsg( 'Invalid prefix: ' . $prefix );
- return FALSE;
- }
-
- if( $underscore AND substr( $prefix, -1 ) != '_' ) {
- $prefix .= '_';
- }
-
- // prefix valid
- logMsg( 'Set prefix: ' . $prefix );
- $this->objectPrefix = $prefix;
- return TRUE;
- }
-
- /**
- * Returns an object name with the current prefix prepended.
- *
- * @param string $name Name
- * @return string Prefixed name
- *
- * @access private
- */
- function prefix( $name = '' ) {
- // if prefix is set
- if( !empty( $this->objectPrefix ) ) {
- // Prepend the object prefix to the table name
- // prepend after quote if used
- return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
- }
-
- // No prefix set. Use name provided.
- return $name;
- }
-
- /**
- * Checks if element references a specific platform
- *
- * @param string $platform Requested platform
- * @returns boolean TRUE if platform check succeeds
- *
- * @access private
- */
- function supportedPlatform( $platform = NULL ) {
- $regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';
-
- if( !isset( $platform ) OR preg_match( $regex, $platform ) ) {
- logMsg( "Platform $platform is supported" );
- return TRUE;
- } else {
- logMsg( "Platform $platform is NOT supported" );
- return FALSE;
- }
- }
-
- /**
- * Clears the array of generated SQL.
- *
- * @access private
- */
- function clearSQL() {
- $this->sqlArray = array();
- }
-
- /**
- * Adds SQL into the SQL array.
- *
- * @param mixed $sql SQL to Add
- * @return boolean TRUE if successful, else FALSE.
- *
- * @access private
- */
- function addSQL( $sql = NULL ) {
- if( is_array( $sql ) ) {
- foreach( $sql as $line ) {
- $this->addSQL( $line );
- }
-
- return TRUE;
- }
-
- if( is_string( $sql ) ) {
- $this->sqlArray[] = $sql;
-
- // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
- if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
- $saved = $this->db->debug;
- $this->db->debug = $this->debug;
- $ok = $this->db->Execute( $sql );
- $this->db->debug = $saved;
-
- if( !$ok ) {
- if( $this->debug ) {
- ADOConnection::outp( $this->db->ErrorMsg() );
- }
-
- $this->success = 1;
- }
- }
-
- return TRUE;
- }
-
- return FALSE;
- }
-
- /**
- * Gets the SQL array in the specified format.
- *
- * @param string $format Format
- * @return mixed SQL
- *
- * @access private
- */
- function getSQL( $format = NULL, $sqlArray = NULL ) {
- if( !is_array( $sqlArray ) ) {
- $sqlArray = $this->sqlArray;
- }
-
- if( !is_array( $sqlArray ) ) {
- return FALSE;
- }
-
- switch( strtolower( $format ) ) {
- case 'string':
- case 'text':
- return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
- case'html':
- return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
- }
-
- return $this->sqlArray;
- }
-
- /**
- * Destroys an adoSchema object.
- *
- * Call this method to clean up after an adoSchema object that is no longer in use.
- * @deprecated adoSchema now cleans up automatically.
- */
- function Destroy() {
- set_magic_quotes_runtime( $this->mgq );
- unset( $this );
- }
-}
-
-/**
-* Message logging function
-*
-* @access private
-*/
-function logMsg( $msg, $title = NULL, $force = FALSE ) {
- if( XMLS_DEBUG or $force ) {
- echo '<pre>';
-
- if( isset( $title ) ) {
- echo '<h3>' . htmlentities( $title ) . '</h3>';
- }
-
- if( is_object( $this ) ) {
- echo '[' . get_class( $this ) . '] ';
- }
-
- print_r( $msg );
-
- echo '</pre>';
- }
-}
+<?php\r
+// Copyright (c) 2004 ars Cognita Inc., all rights reserved\r
+/* ******************************************************************************\r
+ Released under both BSD license and Lesser GPL library license. \r
+ Whenever there is any discrepancy between the two licenses, \r
+ the BSD license will take precedence. \r
+*******************************************************************************/\r
+/**\r
+ * xmlschema is a class that allows the user to quickly and easily\r
+ * build a database on any ADOdb-supported platform using a simple\r
+ * XML schema.\r
+ *\r
+ * Last Editor: $Author$\r
+ * @author Richard Tango-Lowy & Dan Cech\r
+ * @version $Revision$\r
+ *\r
+ * @package axmls\r
+ * @tutorial getting_started.pkg\r
+ */\r
+ \r
+function _file_get_contents($file) \r
+{\r
+ if (function_exists('file_get_contents')) return file_get_contents($file);\r
+ \r
+ $f = fopen($file,'r');\r
+ if (!$f) return '';\r
+ $t = '';\r
+ \r
+ while ($s = fread($f,100000)) $t .= $s;\r
+ fclose($f);\r
+ return $t;\r
+}\r
+\r
+\r
+/**\r
+* Debug on or off\r
+*/\r
+if( !defined( 'XMLS_DEBUG' ) ) {\r
+ define( 'XMLS_DEBUG', FALSE );\r
+}\r
+\r
+/**\r
+* Default prefix key\r
+*/\r
+if( !defined( 'XMLS_PREFIX' ) ) {\r
+ define( 'XMLS_PREFIX', '%%P' );\r
+}\r
+\r
+/**\r
+* Maximum length allowed for object prefix\r
+*/\r
+if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {\r
+ define( 'XMLS_PREFIX_MAXLEN', 10 );\r
+}\r
+\r
+/**\r
+* Execute SQL inline as it is generated\r
+*/\r
+if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {\r
+ define( 'XMLS_EXECUTE_INLINE', FALSE );\r
+}\r
+\r
+/**\r
+* Continue SQL Execution if an error occurs?\r
+*/\r
+if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {\r
+ define( 'XMLS_CONTINUE_ON_ERROR', FALSE );\r
+}\r
+\r
+/**\r
+* Current Schema Version\r
+*/\r
+if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {\r
+ define( 'XMLS_SCHEMA_VERSION', '0.2' );\r
+}\r
+\r
+/**\r
+* Default Schema Version. Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {\r
+ define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );\r
+}\r
+\r
+/**\r
+* Default Schema Version. Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {\r
+ define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );\r
+}\r
+\r
+/**\r
+* Include the main ADODB library\r
+*/\r
+if( !defined( '_ADODB_LAYER' ) ) {\r
+ require( 'adodb.inc.php' );\r
+ require( 'adodb-datadict.inc.php' );\r
+}\r
+\r
+/**\r
+* Abstract DB Object. This class provides basic methods for database objects, such\r
+* as tables and indexes.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbObject {\r
+ \r
+ /**\r
+ * var object Parent\r
+ */\r
+ var $parent;\r
+ \r
+ /**\r
+ * var string current element\r
+ */\r
+ var $currentElement;\r
+ \r
+ /**\r
+ * NOP\r
+ */\r
+ function dbObject( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ \r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ \r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ \r
+ }\r
+ \r
+ function create() {\r
+ return array();\r
+ }\r
+ \r
+ /**\r
+ * Destroys the object\r
+ */\r
+ function destroy() {\r
+ unset( $this );\r
+ }\r
+ \r
+ /**\r
+ * Checks whether the specified RDBMS is supported by the current\r
+ * database object or its ranking ancestor.\r
+ *\r
+ * @param string $platform RDBMS platform name (from ADODB platform list).\r
+ * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.\r
+ */\r
+ function supportedPlatform( $platform = NULL ) {\r
+ return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Returns the prefix set by the ranking ancestor of the database object.\r
+ *\r
+ * @param string $name Prefix string.\r
+ * @return string Prefix.\r
+ */\r
+ function prefix( $name = '' ) {\r
+ return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;\r
+ }\r
+ \r
+ /**\r
+ * Extracts a field ID from the specified field.\r
+ *\r
+ * @param string $field Field.\r
+ * @return string Field ID.\r
+ */\r
+ function FieldID( $field ) {\r
+ return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );\r
+ }\r
+}\r
+\r
+/**\r
+* Creates a table object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database table. As charactaristics\r
+* of the table are loaded from the external source, methods and properties\r
+* of this class are used to build up the table description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbTable extends dbObject {\r
+ \r
+ /**\r
+ * @var string Table name\r
+ */\r
+ var $name;\r
+ \r
+ /**\r
+ * @var array Field specifier: Meta-information about each field\r
+ */\r
+ var $fields = array();\r
+ \r
+ /**\r
+ * @var array List of table indexes.\r
+ */\r
+ var $indexes = array();\r
+ \r
+ /**\r
+ * @var array Table options: Table-level options\r
+ */\r
+ var $opts = array();\r
+ \r
+ /**\r
+ * @var string Field index: Keeps track of which field is currently being processed\r
+ */\r
+ var $current_field;\r
+ \r
+ /**\r
+ * @var boolean Mark table for destruction\r
+ * @access private\r
+ */\r
+ var $drop_table;\r
+ \r
+ /**\r
+ * @var boolean Mark field for destruction (not yet implemented)\r
+ * @access private\r
+ */\r
+ var $drop_field = array();\r
+ \r
+ /**\r
+ * Iniitializes a new table object.\r
+ *\r
+ * @param string $prefix DB Object prefix\r
+ * @param array $attributes Array of table attributes.\r
+ */\r
+ function dbTable( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ $this->name = $this->prefix($attributes['NAME']);\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements. Elements currently \r
+ * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT. \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'INDEX':\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ xml_set_object( $parser, $this->addIndex( $attributes ) );\r
+ }\r
+ break;\r
+ case 'DATA':\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ xml_set_object( $parser, $this->addData( $attributes ) );\r
+ }\r
+ break;\r
+ case 'DROP':\r
+ $this->drop();\r
+ break;\r
+ case 'FIELD':\r
+ // Add a field\r
+ $fieldName = $attributes['NAME'];\r
+ $fieldType = $attributes['TYPE'];\r
+ $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;\r
+ $fieldOpts = isset( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;\r
+ \r
+ $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );\r
+ break;\r
+ case 'KEY':\r
+ case 'NOTNULL':\r
+ case 'AUTOINCREMENT':\r
+ // Add a field option\r
+ $this->addFieldOpt( $this->current_field, $this->currentElement );\r
+ break;\r
+ case 'DEFAULT':\r
+ // Add a field option to the table object\r
+ \r
+ // Work around ADOdb datadict issue that misinterprets empty strings.\r
+ if( $attributes['VALUE'] == '' ) {\r
+ $attributes['VALUE'] = " '' ";\r
+ }\r
+ \r
+ $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );\r
+ break;\r
+ case 'DEFDATE':\r
+ case 'DEFTIMESTAMP':\r
+ // Add a field option to the table object\r
+ $this->addFieldOpt( $this->current_field, $this->currentElement );\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Table constraint\r
+ case 'CONSTRAINT':\r
+ if( isset( $this->current_field ) ) {\r
+ $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );\r
+ } else {\r
+ $this->addTableOpt( $cdata );\r
+ }\r
+ break;\r
+ // Table option\r
+ case 'OPT':\r
+ $this->addTableOpt( $cdata );\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'TABLE':\r
+ $this->parent->addSQL( $this->create( $this->parent ) );\r
+ xml_set_object( $parser, $this->parent );\r
+ $this->destroy();\r
+ break;\r
+ case 'FIELD':\r
+ unset($this->current_field);\r
+ break;\r
+\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds an index to a table object\r
+ *\r
+ * @param array $attributes Index attributes\r
+ * @return object dbIndex object\r
+ */\r
+ function addIndex( $attributes ) {\r
+ $name = strtoupper( $attributes['NAME'] );\r
+ $this->indexes[$name] = new dbIndex( $this, $attributes );\r
+ return $this->indexes[$name];\r
+ }\r
+ \r
+ /**\r
+ * Adds data to a table object\r
+ *\r
+ * @param array $attributes Data attributes\r
+ * @return object dbData object\r
+ */\r
+ function addData( $attributes ) {\r
+ if( !isset( $this->data ) ) {\r
+ $this->data = new dbData( $this, $attributes );\r
+ }\r
+ return $this->data;\r
+ }\r
+ \r
+ /**\r
+ * Adds a field to a table object\r
+ *\r
+ * $name is the name of the table to which the field should be added. \r
+ * $type is an ADODB datadict field type. The following field types\r
+ * are supported as of ADODB 3.40:\r
+ * - C: varchar\r
+ * - X: CLOB (character large object) or largest varchar size\r
+ * if CLOB is not supported\r
+ * - C2: Multibyte varchar\r
+ * - X2: Multibyte CLOB\r
+ * - B: BLOB (binary large object)\r
+ * - D: Date (some databases do not support this, and we return a datetime type)\r
+ * - T: Datetime or Timestamp\r
+ * - L: Integer field suitable for storing booleans (0 or 1)\r
+ * - I: Integer (mapped to I4)\r
+ * - I1: 1-byte integer\r
+ * - I2: 2-byte integer\r
+ * - I4: 4-byte integer\r
+ * - I8: 8-byte integer\r
+ * - F: Floating point number\r
+ * - N: Numeric or decimal number\r
+ *\r
+ * @param string $name Name of the table to which the field will be added.\r
+ * @param string $type ADODB datadict field type.\r
+ * @param string $size Field size\r
+ * @param array $opts Field options array\r
+ * @return array Field specifier array\r
+ */\r
+ function addField( $name, $type, $size = NULL, $opts = NULL ) {\r
+ $field_id = $this->FieldID( $name );\r
+ \r
+ // Set the field index so we know where we are\r
+ $this->current_field = $field_id;\r
+ \r
+ // Set the field name (required)\r
+ $this->fields[$field_id]['NAME'] = $name;\r
+ \r
+ // Set the field type (required)\r
+ $this->fields[$field_id]['TYPE'] = $type;\r
+ \r
+ // Set the field size (optional)\r
+ if( isset( $size ) ) {\r
+ $this->fields[$field_id]['SIZE'] = $size;\r
+ }\r
+ \r
+ // Set the field options\r
+ if( isset( $opts ) ) {\r
+ $this->fields[$field_id]['OPTS'][] = $opts;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds a field option to the current field specifier\r
+ *\r
+ * This method adds a field option allowed by the ADOdb datadict \r
+ * and appends it to the given field.\r
+ *\r
+ * @param string $field Field name\r
+ * @param string $opt ADOdb field option\r
+ * @param mixed $value Field option value\r
+ * @return array Field specifier array\r
+ */\r
+ function addFieldOpt( $field, $opt, $value = NULL ) {\r
+ if( !isset( $value ) ) {\r
+ $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;\r
+ // Add the option and value\r
+ } else {\r
+ $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds an option to the table\r
+ *\r
+ * This method takes a comma-separated list of table-level options\r
+ * and appends them to the table object.\r
+ *\r
+ * @param string $opt Table option\r
+ * @return array Options\r
+ */\r
+ function addTableOpt( $opt ) {\r
+ $this->opts[] = $opt;\r
+ \r
+ return $this->opts;\r
+ }\r
+ \r
+ /**\r
+ * Generates the SQL that will create the table in the database\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Array containing table creation SQL\r
+ */\r
+ function create( &$xmls ) {\r
+ $sql = array();\r
+ \r
+ // drop any existing indexes\r
+ if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {\r
+ foreach( $legacy_indexes as $index => $index_details ) {\r
+ $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );\r
+ }\r
+ }\r
+ \r
+ // remove fields to be dropped from table object\r
+ foreach( $this->drop_field as $field ) {\r
+ unset( $this->fields[$field] );\r
+ }\r
+ \r
+ // if table exists\r
+ if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {\r
+ // drop table\r
+ if( $this->drop_table ) {\r
+ $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+ \r
+ return $sql;\r
+ }\r
+ \r
+ // drop any existing fields not in schema\r
+ foreach( $legacy_fields as $field_id => $field ) {\r
+ if( !isset( $this->fields[$field_id] ) ) {\r
+ $sql[] = $xmls->dict->DropColumnSQL( $this->name, '`'.$field->name.'`' );\r
+ }\r
+ }\r
+ // if table doesn't exist\r
+ } else {\r
+ if( $this->drop_table ) {\r
+ return $sql;\r
+ }\r
+ \r
+ $legacy_fields = array();\r
+ }\r
+ \r
+ // Loop through the field specifier array, building the associative array for the field options\r
+ $fldarray = array();\r
+ \r
+ foreach( $this->fields as $field_id => $finfo ) {\r
+ // Set an empty size if it isn't supplied\r
+ if( !isset( $finfo['SIZE'] ) ) {\r
+ $finfo['SIZE'] = '';\r
+ }\r
+ \r
+ // Initialize the field array with the type and size\r
+ $fldarray[$field_id] = array(\r
+ 'NAME' => $finfo['NAME'],\r
+ 'TYPE' => $finfo['TYPE'],\r
+ 'SIZE' => $finfo['SIZE']\r
+ );\r
+ \r
+ // Loop through the options array and add the field options. \r
+ if( isset( $finfo['OPTS'] ) ) {\r
+ foreach( $finfo['OPTS'] as $opt ) {\r
+ // Option has an argument.\r
+ if( is_array( $opt ) ) {\r
+ $key = key( $opt );\r
+ $value = $opt[key( $opt )];\r
+ @$fldarray[$field_id][$key] .= $value;\r
+ // Option doesn't have arguments\r
+ } else {\r
+ $fldarray[$field_id][$opt] = $opt;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ if( empty( $legacy_fields ) ) {\r
+ // Create the new table\r
+ $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+ logMsg( end( $sql ), 'Generated CreateTableSQL' );\r
+ } else {\r
+ // Upgrade an existing table\r
+ logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );\r
+ switch( $xmls->upgrade ) {\r
+ // Use ChangeTableSQL\r
+ case 'ALTER':\r
+ logMsg( 'Generated ChangeTableSQL (ALTERing table)' );\r
+ $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );\r
+ break;\r
+ case 'REPLACE':\r
+ logMsg( 'Doing upgrade REPLACE (testing)' );\r
+ $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+ $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+ break;\r
+ // ignore table\r
+ default:\r
+ return array();\r
+ }\r
+ }\r
+ \r
+ foreach( $this->indexes as $index ) {\r
+ $sql[] = $index->create( $xmls );\r
+ }\r
+ \r
+ if( isset( $this->data ) ) {\r
+ $sql[] = $this->data->create( $xmls );\r
+ }\r
+ \r
+ return $sql;\r
+ }\r
+ \r
+ /**\r
+ * Marks a field or table for destruction\r
+ */\r
+ function drop() {\r
+ if( isset( $this->current_field ) ) {\r
+ // Drop the current field\r
+ logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );\r
+ // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );\r
+ $this->drop_field[$this->current_field] = $this->current_field;\r
+ } else {\r
+ // Drop the current table\r
+ logMsg( "Dropping table '{$this->name}'" );\r
+ // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );\r
+ $this->drop_table = TRUE;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+* Creates an index object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database index. As charactaristics\r
+* of the index are loaded from the external source, methods and properties\r
+* of this class are used to build up the index description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbIndex extends dbObject {\r
+ \r
+ /**\r
+ * @var string Index name\r
+ */\r
+ var $name;\r
+ \r
+ /**\r
+ * @var array Index options: Index-level options\r
+ */\r
+ var $opts = array();\r
+ \r
+ /**\r
+ * @var array Indexed fields: Table columns included in this index\r
+ */\r
+ var $columns = array();\r
+ \r
+ /**\r
+ * @var boolean Mark index for destruction\r
+ * @access private\r
+ */\r
+ var $drop = FALSE;\r
+ \r
+ /**\r
+ * Initializes the new dbIndex object.\r
+ *\r
+ * @param object $parent Parent object\r
+ * @param array $attributes Attributes\r
+ *\r
+ * @internal\r
+ */\r
+ function dbIndex( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ \r
+ $this->name = $this->prefix ($attributes['NAME']);\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * Processes XML opening tags. \r
+ * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'DROP':\r
+ $this->drop();\r
+ break;\r
+ case 'CLUSTERED':\r
+ case 'BITMAP':\r
+ case 'UNIQUE':\r
+ case 'FULLTEXT':\r
+ case 'HASH':\r
+ // Add index Option\r
+ $this->addIndexOpt( $this->currentElement );\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * Processes XML cdata.\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Index field name\r
+ case 'COL':\r
+ $this->addField( $cdata );\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'INDEX':\r
+ xml_set_object( $parser, $this->parent );\r
+ break;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds a field to the index\r
+ *\r
+ * @param string $name Field name\r
+ * @return string Field list\r
+ */\r
+ function addField( $name ) {\r
+ $this->columns[$this->FieldID( $name )] = $name;\r
+ \r
+ // Return the field list\r
+ return $this->columns;\r
+ }\r
+ \r
+ /**\r
+ * Adds options to the index\r
+ *\r
+ * @param string $opt Comma-separated list of index options.\r
+ * @return string Option list\r
+ */\r
+ function addIndexOpt( $opt ) {\r
+ $this->opts[] = $opt;\r
+ \r
+ // Return the options list\r
+ return $this->opts;\r
+ }\r
+ \r
+ /**\r
+ * Generates the SQL that will create the index in the database\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Array containing index creation SQL\r
+ */\r
+ function create( &$xmls ) {\r
+ if( $this->drop ) {\r
+ return NULL;\r
+ }\r
+ \r
+ // eliminate any columns that aren't in the table\r
+ foreach( $this->columns as $id => $col ) {\r
+ if( !isset( $this->parent->fields[$id] ) ) {\r
+ unset( $this->columns[$id] );\r
+ }\r
+ }\r
+ \r
+ return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );\r
+ }\r
+ \r
+ /**\r
+ * Marks an index for destruction\r
+ */\r
+ function drop() {\r
+ $this->drop = TRUE;\r
+ }\r
+}\r
+\r
+/**\r
+* Creates a data object in ADOdb's datadict format\r
+*\r
+* This class stores information about table data.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbData extends dbObject {\r
+ \r
+ var $data = array();\r
+ \r
+ var $row;\r
+ \r
+ /**\r
+ * Initializes the new dbIndex object.\r
+ *\r
+ * @param object $parent Parent object\r
+ * @param array $attributes Attributes\r
+ *\r
+ * @internal\r
+ */\r
+ function dbData( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * Processes XML opening tags. \r
+ * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'ROW':\r
+ $this->row = count( $this->data );\r
+ $this->data[$this->row] = array();\r
+ break;\r
+ case 'F':\r
+ $this->addField($attributes);\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * Processes XML cdata.\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Index field name\r
+ case 'F':\r
+ $this->addData( $cdata );\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'DATA':\r
+ xml_set_object( $parser, $this->parent );\r
+ break;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds a field to the index\r
+ *\r
+ * @param string $name Field name\r
+ * @return string Field list\r
+ */\r
+ function addField( $attributes ) {\r
+ if( isset( $attributes['NAME'] ) ) {\r
+ $name = $attributes['NAME'];\r
+ } else {\r
+ $name = count($this->data[$this->row]);\r
+ }\r
+ \r
+ // Set the field index so we know where we are\r
+ $this->current_field = $this->FieldID( $name );\r
+ }\r
+ \r
+ /**\r
+ * Adds options to the index\r
+ *\r
+ * @param string $opt Comma-separated list of index options.\r
+ * @return string Option list\r
+ */\r
+ function addData( $cdata ) {\r
+ if( !isset( $this->data[$this->row] ) ) {\r
+ $this->data[$this->row] = array();\r
+ }\r
+ \r
+ if( !isset( $this->data[$this->row][$this->current_field] ) ) {\r
+ $this->data[$this->row][$this->current_field] = '';\r
+ }\r
+ \r
+ $this->data[$this->row][$this->current_field] .= $cdata;\r
+ }\r
+ \r
+ /**\r
+ * Generates the SQL that will create the index in the database\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Array containing index creation SQL\r
+ */\r
+ function create( &$xmls ) {\r
+ $table = $xmls->dict->TableName($this->parent->name);\r
+ $table_field_count = count($this->parent->fields);\r
+ $sql = array();\r
+ \r
+ // eliminate any columns that aren't in the table\r
+ foreach( $this->data as $row ) {\r
+ $table_fields = $this->parent->fields;\r
+ $fields = array();\r
+ \r
+ foreach( $row as $field_id => $field_data ) {\r
+ if( !array_key_exists( $field_id, $table_fields ) ) {\r
+ if( is_numeric( $field_id ) ) {\r
+ $field_id = reset( array_keys( $table_fields ) );\r
+ } else {\r
+ continue;\r
+ }\r
+ }\r
+ \r
+ $name = $table_fields[$field_id]['NAME'];\r
+ \r
+ switch( $table_fields[$field_id]['TYPE'] ) {\r
+ case 'C':\r
+ case 'C2':\r
+ case 'X':\r
+ case 'X2':\r
+ $fields[$name] = $xmls->db->qstr( $field_data );\r
+ break;\r
+ case 'I':\r
+ case 'I1':\r
+ case 'I2':\r
+ case 'I4':\r
+ case 'I8':\r
+ $fields[$name] = intval($field_data);\r
+ break;\r
+ default:\r
+ $fields[$name] = $field_data;\r
+ }\r
+ \r
+ unset($table_fields[$field_id]);\r
+ }\r
+ \r
+ // check that at least 1 column is specified\r
+ if( empty( $fields ) ) {\r
+ continue;\r
+ }\r
+ \r
+ // check that no required columns are missing\r
+ if( count( $fields ) < $table_field_count ) {\r
+ foreach( $table_fields as $field ) {\r
+ if (isset( $field['OPTS'] ))\r
+ if( ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {\r
+ continue(2);\r
+ }\r
+ }\r
+ }\r
+ \r
+ $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';\r
+ }\r
+ \r
+ return $sql;\r
+ }\r
+}\r
+\r
+/**\r
+* Creates the SQL to execute a list of provided SQL queries\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbQuerySet extends dbObject {\r
+ \r
+ /**\r
+ * @var array List of SQL queries\r
+ */\r
+ var $queries = array();\r
+ \r
+ /**\r
+ * @var string String used to build of a query line by line\r
+ */\r
+ var $query;\r
+ \r
+ /**\r
+ * @var string Query prefix key\r
+ */\r
+ var $prefixKey = '';\r
+ \r
+ /**\r
+ * @var boolean Auto prefix enable (TRUE)\r
+ */\r
+ var $prefixMethod = 'AUTO';\r
+ \r
+ /**\r
+ * Initializes the query set.\r
+ *\r
+ * @param object $parent Parent object\r
+ * @param array $attributes Attributes\r
+ */\r
+ function dbQuerySet( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ \r
+ // Overrides the manual prefix key\r
+ if( isset( $attributes['KEY'] ) ) {\r
+ $this->prefixKey = $attributes['KEY'];\r
+ }\r
+ \r
+ $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';\r
+ \r
+ // Enables or disables automatic prefix prepending\r
+ switch( $prefixMethod ) {\r
+ case 'AUTO':\r
+ $this->prefixMethod = 'AUTO';\r
+ break;\r
+ case 'MANUAL':\r
+ $this->prefixMethod = 'MANUAL';\r
+ break;\r
+ case 'NONE':\r
+ $this->prefixMethod = 'NONE';\r
+ break;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements. Elements currently \r
+ * processed are: QUERY. \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'QUERY':\r
+ // Create a new query in a SQL queryset.\r
+ // Ignore this query set if a platform is specified and it's different than the \r
+ // current connection platform.\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ $this->newQuery();\r
+ } else {\r
+ $this->discardQuery();\r
+ }\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Line of queryset SQL data\r
+ case 'QUERY':\r
+ $this->buildQuery( $cdata );\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'QUERY':\r
+ // Add the finished query to the open query set.\r
+ $this->addQuery();\r
+ break;\r
+ case 'SQL':\r
+ $this->parent->addSQL( $this->create( $this->parent ) );\r
+ xml_set_object( $parser, $this->parent );\r
+ $this->destroy();\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Re-initializes the query.\r
+ *\r
+ * @return boolean TRUE\r
+ */\r
+ function newQuery() {\r
+ $this->query = '';\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Discards the existing query.\r
+ *\r
+ * @return boolean TRUE\r
+ */\r
+ function discardQuery() {\r
+ unset( $this->query );\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ /** \r
+ * Appends a line to a query that is being built line by line\r
+ *\r
+ * @param string $data Line of SQL data or NULL to initialize a new query\r
+ * @return string SQL query string.\r
+ */\r
+ function buildQuery( $sql = NULL ) {\r
+ if( !isset( $this->query ) OR empty( $sql ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $this->query .= $sql;\r
+ \r
+ return $this->query;\r
+ }\r
+ \r
+ /**\r
+ * Adds a completed query to the query list\r
+ *\r
+ * @return string SQL of added query\r
+ */\r
+ function addQuery() {\r
+ if( !isset( $this->query ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $this->queries[] = $return = trim($this->query);\r
+ \r
+ unset( $this->query );\r
+ \r
+ return $return;\r
+ }\r
+ \r
+ /**\r
+ * Creates and returns the current query set\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Query set\r
+ */\r
+ function create( &$xmls ) {\r
+ foreach( $this->queries as $id => $query ) {\r
+ switch( $this->prefixMethod ) {\r
+ case 'AUTO':\r
+ // Enable auto prefix replacement\r
+ \r
+ // Process object prefix.\r
+ // Evaluate SQL statements to prepend prefix to objects\r
+ $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+ $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+ $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+ \r
+ // SELECT statements aren't working yet\r
+ #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );\r
+ \r
+ case 'MANUAL':\r
+ // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.\r
+ // If prefixKey is not set, we use the default constant XMLS_PREFIX\r
+ if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {\r
+ // Enable prefix override\r
+ $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );\r
+ } else {\r
+ // Use default replacement\r
+ $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );\r
+ }\r
+ }\r
+ \r
+ $this->queries[$id] = trim( $query );\r
+ }\r
+ \r
+ // Return the query set array\r
+ return $this->queries;\r
+ }\r
+ \r
+ /**\r
+ * Rebuilds the query with the prefix attached to any objects\r
+ *\r
+ * @param string $regex Regex used to add prefix\r
+ * @param string $query SQL query string\r
+ * @param string $prefix Prefix to be appended to tables, indices, etc.\r
+ * @return string Prefixed SQL query string.\r
+ */\r
+ function prefixQuery( $regex, $query, $prefix = NULL ) {\r
+ if( !isset( $prefix ) ) {\r
+ return $query;\r
+ }\r
+ \r
+ if( preg_match( $regex, $query, $match ) ) {\r
+ $preamble = $match[1];\r
+ $postamble = $match[5];\r
+ $objectList = explode( ',', $match[3] );\r
+ // $prefix = $prefix . '_';\r
+ \r
+ $prefixedList = '';\r
+ \r
+ foreach( $objectList as $object ) {\r
+ if( $prefixedList !== '' ) {\r
+ $prefixedList .= ', ';\r
+ }\r
+ \r
+ $prefixedList .= $prefix . trim( $object );\r
+ }\r
+ \r
+ $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;\r
+ }\r
+ \r
+ return $query;\r
+ }\r
+}\r
+\r
+/**\r
+* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements\r
+* \r
+* This class is used to load and parse the XML file, to create an array of SQL statements\r
+* that can be used to build a database, and to build the database using the SQL array.\r
+*\r
+* @tutorial getting_started.pkg\r
+*\r
+* @author Richard Tango-Lowy & Dan Cech\r
+* @version $Revision$\r
+*\r
+* @package axmls\r
+*/\r
+class adoSchema {\r
+ \r
+ /**\r
+ * @var array Array containing SQL queries to generate all objects\r
+ * @access private\r
+ */\r
+ var $sqlArray;\r
+ \r
+ /**\r
+ * @var object ADOdb connection object\r
+ * @access private\r
+ */\r
+ var $db;\r
+ \r
+ /**\r
+ * @var object ADOdb Data Dictionary\r
+ * @access private\r
+ */\r
+ var $dict;\r
+ \r
+ /**\r
+ * @var string Current XML element\r
+ * @access private\r
+ */\r
+ var $currentElement = '';\r
+ \r
+ /**\r
+ * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database\r
+ * @access private\r
+ */\r
+ var $upgrade = '';\r
+ \r
+ /**\r
+ * @var string Optional object prefix\r
+ * @access private\r
+ */\r
+ var $objectPrefix = '';\r
+ \r
+ /**\r
+ * @var long Original Magic Quotes Runtime value\r
+ * @access private\r
+ */\r
+ var $mgq;\r
+ \r
+ /**\r
+ * @var long System debug\r
+ * @access private\r
+ */\r
+ var $debug;\r
+ \r
+ /**\r
+ * @var string Regular expression to find schema version\r
+ * @access private\r
+ */\r
+ var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';\r
+ \r
+ /**\r
+ * @var string Current schema version\r
+ * @access private\r
+ */\r
+ var $schemaVersion;\r
+ \r
+ /**\r
+ * @var int Success of last Schema execution\r
+ */\r
+ var $success;\r
+ \r
+ /**\r
+ * @var bool Execute SQL inline as it is generated\r
+ */\r
+ var $executeInline;\r
+ \r
+ /**\r
+ * @var bool Continue SQL execution if errors occur\r
+ */\r
+ var $continueOnError;\r
+ \r
+ /**\r
+ * Creates an adoSchema object\r
+ *\r
+ * Creating an adoSchema object is the first step in processing an XML schema.\r
+ * The only parameter is an ADOdb database connection object, which must already\r
+ * have been created.\r
+ *\r
+ * @param object $db ADOdb database connection object.\r
+ */\r
+ function adoSchema( &$db ) {\r
+ // Initialize the environment\r
+ $this->mgq = get_magic_quotes_runtime();\r
+ set_magic_quotes_runtime(0);\r
+ \r
+ $this->db = $db;\r
+ $this->debug = $this->db->debug;\r
+ $this->dict = NewDataDictionary( $this->db );\r
+ $this->sqlArray = array();\r
+ $this->schemaVersion = XMLS_SCHEMA_VERSION;\r
+ $this->executeInline( XMLS_EXECUTE_INLINE );\r
+ $this->continueOnError( XMLS_CONTINUE_ON_ERROR );\r
+ $this->setUpgradeMethod();\r
+ }\r
+ \r
+ /**\r
+ * Sets the method to be used for upgrading an existing database\r
+ *\r
+ * Use this method to specify how existing database objects should be upgraded.\r
+ * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to\r
+ * alter each database object directly, REPLACE attempts to rebuild each object\r
+ * from scratch, BEST attempts to determine the best upgrade method for each\r
+ * object, and NONE disables upgrading.\r
+ *\r
+ * This method is not yet used by AXMLS, but exists for backward compatibility.\r
+ * The ALTER method is automatically assumed when the adoSchema object is\r
+ * instantiated; other upgrade methods are not currently supported.\r
+ *\r
+ * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)\r
+ * @returns string Upgrade method used\r
+ */\r
+ function SetUpgradeMethod( $method = '' ) {\r
+ if( !is_string( $method ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $method = strtoupper( $method );\r
+ \r
+ // Handle the upgrade methods\r
+ switch( $method ) {\r
+ case 'ALTER':\r
+ $this->upgrade = $method;\r
+ break;\r
+ case 'REPLACE':\r
+ $this->upgrade = $method;\r
+ break;\r
+ case 'BEST':\r
+ $this->upgrade = 'ALTER';\r
+ break;\r
+ case 'NONE':\r
+ $this->upgrade = 'NONE';\r
+ break;\r
+ default:\r
+ // Use default if no legitimate method is passed.\r
+ $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;\r
+ }\r
+ \r
+ return $this->upgrade;\r
+ }\r
+ \r
+ /**\r
+ * Enables/disables inline SQL execution.\r
+ *\r
+ * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),\r
+ * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode\r
+ * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()\r
+ * to apply the schema to the database.\r
+ *\r
+ * @param bool $mode execute\r
+ * @return bool current execution mode\r
+ *\r
+ * @see ParseSchema(), ExecuteSchema()\r
+ */\r
+ function ExecuteInline( $mode = NULL ) {\r
+ if( is_bool( $mode ) ) {\r
+ $this->executeInline = $mode;\r
+ }\r
+ \r
+ return $this->executeInline;\r
+ }\r
+ \r
+ /**\r
+ * Enables/disables SQL continue on error.\r
+ *\r
+ * Call this method to enable or disable continuation of SQL execution if an error occurs.\r
+ * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.\r
+ * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing\r
+ * of the schema will continue.\r
+ *\r
+ * @param bool $mode execute\r
+ * @return bool current continueOnError mode\r
+ *\r
+ * @see addSQL(), ExecuteSchema()\r
+ */\r
+ function ContinueOnError( $mode = NULL ) {\r
+ if( is_bool( $mode ) ) {\r
+ $this->continueOnError = $mode;\r
+ }\r
+ \r
+ return $this->continueOnError;\r
+ }\r
+ \r
+ /**\r
+ * Loads an XML schema from a file and converts it to SQL.\r
+ *\r
+ * Call this method to load the specified schema (see the DTD for the proper format) from\r
+ * the filesystem and generate the SQL necessary to create the database described. \r
+ * @see ParseSchemaString()\r
+ *\r
+ * @param string $file Name of XML schema file.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute\r
+ */\r
+ function ParseSchema( $filename, $returnSchema = FALSE ) {\r
+ return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+ }\r
+ \r
+ /**\r
+ * Loads an XML schema from a file and converts it to SQL.\r
+ *\r
+ * Call this method to load the specified schema from a file (see the DTD for the proper format) \r
+ * and generate the SQL necessary to create the database described by the schema.\r
+ *\r
+ * @param string $file Name of XML schema file.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute.\r
+ *\r
+ * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()\r
+ * @see ParseSchema(), ParseSchemaString()\r
+ */\r
+ function ParseSchemaFile( $filename, $returnSchema = FALSE ) {\r
+ // Open the file\r
+ if( !($fp = fopen( $filename, 'r' )) ) {\r
+ // die( 'Unable to open file' );\r
+ return FALSE;\r
+ }\r
+ \r
+ // do version detection here\r
+ if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if ( $returnSchema )\r
+ {\r
+ $xmlstring = '';\r
+ while( $data = fread( $fp, 100000 ) ) {\r
+ $xmlstring .= $data;\r
+ }\r
+ return $xmlstring;\r
+ }\r
+ \r
+ $this->success = 2;\r
+ \r
+ $xmlParser = $this->create_parser();\r
+ \r
+ // Process the file\r
+ while( $data = fread( $fp, 4096 ) ) {\r
+ if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {\r
+ die( sprintf(\r
+ "XML error: %s at line %d",\r
+ xml_error_string( xml_get_error_code( $xmlParser) ),\r
+ xml_get_current_line_number( $xmlParser)\r
+ ) );\r
+ }\r
+ }\r
+ \r
+ xml_parser_free( $xmlParser );\r
+ \r
+ return $this->sqlArray;\r
+ }\r
+ \r
+ /**\r
+ * Converts an XML schema string to SQL.\r
+ *\r
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+ * and generate the SQL necessary to create the database described by the schema. \r
+ * @see ParseSchema()\r
+ *\r
+ * @param string $xmlstring XML schema string.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute.\r
+ */\r
+ function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {\r
+ if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ // do version detection here\r
+ if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if ( $returnSchema )\r
+ {\r
+ return $xmlstring;\r
+ }\r
+ \r
+ $this->success = 2;\r
+ \r
+ $xmlParser = $this->create_parser();\r
+ \r
+ if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {\r
+ die( sprintf(\r
+ "XML error: %s at line %d",\r
+ xml_error_string( xml_get_error_code( $xmlParser) ),\r
+ xml_get_current_line_number( $xmlParser)\r
+ ) );\r
+ }\r
+ \r
+ xml_parser_free( $xmlParser );\r
+ \r
+ return $this->sqlArray;\r
+ }\r
+ \r
+ /**\r
+ * Loads an XML schema from a file and converts it to uninstallation SQL.\r
+ *\r
+ * Call this method to load the specified schema (see the DTD for the proper format) from\r
+ * the filesystem and generate the SQL necessary to remove the database described.\r
+ * @see RemoveSchemaString()\r
+ *\r
+ * @param string $file Name of XML schema file.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute\r
+ */\r
+ function RemoveSchema( $filename, $returnSchema = FALSE ) {\r
+ return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+ }\r
+ \r
+ /**\r
+ * Converts an XML schema string to uninstallation SQL.\r
+ *\r
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+ * and generate the SQL necessary to uninstall the database described by the schema. \r
+ * @see RemoveSchema()\r
+ *\r
+ * @param string $schema XML schema string.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute.\r
+ */\r
+ function RemoveSchemaString( $schema, $returnSchema = FALSE ) {\r
+ \r
+ // grab current version\r
+ if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );\r
+ }\r
+ \r
+ /**\r
+ * Applies the current XML schema to the database (post execution).\r
+ *\r
+ * Call this method to apply the current schema (generally created by calling \r
+ * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes, \r
+ * and executing other SQL specified in the schema) after parsing.\r
+ * @see ParseSchema(), ParseSchemaString(), ExecuteInline()\r
+ *\r
+ * @param array $sqlArray Array of SQL statements that will be applied rather than\r
+ * the current schema.\r
+ * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.\r
+ * @returns integer 0 if failure, 1 if errors, 2 if successful.\r
+ */\r
+ function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {\r
+ if( !is_bool( $continueOnErr ) ) {\r
+ $continueOnErr = $this->ContinueOnError();\r
+ }\r
+ \r
+ if( !isset( $sqlArray ) ) {\r
+ $sqlArray = $this->sqlArray;\r
+ }\r
+ \r
+ if( !is_array( $sqlArray ) ) {\r
+ $this->success = 0;\r
+ } else {\r
+ $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );\r
+ }\r
+ \r
+ return $this->success;\r
+ }\r
+ \r
+ /**\r
+ * Returns the current SQL array. \r
+ *\r
+ * Call this method to fetch the array of SQL queries resulting from \r
+ * ParseSchema() or ParseSchemaString(). \r
+ *\r
+ * @param string $format Format: HTML, TEXT, or NONE (PHP array)\r
+ * @return array Array of SQL statements or FALSE if an error occurs\r
+ */\r
+ function PrintSQL( $format = 'NONE' ) {\r
+ $sqlArray = null;\r
+ return $this->getSQL( $format, $sqlArray );\r
+ }\r
+ \r
+ /**\r
+ * Saves the current SQL array to the local filesystem as a list of SQL queries.\r
+ *\r
+ * Call this method to save the array of SQL queries (generally resulting from a\r
+ * parsed XML schema) to the filesystem.\r
+ *\r
+ * @param string $filename Path and name where the file should be saved.\r
+ * @return boolean TRUE if save is successful, else FALSE. \r
+ */\r
+ function SaveSQL( $filename = './schema.sql' ) {\r
+ \r
+ if( !isset( $sqlArray ) ) {\r
+ $sqlArray = $this->sqlArray;\r
+ }\r
+ if( !isset( $sqlArray ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $fp = fopen( $filename, "w" );\r
+ \r
+ foreach( $sqlArray as $key => $query ) {\r
+ fwrite( $fp, $query . ";\n" );\r
+ }\r
+ fclose( $fp );\r
+ }\r
+ \r
+ /**\r
+ * Create an xml parser\r
+ *\r
+ * @return object PHP XML parser object\r
+ *\r
+ * @access private\r
+ */\r
+ function create_parser() {\r
+ // Create the parser\r
+ $xmlParser = xml_parser_create();\r
+ xml_set_object( $xmlParser, $this );\r
+ \r
+ // Initialize the XML callback functions\r
+ xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );\r
+ xml_set_character_data_handler( $xmlParser, '_tag_cdata' );\r
+ \r
+ return $xmlParser;\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ switch( strtoupper( $tag ) ) {\r
+ case 'TABLE':\r
+ $this->obj = new dbTable( $this, $attributes );\r
+ xml_set_object( $parser, $this->obj );\r
+ break;\r
+ case 'SQL':\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ $this->obj = new dbQuerySet( $this, $attributes );\r
+ xml_set_object( $parser, $this->obj );\r
+ }\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ \r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ * @internal\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ \r
+ }\r
+ \r
+ /**\r
+ * Converts an XML schema string to the specified DTD version.\r
+ *\r
+ * Call this method to convert a string containing an XML schema to a different AXMLS\r
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+ * parameter is specified, the schema will be converted to the current DTD version. \r
+ * If the newFile parameter is provided, the converted schema will be written to the specified\r
+ * file.\r
+ * @see ConvertSchemaFile()\r
+ *\r
+ * @param string $schema String containing XML schema that will be converted.\r
+ * @param string $newVersion DTD version to convert to.\r
+ * @param string $newFile File name of (converted) output file.\r
+ * @return string Converted XML schema or FALSE if an error occurs.\r
+ */\r
+ function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {\r
+ \r
+ // grab current version\r
+ if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if( !isset ($newVersion) ) {\r
+ $newVersion = $this->schemaVersion;\r
+ }\r
+ \r
+ if( $version == $newVersion ) {\r
+ $result = $schema;\r
+ } else {\r
+ $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);\r
+ }\r
+ \r
+ if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+ fwrite( $fp, $result );\r
+ fclose( $fp );\r
+ }\r
+ \r
+ return $result;\r
+ }\r
+ \r
+ // compat for pre-4.3 - jlim\r
+ function _file_get_contents($path)\r
+ {\r
+ if (function_exists('file_get_contents')) return file_get_contents($path);\r
+ return join('',file($path));\r
+ }\r
+ \r
+ /**\r
+ * Converts an XML schema file to the specified DTD version.\r
+ *\r
+ * Call this method to convert the specified XML schema file to a different AXMLS\r
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+ * parameter is specified, the schema will be converted to the current DTD version. \r
+ * If the newFile parameter is provided, the converted schema will be written to the specified\r
+ * file.\r
+ * @see ConvertSchemaString()\r
+ *\r
+ * @param string $filename Name of XML schema file that will be converted.\r
+ * @param string $newVersion DTD version to convert to.\r
+ * @param string $newFile File name of (converted) output file.\r
+ * @return string Converted XML schema or FALSE if an error occurs.\r
+ */\r
+ function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {\r
+ \r
+ // grab current version\r
+ if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if( !isset ($newVersion) ) {\r
+ $newVersion = $this->schemaVersion;\r
+ }\r
+ \r
+ if( $version == $newVersion ) {\r
+ $result = _file_get_contents( $filename );\r
+ \r
+ // remove unicode BOM if present\r
+ if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {\r
+ $result = substr( $result, 3 );\r
+ }\r
+ } else {\r
+ $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );\r
+ }\r
+ \r
+ if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+ fwrite( $fp, $result );\r
+ fclose( $fp );\r
+ }\r
+ \r
+ return $result;\r
+ }\r
+ \r
+ function TransformSchema( $schema, $xsl, $schematype='string' )\r
+ {\r
+ // Fail if XSLT extension is not available\r
+ if( ! function_exists( 'xslt_create' ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';\r
+ \r
+ // look for xsl\r
+ if( !is_readable( $xsl_file ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ switch( $schematype )\r
+ {\r
+ case 'file':\r
+ if( !is_readable( $schema ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $schema = _file_get_contents( $schema );\r
+ break;\r
+ case 'string':\r
+ default:\r
+ if( !is_string( $schema ) ) {\r
+ return FALSE;\r
+ }\r
+ }\r
+ \r
+ $arguments = array (\r
+ '/_xml' => $schema,\r
+ '/_xsl' => _file_get_contents( $xsl_file )\r
+ );\r
+ \r
+ // create an XSLT processor\r
+ $xh = xslt_create ();\r
+ \r
+ // set error handler\r
+ xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));\r
+ \r
+ // process the schema\r
+ $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); \r
+ \r
+ xslt_free ($xh);\r
+ \r
+ return $result;\r
+ }\r
+ \r
+ /**\r
+ * Processes XSLT transformation errors\r
+ *\r
+ * @param object $parser XML parser object\r
+ * @param integer $errno Error number\r
+ * @param integer $level Error level\r
+ * @param array $fields Error information fields\r
+ *\r
+ * @access private\r
+ */\r
+ function xslt_error_handler( $parser, $errno, $level, $fields ) {\r
+ if( is_array( $fields ) ) {\r
+ $msg = array(\r
+ 'Message Type' => ucfirst( $fields['msgtype'] ),\r
+ 'Message Code' => $fields['code'],\r
+ 'Message' => $fields['msg'],\r
+ 'Error Number' => $errno,\r
+ 'Level' => $level\r
+ );\r
+ \r
+ switch( $fields['URI'] ) {\r
+ case 'arg:/_xml':\r
+ $msg['Input'] = 'XML';\r
+ break;\r
+ case 'arg:/_xsl':\r
+ $msg['Input'] = 'XSL';\r
+ break;\r
+ default:\r
+ $msg['Input'] = $fields['URI'];\r
+ }\r
+ \r
+ $msg['Line'] = $fields['line'];\r
+ } else {\r
+ $msg = array(\r
+ 'Message Type' => 'Error',\r
+ 'Error Number' => $errno,\r
+ 'Level' => $level,\r
+ 'Fields' => var_export( $fields, TRUE )\r
+ );\r
+ }\r
+ \r
+ $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"\r
+ . '<table>' . "\n";\r
+ \r
+ foreach( $msg as $label => $details ) {\r
+ $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";\r
+ }\r
+ \r
+ $error_details .= '</table>';\r
+ \r
+ trigger_error( $error_details, E_USER_ERROR );\r
+ }\r
+ \r
+ /**\r
+ * Returns the AXMLS Schema Version of the requested XML schema file.\r
+ *\r
+ * Call this method to obtain the AXMLS DTD version of the requested XML schema file.\r
+ * @see SchemaStringVersion()\r
+ *\r
+ * @param string $filename AXMLS schema file\r
+ * @return string Schema version number or FALSE on error\r
+ */\r
+ function SchemaFileVersion( $filename ) {\r
+ // Open the file\r
+ if( !($fp = fopen( $filename, 'r' )) ) {\r
+ // die( 'Unable to open file' );\r
+ return FALSE;\r
+ }\r
+ \r
+ // Process the file\r
+ while( $data = fread( $fp, 4096 ) ) {\r
+ if( preg_match( $this->versionRegex, $data, $matches ) ) {\r
+ return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+ }\r
+ }\r
+ \r
+ return FALSE;\r
+ }\r
+ \r
+ /**\r
+ * Returns the AXMLS Schema Version of the provided XML schema string.\r
+ *\r
+ * Call this method to obtain the AXMLS DTD version of the provided XML schema string.\r
+ * @see SchemaFileVersion()\r
+ *\r
+ * @param string $xmlstring XML schema string\r
+ * @return string Schema version number or FALSE on error\r
+ */\r
+ function SchemaStringVersion( $xmlstring ) {\r
+ if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {\r
+ return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+ }\r
+ \r
+ return FALSE;\r
+ }\r
+ \r
+ /**\r
+ * Extracts an XML schema from an existing database.\r
+ *\r
+ * Call this method to create an XML schema string from an existing database.\r
+ * If the data parameter is set to TRUE, AXMLS will include the data from the database\r
+ * in the schema. \r
+ *\r
+ * @param boolean $data Include data in schema dump\r
+ * @return string Generated XML schema\r
+ */\r
+ function ExtractSchema( $data = FALSE ) {\r
+ $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );\r
+ \r
+ $schema = '<?xml version="1.0"?>' . "\n"\r
+ . '<schema version="' . $this->schemaVersion . '">' . "\n";\r
+ \r
+ if( is_array( $tables = $this->db->MetaTables( 'TABLES' ) ) ) {\r
+ foreach( $tables as $table ) {\r
+ $schema .= ' <table name="' . $table . '">' . "\n";\r
+ \r
+ // grab details from database\r
+ $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' );\r
+ $fields = $this->db->MetaColumns( $table );\r
+ $indexes = $this->db->MetaIndexes( $table );\r
+ \r
+ if( is_array( $fields ) ) {\r
+ foreach( $fields as $details ) {\r
+ $extra = '';\r
+ $content = array();\r
+ \r
+ if( $details->max_length > 0 ) {\r
+ $extra .= ' size="' . $details->max_length . '"';\r
+ }\r
+ \r
+ if( $details->primary_key ) {\r
+ $content[] = '<KEY/>';\r
+ } elseif( $details->not_null ) {\r
+ $content[] = '<NOTNULL/>';\r
+ }\r
+ \r
+ if( $details->has_default ) {\r
+ $content[] = '<DEFAULT value="' . $details->default_value . '"/>';\r
+ }\r
+ \r
+ if( $details->auto_increment ) {\r
+ $content[] = '<AUTOINCREMENT/>';\r
+ }\r
+ \r
+ // this stops the creation of 'R' columns,\r
+ // AUTOINCREMENT is used to create auto columns\r
+ $details->primary_key = 0;\r
+ $type = $rs->MetaType( $details );\r
+ \r
+ $schema .= ' <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>';\r
+ \r
+ if( !empty( $content ) ) {\r
+ $schema .= "\n " . implode( "\n ", $content ) . "\n ";\r
+ }\r
+ \r
+ $schema .= '</field>' . "\n";\r
+ }\r
+ }\r
+ \r
+ if( is_array( $indexes ) ) {\r
+ foreach( $indexes as $index => $details ) {\r
+ $schema .= ' <index name="' . $index . '">' . "\n";\r
+ \r
+ if( $details['unique'] ) {\r
+ $schema .= ' <UNIQUE/>' . "\n";\r
+ }\r
+ \r
+ foreach( $details['columns'] as $column ) {\r
+ $schema .= ' <col>' . $column . '</col>' . "\n";\r
+ }\r
+ \r
+ $schema .= ' </index>' . "\n";\r
+ }\r
+ }\r
+ \r
+ if( $data ) {\r
+ $rs = $this->db->Execute( 'SELECT * FROM ' . $table );\r
+ \r
+ if( is_object( $rs ) ) {\r
+ $schema .= ' <data>' . "\n";\r
+ \r
+ while( $row = $rs->FetchRow() ) {\r
+ foreach( $row as $key => $val ) {\r
+ $row[$key] = htmlentities($val);\r
+ }\r
+ \r
+ $schema .= ' <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";\r
+ }\r
+ \r
+ $schema .= ' </data>' . "\n";\r
+ }\r
+ }\r
+ \r
+ $schema .= ' </table>' . "\n";\r
+ }\r
+ }\r
+ \r
+ $this->db->SetFetchMode( $old_mode );\r
+ \r
+ $schema .= '</schema>';\r
+ return $schema;\r
+ }\r
+ \r
+ /**\r
+ * Sets a prefix for database objects\r
+ *\r
+ * Call this method to set a standard prefix that will be prepended to all database tables \r
+ * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.\r
+ *\r
+ * @param string $prefix Prefix that will be prepended.\r
+ * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.\r
+ * @return boolean TRUE if successful, else FALSE\r
+ */\r
+ function SetPrefix( $prefix = '', $underscore = TRUE ) {\r
+ switch( TRUE ) {\r
+ // clear prefix\r
+ case empty( $prefix ):\r
+ logMsg( 'Cleared prefix' );\r
+ $this->objectPrefix = '';\r
+ return TRUE;\r
+ // prefix too long\r
+ case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:\r
+ // prefix contains invalid characters\r
+ case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):\r
+ logMsg( 'Invalid prefix: ' . $prefix );\r
+ return FALSE;\r
+ }\r
+ \r
+ if( $underscore AND substr( $prefix, -1 ) != '_' ) {\r
+ $prefix .= '_';\r
+ }\r
+ \r
+ // prefix valid\r
+ logMsg( 'Set prefix: ' . $prefix );\r
+ $this->objectPrefix = $prefix;\r
+ return TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Returns an object name with the current prefix prepended.\r
+ *\r
+ * @param string $name Name\r
+ * @return string Prefixed name\r
+ *\r
+ * @access private\r
+ */\r
+ function prefix( $name = '' ) {\r
+ // if prefix is set\r
+ if( !empty( $this->objectPrefix ) ) {\r
+ // Prepend the object prefix to the table name\r
+ // prepend after quote if used\r
+ return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );\r
+ }\r
+ \r
+ // No prefix set. Use name provided.\r
+ return $name;\r
+ }\r
+ \r
+ /**\r
+ * Checks if element references a specific platform\r
+ *\r
+ * @param string $platform Requested platform\r
+ * @returns boolean TRUE if platform check succeeds\r
+ *\r
+ * @access private\r
+ */\r
+ function supportedPlatform( $platform = NULL ) {\r
+ $regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';\r
+ \r
+ if( !isset( $platform ) OR preg_match( $regex, $platform ) ) {\r
+ logMsg( "Platform $platform is supported" );\r
+ return TRUE;\r
+ } else {\r
+ logMsg( "Platform $platform is NOT supported" );\r
+ return FALSE;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Clears the array of generated SQL.\r
+ *\r
+ * @access private\r
+ */\r
+ function clearSQL() {\r
+ $this->sqlArray = array();\r
+ }\r
+ \r
+ /**\r
+ * Adds SQL into the SQL array.\r
+ *\r
+ * @param mixed $sql SQL to Add\r
+ * @return boolean TRUE if successful, else FALSE.\r
+ *\r
+ * @access private\r
+ */ \r
+ function addSQL( $sql = NULL ) {\r
+ if( is_array( $sql ) ) {\r
+ foreach( $sql as $line ) {\r
+ $this->addSQL( $line );\r
+ }\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ if( is_string( $sql ) ) {\r
+ $this->sqlArray[] = $sql;\r
+ \r
+ // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.\r
+ if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {\r
+ $saved = $this->db->debug;\r
+ $this->db->debug = $this->debug;\r
+ $ok = $this->db->Execute( $sql );\r
+ $this->db->debug = $saved;\r
+ \r
+ if( !$ok ) {\r
+ if( $this->debug ) {\r
+ ADOConnection::outp( $this->db->ErrorMsg() );\r
+ }\r
+ \r
+ $this->success = 1;\r
+ }\r
+ }\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ return FALSE;\r
+ }\r
+ \r
+ /**\r
+ * Gets the SQL array in the specified format.\r
+ *\r
+ * @param string $format Format\r
+ * @return mixed SQL\r
+ * \r
+ * @access private\r
+ */\r
+ function getSQL( $format = NULL, $sqlArray = NULL ) {\r
+ if( !is_array( $sqlArray ) ) {\r
+ $sqlArray = $this->sqlArray;\r
+ }\r
+ \r
+ if( !is_array( $sqlArray ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ switch( strtolower( $format ) ) {\r
+ case 'string':\r
+ case 'text':\r
+ return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';\r
+ case'html':\r
+ return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';\r
+ }\r
+ \r
+ return $this->sqlArray;\r
+ }\r
+ \r
+ /**\r
+ * Destroys an adoSchema object.\r
+ *\r
+ * Call this method to clean up after an adoSchema object that is no longer in use.\r
+ * @deprecated adoSchema now cleans up automatically.\r
+ */\r
+ function Destroy() {\r
+ set_magic_quotes_runtime( $this->mgq );\r
+ unset( $this );\r
+ }\r
+}\r
+\r
+/**\r
+* Message logging function\r
+*\r
+* @access private\r
+*/\r
+function logMsg( $msg, $title = NULL, $force = FALSE ) {\r
+ if( XMLS_DEBUG or $force ) {\r
+ echo '<pre>';\r
+ \r
+ if( isset( $title ) ) {\r
+ echo '<h3>' . htmlentities( $title ) . '</h3>';\r
+ }\r
+ \r
+ if( is_object( $this ) ) {\r
+ echo '[' . get_class( $this ) . '] ';\r
+ }\r
+ \r
+ print_r( $msg );\r
+ \r
+ echo '</pre>';\r
+ }\r
+}\r
?>
\ No newline at end of file
-<?php
-// Copyright (c) 2004-2005 ars Cognita Inc., all rights reserved
-/* ******************************************************************************
- Released under both BSD license and Lesser GPL library license.
- Whenever there is any discrepancy between the two licenses,
- the BSD license will take precedence.
-*******************************************************************************/
-/**
- * xmlschema is a class that allows the user to quickly and easily
- * build a database on any ADOdb-supported platform using a simple
- * XML schema.
- *
- * Last Editor: $Author$
- * @author Richard Tango-Lowy & Dan Cech
- * @version $Revision$
- *
- * @package axmls
- * @tutorial getting_started.pkg
- */
-
-function _file_get_contents($file)
-{
- if (function_exists('file_get_contents')) return file_get_contents($file);
-
- $f = fopen($file,'r');
- if (!$f) return '';
- $t = '';
-
- while ($s = fread($f,100000)) $t .= $s;
- fclose($f);
- return $t;
-}
-
-
-/**
-* Debug on or off
-*/
-if( !defined( 'XMLS_DEBUG' ) ) {
- define( 'XMLS_DEBUG', FALSE );
-}
-
-/**
-* Default prefix key
-*/
-if( !defined( 'XMLS_PREFIX' ) ) {
- define( 'XMLS_PREFIX', '%%P' );
-}
-
-/**
-* Maximum length allowed for object prefix
-*/
-if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
- define( 'XMLS_PREFIX_MAXLEN', 10 );
-}
-
-/**
-* Execute SQL inline as it is generated
-*/
-if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
- define( 'XMLS_EXECUTE_INLINE', FALSE );
-}
-
-/**
-* Continue SQL Execution if an error occurs?
-*/
-if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
- define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
-}
-
-/**
-* Current Schema Version
-*/
-if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
- define( 'XMLS_SCHEMA_VERSION', '0.3' );
-}
-
-/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
- define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
-}
-
-/**
-* How to handle data rows that already exist in a database during and upgrade.
-* Options are INSERT (attempts to insert duplicate rows), UPDATE (updates existing
-* rows) and IGNORE (ignores existing rows).
-*/
-if( !defined( 'XMLS_MODE_INSERT' ) ) {
- define( 'XMLS_MODE_INSERT', 0 );
-}
-if( !defined( 'XMLS_MODE_UPDATE' ) ) {
- define( 'XMLS_MODE_UPDATE', 1 );
-}
-if( !defined( 'XMLS_MODE_IGNORE' ) ) {
- define( 'XMLS_MODE_IGNORE', 2 );
-}
-if( !defined( 'XMLS_EXISTING_DATA' ) ) {
- define( 'XMLS_EXISTING_DATA', XMLS_MODE_INSERT );
-}
-
-/**
-* Default Schema Version. Used for Schemas without an explicit version set.
-*/
-if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
- define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
-}
-
-/**
-* Include the main ADODB library
-*/
-if( !defined( '_ADODB_LAYER' ) ) {
- require( 'adodb.inc.php' );
- require( 'adodb-datadict.inc.php' );
-}
-
-/**
-* Abstract DB Object. This class provides basic methods for database objects, such
-* as tables and indexes.
-*
-* @package axmls
-* @access private
-*/
-class dbObject {
-
- /**
- * var object Parent
- */
- var $parent;
-
- /**
- * var string current element
- */
- var $currentElement;
-
- /**
- * NOP
- */
- function dbObject( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
- }
-
- /**
- * XML Callback to process start elements
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
-
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
-
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
-
- }
-
- function create() {
- return array();
- }
-
- /**
- * Destroys the object
- */
- function destroy() {
- unset( $this );
- }
-
- /**
- * Checks whether the specified RDBMS is supported by the current
- * database object or its ranking ancestor.
- *
- * @param string $platform RDBMS platform name (from ADODB platform list).
- * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.
- */
- function supportedPlatform( $platform = NULL ) {
- return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
- }
-
- /**
- * Returns the prefix set by the ranking ancestor of the database object.
- *
- * @param string $name Prefix string.
- * @return string Prefix.
- */
- function prefix( $name = '' ) {
- return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
- }
-
- /**
- * Extracts a field ID from the specified field.
- *
- * @param string $field Field.
- * @return string Field ID.
- */
- function FieldID( $field ) {
- return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
- }
-}
-
-/**
-* Creates a table object in ADOdb's datadict format
-*
-* This class stores information about a database table. As charactaristics
-* of the table are loaded from the external source, methods and properties
-* of this class are used to build up the table description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbTable extends dbObject {
-
- /**
- * @var string Table name
- */
- var $name;
-
- /**
- * @var array Field specifier: Meta-information about each field
- */
- var $fields = array();
-
- /**
- * @var array List of table indexes.
- */
- var $indexes = array();
-
- /**
- * @var array Table options: Table-level options
- */
- var $opts = array();
-
- /**
- * @var string Field index: Keeps track of which field is currently being processed
- */
- var $current_field;
-
- /**
- * @var boolean Mark table for destruction
- * @access private
- */
- var $drop_table;
-
- /**
- * @var boolean Mark field for destruction (not yet implemented)
- * @access private
- */
- var $drop_field = array();
-
- /**
- * @var array Platform-specific options
- * @access private
- */
- var $currentPlatform = true;
-
-
- /**
- * Iniitializes a new table object.
- *
- * @param string $prefix DB Object prefix
- * @param array $attributes Array of table attributes.
- */
- function dbTable( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
- $this->name = $this->prefix($attributes['NAME']);
- }
-
- /**
- * XML Callback to process start elements. Elements currently
- * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT.
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'INDEX':
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- xml_set_object( $parser, $this->addIndex( $attributes ) );
- }
- break;
- case 'DATA':
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- xml_set_object( $parser, $this->addData( $attributes ) );
- }
- break;
- case 'DROP':
- $this->drop();
- break;
- case 'FIELD':
- // Add a field
- $fieldName = $attributes['NAME'];
- $fieldType = $attributes['TYPE'];
- $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;
- $fieldOpts = !empty( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;
-
- $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
- break;
- case 'KEY':
- case 'NOTNULL':
- case 'AUTOINCREMENT':
- case 'DEFDATE':
- case 'DEFTIMESTAMP':
- case 'UNSIGNED':
- // Add a field option
- $this->addFieldOpt( $this->current_field, $this->currentElement );
- break;
- case 'DEFAULT':
- // Add a field option to the table object
-
- // Work around ADOdb datadict issue that misinterprets empty strings.
- if( $attributes['VALUE'] == '' ) {
- $attributes['VALUE'] = " '' ";
- }
-
- $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );
- break;
- case 'OPT':
- case 'CONSTRAINT':
- // Accept platform-specific options
- $this->currentPlatform = ( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) );
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Table/field constraint
- case 'CONSTRAINT':
- if( isset( $this->current_field ) ) {
- $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
- } else {
- $this->addTableOpt( $cdata );
- }
- break;
- // Table/field option
- case 'OPT':
- if( isset( $this->current_field ) ) {
- $this->addFieldOpt( $this->current_field, $cdata );
- } else {
- $this->addTableOpt( $cdata );
- }
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'TABLE':
- $this->parent->addSQL( $this->create( $this->parent ) );
- xml_set_object( $parser, $this->parent );
- $this->destroy();
- break;
- case 'FIELD':
- unset($this->current_field);
- break;
- case 'OPT':
- case 'CONSTRAINT':
- $this->currentPlatform = true;
- break;
- default:
-
- }
- }
-
- /**
- * Adds an index to a table object
- *
- * @param array $attributes Index attributes
- * @return object dbIndex object
- */
- function &addIndex( $attributes ) {
- $name = strtoupper( $attributes['NAME'] );
- $this->indexes[$name] =& new dbIndex( $this, $attributes );
- return $this->indexes[$name];
- }
-
- /**
- * Adds data to a table object
- *
- * @param array $attributes Data attributes
- * @return object dbData object
- */
- function &addData( $attributes ) {
- if( !isset( $this->data ) ) {
- $this->data =& new dbData( $this, $attributes );
- }
- return $this->data;
- }
-
- /**
- * Adds a field to a table object
- *
- * $name is the name of the table to which the field should be added.
- * $type is an ADODB datadict field type. The following field types
- * are supported as of ADODB 3.40:
- * - C: varchar
- * - X: CLOB (character large object) or largest varchar size
- * if CLOB is not supported
- * - C2: Multibyte varchar
- * - X2: Multibyte CLOB
- * - B: BLOB (binary large object)
- * - D: Date (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
- *
- * @param string $name Name of the table to which the field will be added.
- * @param string $type ADODB datadict field type.
- * @param string $size Field size
- * @param array $opts Field options array
- * @return array Field specifier array
- */
- function addField( $name, $type, $size = NULL, $opts = NULL ) {
- $field_id = $this->FieldID( $name );
-
- // Set the field index so we know where we are
- $this->current_field = $field_id;
-
- // Set the field name (required)
- $this->fields[$field_id]['NAME'] = $name;
-
- // Set the field type (required)
- $this->fields[$field_id]['TYPE'] = $type;
-
- // Set the field size (optional)
- if( isset( $size ) ) {
- $this->fields[$field_id]['SIZE'] = $size;
- }
-
- // Set the field options
- if( isset( $opts ) ) {
- $this->fields[$field_id]['OPTS'] = array($opts);
- } else {
- $this->fields[$field_id]['OPTS'] = array();
- }
- }
-
- /**
- * Adds a field option to the current field specifier
- *
- * This method adds a field option allowed by the ADOdb datadict
- * and appends it to the given field.
- *
- * @param string $field Field name
- * @param string $opt ADOdb field option
- * @param mixed $value Field option value
- * @return array Field specifier array
- */
- function addFieldOpt( $field, $opt, $value = NULL ) {
- if( $this->currentPlatform ) {
- if( !isset( $value ) ) {
- $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
- // Add the option and value
- } else {
- $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );
- }
- }
- }
-
- /**
- * Adds an option to the table
- *
- * This method takes a comma-separated list of table-level options
- * and appends them to the table object.
- *
- * @param string $opt Table option
- * @return array Options
- */
- function addTableOpt( $opt ) {
- if( $this->currentPlatform ) {
- $this->opts[] = $opt;
- }
- return $this->opts;
- }
-
- /**
- * Generates the SQL that will create the table in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing table creation SQL
- */
- function create( &$xmls ) {
- $sql = array();
-
- // drop any existing indexes
- if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
- foreach( $legacy_indexes as $index => $index_details ) {
- $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
- }
- }
-
- // remove fields to be dropped from table object
- foreach( $this->drop_field as $field ) {
- unset( $this->fields[$field] );
- }
-
- // if table exists
- if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
- // drop table
- if( $this->drop_table ) {
- $sql[] = $xmls->dict->DropTableSQL( $this->name );
-
- return $sql;
- }
-
- // drop any existing fields not in schema
- foreach( $legacy_fields as $field_id => $field ) {
- if( !isset( $this->fields[$field_id] ) ) {
- $sql[] = $xmls->dict->DropColumnSQL( $this->name, $field->name );
- }
- }
- // if table doesn't exist
- } else {
- if( $this->drop_table ) {
- return $sql;
- }
-
- $legacy_fields = array();
- }
-
- // Loop through the field specifier array, building the associative array for the field options
- $fldarray = array();
-
- foreach( $this->fields as $field_id => $finfo ) {
- // Set an empty size if it isn't supplied
- if( !isset( $finfo['SIZE'] ) ) {
- $finfo['SIZE'] = '';
- }
-
- // Initialize the field array with the type and size
- $fldarray[$field_id] = array(
- 'NAME' => $finfo['NAME'],
- 'TYPE' => $finfo['TYPE'],
- 'SIZE' => $finfo['SIZE']
- );
-
- // Loop through the options array and add the field options.
- if( isset( $finfo['OPTS'] ) ) {
- foreach( $finfo['OPTS'] as $opt ) {
- // Option has an argument.
- if( is_array( $opt ) ) {
- $key = key( $opt );
- $value = $opt[key( $opt )];
- @$fldarray[$field_id][$key] .= $value;
- // Option doesn't have arguments
- } else {
- $fldarray[$field_id][$opt] = $opt;
- }
- }
- }
- }
-
- if( empty( $legacy_fields ) ) {
- // Create the new table
- $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
- logMsg( end( $sql ), 'Generated CreateTableSQL' );
- } else {
- // Upgrade an existing table
- logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
- switch( $xmls->upgrade ) {
- // Use ChangeTableSQL
- case 'ALTER':
- logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
- $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
- break;
- case 'REPLACE':
- logMsg( 'Doing upgrade REPLACE (testing)' );
- $sql[] = $xmls->dict->DropTableSQL( $this->name );
- $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
- break;
- // ignore table
- default:
- return array();
- }
- }
-
- foreach( $this->indexes as $index ) {
- $sql[] = $index->create( $xmls );
- }
-
- if( isset( $this->data ) ) {
- $sql[] = $this->data->create( $xmls );
- }
-
- return $sql;
- }
-
- /**
- * Marks a field or table for destruction
- */
- function drop() {
- if( isset( $this->current_field ) ) {
- // Drop the current field
- logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );
- // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );
- $this->drop_field[$this->current_field] = $this->current_field;
- } else {
- // Drop the current table
- logMsg( "Dropping table '{$this->name}'" );
- // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );
- $this->drop_table = TRUE;
- }
- }
-}
-
-/**
-* Creates an index object in ADOdb's datadict format
-*
-* This class stores information about a database index. As charactaristics
-* of the index are loaded from the external source, methods and properties
-* of this class are used to build up the index description in ADOdb's
-* datadict format.
-*
-* @package axmls
-* @access private
-*/
-class dbIndex extends dbObject {
-
- /**
- * @var string Index name
- */
- var $name;
-
- /**
- * @var array Index options: Index-level options
- */
- var $opts = array();
-
- /**
- * @var array Indexed fields: Table columns included in this index
- */
- var $columns = array();
-
- /**
- * @var boolean Mark index for destruction
- * @access private
- */
- var $drop = FALSE;
-
- /**
- * Initializes the new dbIndex object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function dbIndex( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
-
- $this->name = $this->prefix ($attributes['NAME']);
- }
-
- /**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH.
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'DROP':
- $this->drop();
- break;
- case 'CLUSTERED':
- case 'BITMAP':
- case 'UNIQUE':
- case 'FULLTEXT':
- case 'HASH':
- // Add index Option
- $this->addIndexOpt( $this->currentElement );
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Index field name
- case 'COL':
- $this->addField( $cdata );
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'INDEX':
- xml_set_object( $parser, $this->parent );
- break;
- }
- }
-
- /**
- * Adds a field to the index
- *
- * @param string $name Field name
- * @return string Field list
- */
- function addField( $name ) {
- $this->columns[$this->FieldID( $name )] = $name;
-
- // Return the field list
- return $this->columns;
- }
-
- /**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
- function addIndexOpt( $opt ) {
- $this->opts[] = $opt;
-
- // Return the options list
- return $this->opts;
- }
-
- /**
- * Generates the SQL that will create the index in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
- function create( &$xmls ) {
- if( $this->drop ) {
- return NULL;
- }
-
- // eliminate any columns that aren't in the table
- foreach( $this->columns as $id => $col ) {
- if( !isset( $this->parent->fields[$id] ) ) {
- unset( $this->columns[$id] );
- }
- }
-
- return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
- }
-
- /**
- * Marks an index for destruction
- */
- function drop() {
- $this->drop = TRUE;
- }
-}
-
-/**
-* Creates a data object in ADOdb's datadict format
-*
-* This class stores information about table data, and is called
-* when we need to load field data into a table.
-*
-* @package axmls
-* @access private
-*/
-class dbData extends dbObject {
-
- var $data = array();
-
- var $row;
-
- /**
- * Initializes the new dbData object.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- *
- * @internal
- */
- function dbData( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
- }
-
- /**
- * XML Callback to process start elements
- *
- * Processes XML opening tags.
- * Elements currently processed are: ROW and F (field).
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'ROW':
- $this->row = count( $this->data );
- $this->data[$this->row] = array();
- break;
- case 'F':
- $this->addField($attributes);
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * Processes XML cdata.
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Index field name
- case 'F':
- $this->addData( $cdata );
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'DATA':
- xml_set_object( $parser, $this->parent );
- break;
- }
- }
-
- /**
- * Adds a field to the insert
- *
- * @param string $name Field name
- * @return string Field list
- */
- function addField( $attributes ) {
- // check we're in a valid row
- if( !isset( $this->row ) || !isset( $this->data[$this->row] ) ) {
- return;
- }
-
- // Set the field index so we know where we are
- if( isset( $attributes['NAME'] ) ) {
- $this->current_field = $this->FieldID( $attributes['NAME'] );
- } else {
- $this->current_field = count( $this->data[$this->row] );
- }
-
- // initialise data
- if( !isset( $this->data[$this->row][$this->current_field] ) ) {
- $this->data[$this->row][$this->current_field] = '';
- }
- }
-
- /**
- * Adds options to the index
- *
- * @param string $opt Comma-separated list of index options.
- * @return string Option list
- */
- function addData( $cdata ) {
- // check we're in a valid field
- if ( isset( $this->data[$this->row][$this->current_field] ) ) {
- // add data to field
- $this->data[$this->row][$this->current_field] .= $cdata;
- }
- }
-
- /**
- * Generates the SQL that will add/update the data in the database
- *
- * @param object $xmls adoSchema object
- * @return array Array containing index creation SQL
- */
- function create( &$xmls ) {
- $table = $xmls->dict->TableName($this->parent->name);
- $table_field_count = count($this->parent->fields);
- $tables = $xmls->db->MetaTables();
- $sql = array();
-
- $ukeys = $xmls->db->MetaPrimaryKeys( $table );
- if( !empty( $this->parent->indexes ) and !empty( $ukeys ) ) {
- foreach( $this->parent->indexes as $indexObj ) {
- if( !in_array( $indexObj->name, $ukeys ) ) $ukeys[] = $indexObj->name;
- }
- }
-
- // eliminate any columns that aren't in the table
- foreach( $this->data as $row ) {
- $table_fields = $this->parent->fields;
- $fields = array();
- $rawfields = array(); // Need to keep some of the unprocessed data on hand.
-
- foreach( $row as $field_id => $field_data ) {
- if( !array_key_exists( $field_id, $table_fields ) ) {
- if( is_numeric( $field_id ) ) {
- $field_id = reset( array_keys( $table_fields ) );
- } else {
- continue;
- }
- }
-
- $name = $table_fields[$field_id]['NAME'];
-
- switch( $table_fields[$field_id]['TYPE'] ) {
- case 'I':
- case 'I1':
- case 'I2':
- case 'I4':
- case 'I8':
- $fields[$name] = intval($field_data);
- break;
- case 'C':
- case 'C2':
- case 'X':
- case 'X2':
- default:
- $fields[$name] = $xmls->db->qstr( $field_data );
- $rawfields[$name] = $field_data;
- }
-
- unset($table_fields[$field_id]);
-
- }
-
- // check that at least 1 column is specified
- if( empty( $fields ) ) {
- continue;
- }
-
- // check that no required columns are missing
- if( count( $fields ) < $table_field_count ) {
- foreach( $table_fields as $field ) {
- if( isset( $field['OPTS'] ) and ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {
- continue(2);
- }
- }
- }
-
- // The rest of this method deals with updating existing data records.
-
- if( !in_array( $table, $tables ) or ( $mode = $xmls->existingData() ) == XMLS_MODE_INSERT ) {
- // Table doesn't yet exist, so it's safe to insert.
- logMsg( "$table doesn't exist, inserting or mode is INSERT" );
- $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
- continue;
- }
-
- // Prepare to test for potential violations. Get primary keys and unique indexes
- $mfields = array_merge( $fields, $rawfields );
- $keyFields = array_intersect( $ukeys, array_keys( $mfields ) );
-
- if( empty( $ukeys ) or count( $keyFields ) == 0 ) {
- // No unique keys in schema, so safe to insert
- logMsg( "Either schema or data has no unique keys, so safe to insert" );
- $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
- continue;
- }
-
- // Select record containing matching unique keys.
- $where = '';
- foreach( $ukeys as $key ) {
- if( isset( $mfields[$key] ) and $mfields[$key] ) {
- if( $where ) $where .= ' AND ';
- $where .= $key . ' = ' . $xmls->db->qstr( $mfields[$key] );
- }
- }
- $records = $xmls->db->Execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where );
- switch( $records->RecordCount() ) {
- case 0:
- // No matching record, so safe to insert.
- logMsg( "No matching records. Inserting new row with unique data" );
- $sql[] = $xmls->db->GetInsertSQL( $records, $mfields );
- break;
- case 1:
- // Exactly one matching record, so we can update if the mode permits.
- logMsg( "One matching record..." );
- if( $mode == XMLS_MODE_UPDATE ) {
- logMsg( "...Updating existing row from unique data" );
- $sql[] = $xmls->db->GetUpdateSQL( $records, $mfields );
- }
- break;
- default:
- // More than one matching record; the result is ambiguous, so we must ignore the row.
- logMsg( "More than one matching record. Ignoring row." );
- }
- }
- return $sql;
- }
-}
-
-/**
-* Creates the SQL to execute a list of provided SQL queries
-*
-* @package axmls
-* @access private
-*/
-class dbQuerySet extends dbObject {
-
- /**
- * @var array List of SQL queries
- */
- var $queries = array();
-
- /**
- * @var string String used to build of a query line by line
- */
- var $query;
-
- /**
- * @var string Query prefix key
- */
- var $prefixKey = '';
-
- /**
- * @var boolean Auto prefix enable (TRUE)
- */
- var $prefixMethod = 'AUTO';
-
- /**
- * Initializes the query set.
- *
- * @param object $parent Parent object
- * @param array $attributes Attributes
- */
- function dbQuerySet( &$parent, $attributes = NULL ) {
- $this->parent =& $parent;
-
- // Overrides the manual prefix key
- if( isset( $attributes['KEY'] ) ) {
- $this->prefixKey = $attributes['KEY'];
- }
-
- $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';
-
- // Enables or disables automatic prefix prepending
- switch( $prefixMethod ) {
- case 'AUTO':
- $this->prefixMethod = 'AUTO';
- break;
- case 'MANUAL':
- $this->prefixMethod = 'MANUAL';
- break;
- case 'NONE':
- $this->prefixMethod = 'NONE';
- break;
- }
- }
-
- /**
- * XML Callback to process start elements. Elements currently
- * processed are: QUERY.
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- $this->currentElement = strtoupper( $tag );
-
- switch( $this->currentElement ) {
- case 'QUERY':
- // Create a new query in a SQL queryset.
- // Ignore this query set if a platform is specified and it's different than the
- // current connection platform.
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- $this->newQuery();
- } else {
- $this->discardQuery();
- }
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
- }
-
- /**
- * XML Callback to process CDATA elements
- */
- function _tag_cdata( &$parser, $cdata ) {
- switch( $this->currentElement ) {
- // Line of queryset SQL data
- case 'QUERY':
- $this->buildQuery( $cdata );
- break;
- default:
-
- }
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- */
- function _tag_close( &$parser, $tag ) {
- $this->currentElement = '';
-
- switch( strtoupper( $tag ) ) {
- case 'QUERY':
- // Add the finished query to the open query set.
- $this->addQuery();
- break;
- case 'SQL':
- $this->parent->addSQL( $this->create( $this->parent ) );
- xml_set_object( $parser, $this->parent );
- $this->destroy();
- break;
- default:
-
- }
- }
-
- /**
- * Re-initializes the query.
- *
- * @return boolean TRUE
- */
- function newQuery() {
- $this->query = '';
-
- return TRUE;
- }
-
- /**
- * Discards the existing query.
- *
- * @return boolean TRUE
- */
- function discardQuery() {
- unset( $this->query );
-
- return TRUE;
- }
-
- /**
- * Appends a line to a query that is being built line by line
- *
- * @param string $data Line of SQL data or NULL to initialize a new query
- * @return string SQL query string.
- */
- function buildQuery( $sql = NULL ) {
- if( !isset( $this->query ) OR empty( $sql ) ) {
- return FALSE;
- }
-
- $this->query .= $sql;
-
- return $this->query;
- }
-
- /**
- * Adds a completed query to the query list
- *
- * @return string SQL of added query
- */
- function addQuery() {
- if( !isset( $this->query ) ) {
- return FALSE;
- }
-
- $this->queries[] = $return = trim($this->query);
-
- unset( $this->query );
-
- return $return;
- }
-
- /**
- * Creates and returns the current query set
- *
- * @param object $xmls adoSchema object
- * @return array Query set
- */
- function create( &$xmls ) {
- foreach( $this->queries as $id => $query ) {
- switch( $this->prefixMethod ) {
- case 'AUTO':
- // Enable auto prefix replacement
-
- // Process object prefix.
- // Evaluate SQL statements to prepend prefix to objects
- $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
- $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
- $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
-
- // SELECT statements aren't working yet
- #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
-
- case 'MANUAL':
- // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
- // If prefixKey is not set, we use the default constant XMLS_PREFIX
- if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
- // Enable prefix override
- $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
- } else {
- // Use default replacement
- $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
- }
- }
-
- $this->queries[$id] = trim( $query );
- }
-
- // Return the query set array
- return $this->queries;
- }
-
- /**
- * Rebuilds the query with the prefix attached to any objects
- *
- * @param string $regex Regex used to add prefix
- * @param string $query SQL query string
- * @param string $prefix Prefix to be appended to tables, indices, etc.
- * @return string Prefixed SQL query string.
- */
- function prefixQuery( $regex, $query, $prefix = NULL ) {
- if( !isset( $prefix ) ) {
- return $query;
- }
-
- if( preg_match( $regex, $query, $match ) ) {
- $preamble = $match[1];
- $postamble = $match[5];
- $objectList = explode( ',', $match[3] );
- // $prefix = $prefix . '_';
-
- $prefixedList = '';
-
- foreach( $objectList as $object ) {
- if( $prefixedList !== '' ) {
- $prefixedList .= ', ';
- }
-
- $prefixedList .= $prefix . trim( $object );
- }
-
- $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
- }
-
- return $query;
- }
-}
-
-/**
-* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements
-*
-* This class is used to load and parse the XML file, to create an array of SQL statements
-* that can be used to build a database, and to build the database using the SQL array.
-*
-* @tutorial getting_started.pkg
-*
-* @author Richard Tango-Lowy & Dan Cech
-* @version $Revision$
-*
-* @package axmls
-*/
-class adoSchema {
-
- /**
- * @var array Array containing SQL queries to generate all objects
- * @access private
- */
- var $sqlArray;
-
- /**
- * @var object ADOdb connection object
- * @access private
- */
- var $db;
-
- /**
- * @var object ADOdb Data Dictionary
- * @access private
- */
- var $dict;
-
- /**
- * @var string Current XML element
- * @access private
- */
- var $currentElement = '';
-
- /**
- * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
- * @access private
- */
- var $upgrade = '';
-
- /**
- * @var string Optional object prefix
- * @access private
- */
- var $objectPrefix = '';
-
- /**
- * @var long Original Magic Quotes Runtime value
- * @access private
- */
- var $mgq;
-
- /**
- * @var long System debug
- * @access private
- */
- var $debug;
-
- /**
- * @var string Regular expression to find schema version
- * @access private
- */
- var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
-
- /**
- * @var string Current schema version
- * @access private
- */
- var $schemaVersion;
-
- /**
- * @var int Success of last Schema execution
- */
- var $success;
-
- /**
- * @var bool Execute SQL inline as it is generated
- */
- var $executeInline;
-
- /**
- * @var bool Continue SQL execution if errors occur
- */
- var $continueOnError;
-
- /**
- * @var int How to handle existing data rows (insert, update, or ignore)
- */
- var $existingData;
-
- /**
- * Creates an adoSchema object
- *
- * Creating an adoSchema object is the first step in processing an XML schema.
- * The only parameter is an ADOdb database connection object, which must already
- * have been created.
- *
- * @param object $db ADOdb database connection object.
- */
- function adoSchema( &$db ) {
- // Initialize the environment
- $this->mgq = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
-
- $this->db =& $db;
- $this->debug = $this->db->debug;
- $this->dict = NewDataDictionary( $this->db );
- $this->sqlArray = array();
- $this->schemaVersion = XMLS_SCHEMA_VERSION;
- $this->executeInline( XMLS_EXECUTE_INLINE );
- $this->continueOnError( XMLS_CONTINUE_ON_ERROR );
- $this->existingData( XMLS_EXISTING_DATA );
- $this->setUpgradeMethod();
- }
-
- /**
- * Sets the method to be used for upgrading an existing database
- *
- * Use this method to specify how existing database objects should be upgraded.
- * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
- * alter each database object directly, REPLACE attempts to rebuild each object
- * from scratch, BEST attempts to determine the best upgrade method for each
- * object, and NONE disables upgrading.
- *
- * This method is not yet used by AXMLS, but exists for backward compatibility.
- * The ALTER method is automatically assumed when the adoSchema object is
- * instantiated; other upgrade methods are not currently supported.
- *
- * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
- * @returns string Upgrade method used
- */
- function SetUpgradeMethod( $method = '' ) {
- if( !is_string( $method ) ) {
- return FALSE;
- }
-
- $method = strtoupper( $method );
-
- // Handle the upgrade methods
- switch( $method ) {
- case 'ALTER':
- $this->upgrade = $method;
- break;
- case 'REPLACE':
- $this->upgrade = $method;
- break;
- case 'BEST':
- $this->upgrade = 'ALTER';
- break;
- case 'NONE':
- $this->upgrade = 'NONE';
- break;
- default:
- // Use default if no legitimate method is passed.
- $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
- }
-
- return $this->upgrade;
- }
-
- /**
- * Specifies how to handle existing data row when there is a unique key conflict.
- *
- * The existingData setting specifies how the parser should handle existing rows
- * when a unique key violation occurs during the insert. This can happen when inserting
- * data into an existing table with one or more primary keys or unique indexes.
- * The existingData method takes one of three options: XMLS_MODE_INSERT attempts
- * to always insert the data as a new row. In the event of a unique key violation,
- * the database will generate an error. XMLS_MODE_UPDATE attempts to update the
- * any existing rows with the new data based upon primary or unique key fields in
- * the schema. If the data row in the schema specifies no unique fields, the row
- * data will be inserted as a new row. XMLS_MODE_IGNORE specifies that any data rows
- * that would result in a unique key violation be ignored; no inserts or updates will
- * take place. For backward compatibility, the default setting is XMLS_MODE_INSERT,
- * but XMLS_MODE_UPDATE will generally be the most appropriate setting.
- *
- * @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE
- * @return int current mode
- */
- function ExistingData( $mode = NULL ) {
- if( is_int( $mode ) ) {
- switch( $mode ) {
- case XMLS_MODE_UPDATE:
- $mode = XMLS_MODE_UPDATE;
- break;
- case XMLS_MODE_IGNORE:
- $mode = XMLS_MODE_IGNORE;
- break;
- case XMLS_MODE_INSERT:
- $mode = XMLS_MODE_INSERT;
- break;
- default:
- $mode = XMLS_EXISITNG_DATA;
- break;
- }
- $this->existingData = $mode;
- }
-
- return $this->existingData;
- }
-
- /**
- * Enables/disables inline SQL execution.
- *
- * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
- * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
- * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
- * to apply the schema to the database.
- *
- * @param bool $mode execute
- * @return bool current execution mode
- *
- * @see ParseSchema(), ExecuteSchema()
- */
- function ExecuteInline( $mode = NULL ) {
- if( is_bool( $mode ) ) {
- $this->executeInline = $mode;
- }
-
- return $this->executeInline;
- }
-
- /**
- * Enables/disables SQL continue on error.
- *
- * Call this method to enable or disable continuation of SQL execution if an error occurs.
- * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
- * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
- * of the schema will continue.
- *
- * @param bool $mode execute
- * @return bool current continueOnError mode
- *
- * @see addSQL(), ExecuteSchema()
- */
- function ContinueOnError( $mode = NULL ) {
- if( is_bool( $mode ) ) {
- $this->continueOnError = $mode;
- }
-
- return $this->continueOnError;
- }
-
- /**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to create the database
- * described. This method automatically converts the schema to the latest
- * axmls schema version.
- * @see ParseSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
- function ParseSchema( $filename, $returnSchema = FALSE ) {
- return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
- }
-
- /**
- * Loads an XML schema from a file and converts it to SQL.
- *
- * Call this method to load the specified schema directly from a file (see
- * the DTD for the proper format) and generate the SQL necessary to create
- * the database described by the schema. Use this method when you are dealing
- * with large schema files. Otherwise, ParseSchema() is faster.
- * This method does not automatically convert the schema to the latest axmls
- * schema version. You must convert the schema manually using either the
- * ConvertSchemaFile() or ConvertSchemaString() method.
- * @see ParseSchema()
- * @see ConvertSchemaFile()
- * @see ConvertSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- *
- * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
- * @see ParseSchema(), ParseSchemaString()
- */
- function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
- // Open the file
- if( !($fp = fopen( $filename, 'r' )) ) {
- logMsg( 'Unable to open file' );
- return FALSE;
- }
-
- // do version detection here
- if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
- logMsg( 'Invalid Schema Version' );
- return FALSE;
- }
-
- if( $returnSchema ) {
- $xmlstring = '';
- while( $data = fread( $fp, 4096 ) ) {
- $xmlstring .= $data . "\n";
- }
- return $xmlstring;
- }
-
- $this->success = 2;
-
- $xmlParser = $this->create_parser();
-
- // Process the file
- while( $data = fread( $fp, 4096 ) ) {
- if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
- die( sprintf(
- "XML error: %s at line %d",
- xml_error_string( xml_get_error_code( $xmlParser) ),
- xml_get_current_line_number( $xmlParser)
- ) );
- }
- }
-
- xml_parser_free( $xmlParser );
-
- return $this->sqlArray;
- }
-
- /**
- * Converts an XML schema string to SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to create the database described by the schema.
- * @see ParseSchema()
- *
- * @param string $xmlstring XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
- function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
- if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
- logMsg( 'Empty or Invalid Schema' );
- return FALSE;
- }
-
- // do version detection here
- if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
- logMsg( 'Invalid Schema Version' );
- return FALSE;
- }
-
- if( $returnSchema ) {
- return $xmlstring;
- }
-
- $this->success = 2;
-
- $xmlParser = $this->create_parser();
-
- if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
- die( sprintf(
- "XML error: %s at line %d",
- xml_error_string( xml_get_error_code( $xmlParser) ),
- xml_get_current_line_number( $xmlParser)
- ) );
- }
-
- xml_parser_free( $xmlParser );
-
- return $this->sqlArray;
- }
-
- /**
- * Loads an XML schema from a file and converts it to uninstallation SQL.
- *
- * Call this method to load the specified schema (see the DTD for the proper format) from
- * the filesystem and generate the SQL necessary to remove the database described.
- * @see RemoveSchemaString()
- *
- * @param string $file Name of XML schema file.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute
- */
- function RemoveSchema( $filename, $returnSchema = FALSE ) {
- return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
- }
-
- /**
- * Converts an XML schema string to uninstallation SQL.
- *
- * Call this method to parse a string containing an XML schema (see the DTD for the proper format)
- * and generate the SQL necessary to uninstall the database described by the schema.
- * @see RemoveSchema()
- *
- * @param string $schema XML schema string.
- * @param bool $returnSchema Return schema rather than parsing.
- * @return array Array of SQL queries, ready to execute.
- */
- function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
-
- // grab current version
- if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
- return FALSE;
- }
-
- return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
- }
-
- /**
- * Applies the current XML schema to the database (post execution).
- *
- * Call this method to apply the current schema (generally created by calling
- * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
- * and executing other SQL specified in the schema) after parsing.
- * @see ParseSchema(), ParseSchemaString(), ExecuteInline()
- *
- * @param array $sqlArray Array of SQL statements that will be applied rather than
- * the current schema.
- * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
- * @returns integer 0 if failure, 1 if errors, 2 if successful.
- */
- function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
- if( !is_bool( $continueOnErr ) ) {
- $continueOnErr = $this->ContinueOnError();
- }
-
- if( !isset( $sqlArray ) ) {
- $sqlArray = $this->sqlArray;
- }
-
- if( !is_array( $sqlArray ) ) {
- $this->success = 0;
- } else {
- $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
- }
-
- return $this->success;
- }
-
- /**
- * Returns the current SQL array.
- *
- * Call this method to fetch the array of SQL queries resulting from
- * ParseSchema() or ParseSchemaString().
- *
- * @param string $format Format: HTML, TEXT, or NONE (PHP array)
- * @return array Array of SQL statements or FALSE if an error occurs
- */
- function PrintSQL( $format = 'NONE' ) {
- $sqlArray = null;
- return $this->getSQL( $format, $sqlArray );
- }
-
- /**
- * Saves the current SQL array to the local filesystem as a list of SQL queries.
- *
- * Call this method to save the array of SQL queries (generally resulting from a
- * parsed XML schema) to the filesystem.
- *
- * @param string $filename Path and name where the file should be saved.
- * @return boolean TRUE if save is successful, else FALSE.
- */
- function SaveSQL( $filename = './schema.sql' ) {
-
- if( !isset( $sqlArray ) ) {
- $sqlArray = $this->sqlArray;
- }
- if( !isset( $sqlArray ) ) {
- return FALSE;
- }
-
- $fp = fopen( $filename, "w" );
-
- foreach( $sqlArray as $key => $query ) {
- fwrite( $fp, $query . ";\n" );
- }
- fclose( $fp );
- }
-
- /**
- * Create an xml parser
- *
- * @return object PHP XML parser object
- *
- * @access private
- */
- function &create_parser() {
- // Create the parser
- $xmlParser = xml_parser_create();
- xml_set_object( $xmlParser, $this );
-
- // Initialize the XML callback functions
- xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
- xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
-
- return $xmlParser;
- }
-
- /**
- * XML Callback to process start elements
- *
- * @access private
- */
- function _tag_open( &$parser, $tag, $attributes ) {
- switch( strtoupper( $tag ) ) {
- case 'TABLE':
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- $this->obj = new dbTable( $this, $attributes );
- xml_set_object( $parser, $this->obj );
- }
- break;
- case 'SQL':
- if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
- $this->obj = new dbQuerySet( $this, $attributes );
- xml_set_object( $parser, $this->obj );
- }
- break;
- default:
- // print_r( array( $tag, $attributes ) );
- }
-
- }
-
- /**
- * XML Callback to process CDATA elements
- *
- * @access private
- */
- function _tag_cdata( &$parser, $cdata ) {
- }
-
- /**
- * XML Callback to process end elements
- *
- * @access private
- * @internal
- */
- function _tag_close( &$parser, $tag ) {
-
- }
-
- /**
- * Converts an XML schema string to the specified DTD version.
- *
- * Call this method to convert a string containing an XML schema to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see ConvertSchemaFile()
- *
- * @param string $schema String containing XML schema that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
- function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
-
- // grab current version
- if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
- return FALSE;
- }
-
- if( !isset ($newVersion) ) {
- $newVersion = $this->schemaVersion;
- }
-
- if( $version == $newVersion ) {
- $result = $schema;
- } else {
- $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
- }
-
- if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
- fwrite( $fp, $result );
- fclose( $fp );
- }
-
- return $result;
- }
-
- /*
- // compat for pre-4.3 - jlim
- function _file_get_contents($path)
- {
- if (function_exists('file_get_contents')) return file_get_contents($path);
- return join('',file($path));
- }*/
-
- /**
- * Converts an XML schema file to the specified DTD version.
- *
- * Call this method to convert the specified XML schema file to a different AXMLS
- * DTD version. For instance, to convert a schema created for an pre-1.0 version for
- * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version
- * parameter is specified, the schema will be converted to the current DTD version.
- * If the newFile parameter is provided, the converted schema will be written to the specified
- * file.
- * @see ConvertSchemaString()
- *
- * @param string $filename Name of XML schema file that will be converted.
- * @param string $newVersion DTD version to convert to.
- * @param string $newFile File name of (converted) output file.
- * @return string Converted XML schema or FALSE if an error occurs.
- */
- function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
-
- // grab current version
- if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
- return FALSE;
- }
-
- if( !isset ($newVersion) ) {
- $newVersion = $this->schemaVersion;
- }
-
- if( $version == $newVersion ) {
- $result = _file_get_contents( $filename );
-
- // remove unicode BOM if present
- if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
- $result = substr( $result, 3 );
- }
- } else {
- $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
- }
-
- if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
- fwrite( $fp, $result );
- fclose( $fp );
- }
-
- return $result;
- }
-
- function TransformSchema( $schema, $xsl, $schematype='string' )
- {
- // Fail if XSLT extension is not available
- if( ! function_exists( 'xslt_create' ) ) {
- return FALSE;
- }
-
- $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
-
- // look for xsl
- if( !is_readable( $xsl_file ) ) {
- return FALSE;
- }
-
- switch( $schematype )
- {
- case 'file':
- if( !is_readable( $schema ) ) {
- return FALSE;
- }
-
- $schema = _file_get_contents( $schema );
- break;
- case 'string':
- default:
- if( !is_string( $schema ) ) {
- return FALSE;
- }
- }
-
- $arguments = array (
- '/_xml' => $schema,
- '/_xsl' => _file_get_contents( $xsl_file )
- );
-
- // create an XSLT processor
- $xh = xslt_create ();
-
- // set error handler
- xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
-
- // process the schema
- $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
-
- xslt_free ($xh);
-
- return $result;
- }
-
- /**
- * Processes XSLT transformation errors
- *
- * @param object $parser XML parser object
- * @param integer $errno Error number
- * @param integer $level Error level
- * @param array $fields Error information fields
- *
- * @access private
- */
- function xslt_error_handler( $parser, $errno, $level, $fields ) {
- if( is_array( $fields ) ) {
- $msg = array(
- 'Message Type' => ucfirst( $fields['msgtype'] ),
- 'Message Code' => $fields['code'],
- 'Message' => $fields['msg'],
- 'Error Number' => $errno,
- 'Level' => $level
- );
-
- switch( $fields['URI'] ) {
- case 'arg:/_xml':
- $msg['Input'] = 'XML';
- break;
- case 'arg:/_xsl':
- $msg['Input'] = 'XSL';
- break;
- default:
- $msg['Input'] = $fields['URI'];
- }
-
- $msg['Line'] = $fields['line'];
- } else {
- $msg = array(
- 'Message Type' => 'Error',
- 'Error Number' => $errno,
- 'Level' => $level,
- 'Fields' => var_export( $fields, TRUE )
- );
- }
-
- $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
- . '<table>' . "\n";
-
- foreach( $msg as $label => $details ) {
- $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
- }
-
- $error_details .= '</table>';
-
- trigger_error( $error_details, E_USER_ERROR );
- }
-
- /**
- * Returns the AXMLS Schema Version of the requested XML schema file.
- *
- * Call this method to obtain the AXMLS DTD version of the requested XML schema file.
- * @see SchemaStringVersion()
- *
- * @param string $filename AXMLS schema file
- * @return string Schema version number or FALSE on error
- */
- function SchemaFileVersion( $filename ) {
- // Open the file
- if( !($fp = fopen( $filename, 'r' )) ) {
- // die( 'Unable to open file' );
- return FALSE;
- }
-
- // Process the file
- while( $data = fread( $fp, 4096 ) ) {
- if( preg_match( $this->versionRegex, $data, $matches ) ) {
- return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
- }
- }
-
- return FALSE;
- }
-
- /**
- * Returns the AXMLS Schema Version of the provided XML schema string.
- *
- * Call this method to obtain the AXMLS DTD version of the provided XML schema string.
- * @see SchemaFileVersion()
- *
- * @param string $xmlstring XML schema string
- * @return string Schema version number or FALSE on error
- */
- function SchemaStringVersion( $xmlstring ) {
- if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
- return FALSE;
- }
-
- if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
- return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
- }
-
- return FALSE;
- }
-
- /**
- * Extracts an XML schema from an existing database.
- *
- * Call this method to create an XML schema string from an existing database.
- * If the data parameter is set to TRUE, AXMLS will include the data from the database
- * in the schema.
- *
- * @param boolean $data Include data in schema dump
- * @indent string indentation to use
- * @prefix string extract only tables with given prefix
- * @stripprefix strip prefix string when storing in XML schema
- * @return string Generated XML schema
- */
- function ExtractSchema( $data = FALSE, $indent = ' ', $prefix = '' , $stripprefix=false) {
- $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
-
- $schema = '<?xml version="1.0"?>' . "\n"
- . '<schema version="' . $this->schemaVersion . '">' . "\n";
-
- if( is_array( $tables = $this->db->MetaTables( 'TABLES' , ($prefix) ? $prefix.'%' : '') ) ) {
- foreach( $tables as $table ) {
- if ($stripprefix) $table = str_replace(str_replace('\\_', '_', $pfx ), '', $table);
- $schema .= $indent . '<table name="' . htmlentities( $table ) . '">' . "\n";
-
- // grab details from database
- $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE -1' );
- $fields = $this->db->MetaColumns( $table );
- $indexes = $this->db->MetaIndexes( $table );
-
- if( is_array( $fields ) ) {
- foreach( $fields as $details ) {
- $extra = '';
- $content = array();
-
- if( isset($details->max_length) && $details->max_length > 0 ) {
- $extra .= ' size="' . $details->max_length . '"';
- }
-
- if( isset($details->primary_key) && $details->primary_key ) {
- $content[] = '<KEY/>';
- } elseif( isset($details->not_null) && $details->not_null ) {
- $content[] = '<NOTNULL/>';
- }
-
- if( isset($details->has_default) && $details->has_default ) {
- $content[] = '<DEFAULT value="' . htmlentities( $details->default_value ) . '"/>';
- }
-
- if( isset($details->auto_increment) && $details->auto_increment ) {
- $content[] = '<AUTOINCREMENT/>';
- }
-
- if( isset($details->unsigned) && $details->unsigned ) {
- $content[] = '<UNSIGNED/>';
- }
-
- // this stops the creation of 'R' columns,
- // AUTOINCREMENT is used to create auto columns
- $details->primary_key = 0;
- $type = $rs->MetaType( $details );
-
- $schema .= str_repeat( $indent, 2 ) . '<field name="' . htmlentities( $details->name ) . '" type="' . $type . '"' . $extra;
-
- if( !empty( $content ) ) {
- $schema .= ">\n" . str_repeat( $indent, 3 )
- . implode( "\n" . str_repeat( $indent, 3 ), $content ) . "\n"
- . str_repeat( $indent, 2 ) . '</field>' . "\n";
- } else {
- $schema .= "/>\n";
- }
- }
- }
-
- if( is_array( $indexes ) ) {
- foreach( $indexes as $index => $details ) {
- $schema .= str_repeat( $indent, 2 ) . '<index name="' . $index . '">' . "\n";
-
- if( $details['unique'] ) {
- $schema .= str_repeat( $indent, 3 ) . '<UNIQUE/>' . "\n";
- }
-
- foreach( $details['columns'] as $column ) {
- $schema .= str_repeat( $indent, 3 ) . '<col>' . htmlentities( $column ) . '</col>' . "\n";
- }
-
- $schema .= str_repeat( $indent, 2 ) . '</index>' . "\n";
- }
- }
-
- if( $data ) {
- $rs = $this->db->Execute( 'SELECT * FROM ' . $table );
-
- if( is_object( $rs ) && !$rs->EOF ) {
- $schema .= str_repeat( $indent, 2 ) . "<data>\n";
-
- while( $row = $rs->FetchRow() ) {
- foreach( $row as $key => $val ) {
- if ( $val != htmlentities( $val ) ) {
- $row[$key] = '<![CDATA[' . $val . ']]>';
- }
- }
-
- $schema .= str_repeat( $indent, 3 ) . '<row><f>' . implode( '</f><f>', $row ) . "</f></row>\n";
- }
-
- $schema .= str_repeat( $indent, 2 ) . "</data>\n";
- }
- }
-
- $schema .= $indent . "</table>\n";
- }
- }
-
- $this->db->SetFetchMode( $old_mode );
-
- $schema .= '</schema>';
- return $schema;
- }
-
- /**
- * Sets a prefix for database objects
- *
- * Call this method to set a standard prefix that will be prepended to all database tables
- * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.
- *
- * @param string $prefix Prefix that will be prepended.
- * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.
- * @return boolean TRUE if successful, else FALSE
- */
- function SetPrefix( $prefix = '', $underscore = TRUE ) {
- switch( TRUE ) {
- // clear prefix
- case empty( $prefix ):
- logMsg( 'Cleared prefix' );
- $this->objectPrefix = '';
- return TRUE;
- // prefix too long
- case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
- // prefix contains invalid characters
- case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
- logMsg( 'Invalid prefix: ' . $prefix );
- return FALSE;
- }
-
- if( $underscore AND substr( $prefix, -1 ) != '_' ) {
- $prefix .= '_';
- }
-
- // prefix valid
- logMsg( 'Set prefix: ' . $prefix );
- $this->objectPrefix = $prefix;
- return TRUE;
- }
-
- /**
- * Returns an object name with the current prefix prepended.
- *
- * @param string $name Name
- * @return string Prefixed name
- *
- * @access private
- */
- function prefix( $name = '' ) {
- // if prefix is set
- if( !empty( $this->objectPrefix ) ) {
- // Prepend the object prefix to the table name
- // prepend after quote if used
- return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
- }
-
- // No prefix set. Use name provided.
- return $name;
- }
-
- /**
- * Checks if element references a specific platform
- *
- * @param string $platform Requested platform
- * @returns boolean TRUE if platform check succeeds
- *
- * @access private
- */
- function supportedPlatform( $platform = NULL ) {
- if( !empty( $platform ) ) {
- $regex = '/(^|\|)' . $this->db->databaseType . '(\||$)/i';
-
- if( preg_match( '/^- /', $platform ) ) {
- if (preg_match ( $regex, substr( $platform, 2 ) ) ) {
- logMsg( 'Platform ' . $platform . ' is NOT supported' );
- return FALSE;
- }
- } else {
- if( !preg_match ( $regex, $platform ) ) {
- logMsg( 'Platform ' . $platform . ' is NOT supported' );
- return FALSE;
- }
- }
- }
-
- logMsg( 'Platform ' . $platform . ' is supported' );
- return TRUE;
- }
-
- /**
- * Clears the array of generated SQL.
- *
- * @access private
- */
- function clearSQL() {
- $this->sqlArray = array();
- }
-
- /**
- * Adds SQL into the SQL array.
- *
- * @param mixed $sql SQL to Add
- * @return boolean TRUE if successful, else FALSE.
- *
- * @access private
- */
- function addSQL( $sql = NULL ) {
- if( is_array( $sql ) ) {
- foreach( $sql as $line ) {
- $this->addSQL( $line );
- }
-
- return TRUE;
- }
-
- if( is_string( $sql ) ) {
- $this->sqlArray[] = $sql;
-
- // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
- if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
- $saved = $this->db->debug;
- $this->db->debug = $this->debug;
- $ok = $this->db->Execute( $sql );
- $this->db->debug = $saved;
-
- if( !$ok ) {
- if( $this->debug ) {
- ADOConnection::outp( $this->db->ErrorMsg() );
- }
-
- $this->success = 1;
- }
- }
-
- return TRUE;
- }
-
- return FALSE;
- }
-
- /**
- * Gets the SQL array in the specified format.
- *
- * @param string $format Format
- * @return mixed SQL
- *
- * @access private
- */
- function getSQL( $format = NULL, $sqlArray = NULL ) {
- if( !is_array( $sqlArray ) ) {
- $sqlArray = $this->sqlArray;
- }
-
- if( !is_array( $sqlArray ) ) {
- return FALSE;
- }
-
- switch( strtolower( $format ) ) {
- case 'string':
- case 'text':
- return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
- case'html':
- return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
- }
-
- return $this->sqlArray;
- }
-
- /**
- * Destroys an adoSchema object.
- *
- * Call this method to clean up after an adoSchema object that is no longer in use.
- * @deprecated adoSchema now cleans up automatically.
- */
- function Destroy() {
- set_magic_quotes_runtime( $this->mgq );
- unset( $this );
- }
-}
-
-/**
-* Message logging function
-*
-* @access private
-*/
-function logMsg( $msg, $title = NULL, $force = FALSE ) {
- if( XMLS_DEBUG or $force ) {
- echo '<pre>';
-
- if( isset( $title ) ) {
- echo '<h3>' . htmlentities( $title ) . '</h3>';
- }
-
- if( @is_object( $this ) ) {
- echo '[' . get_class( $this ) . '] ';
- }
-
- print_r( $msg );
-
- echo '</pre>';
- }
-}
+<?php\r
+// Copyright (c) 2004-2005 ars Cognita Inc., all rights reserved\r
+/* ******************************************************************************\r
+ Released under both BSD license and Lesser GPL library license. \r
+ Whenever there is any discrepancy between the two licenses, \r
+ the BSD license will take precedence. \r
+*******************************************************************************/\r
+/**\r
+ * xmlschema is a class that allows the user to quickly and easily\r
+ * build a database on any ADOdb-supported platform using a simple\r
+ * XML schema.\r
+ *\r
+ * Last Editor: $Author$\r
+ * @author Richard Tango-Lowy & Dan Cech\r
+ * @version $Revision$\r
+ *\r
+ * @package axmls\r
+ * @tutorial getting_started.pkg\r
+ */\r
+ \r
+function _file_get_contents($file) \r
+{\r
+ if (function_exists('file_get_contents')) return file_get_contents($file);\r
+ \r
+ $f = fopen($file,'r');\r
+ if (!$f) return '';\r
+ $t = '';\r
+ \r
+ while ($s = fread($f,100000)) $t .= $s;\r
+ fclose($f);\r
+ return $t;\r
+}\r
+\r
+\r
+/**\r
+* Debug on or off\r
+*/\r
+if( !defined( 'XMLS_DEBUG' ) ) {\r
+ define( 'XMLS_DEBUG', FALSE );\r
+}\r
+\r
+/**\r
+* Default prefix key\r
+*/\r
+if( !defined( 'XMLS_PREFIX' ) ) {\r
+ define( 'XMLS_PREFIX', '%%P' );\r
+}\r
+\r
+/**\r
+* Maximum length allowed for object prefix\r
+*/\r
+if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {\r
+ define( 'XMLS_PREFIX_MAXLEN', 10 );\r
+}\r
+\r
+/**\r
+* Execute SQL inline as it is generated\r
+*/\r
+if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {\r
+ define( 'XMLS_EXECUTE_INLINE', FALSE );\r
+}\r
+\r
+/**\r
+* Continue SQL Execution if an error occurs?\r
+*/\r
+if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {\r
+ define( 'XMLS_CONTINUE_ON_ERROR', FALSE );\r
+}\r
+\r
+/**\r
+* Current Schema Version\r
+*/\r
+if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {\r
+ define( 'XMLS_SCHEMA_VERSION', '0.3' );\r
+}\r
+\r
+/**\r
+* Default Schema Version. Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {\r
+ define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );\r
+}\r
+\r
+/**\r
+* How to handle data rows that already exist in a database during and upgrade.\r
+* Options are INSERT (attempts to insert duplicate rows), UPDATE (updates existing\r
+* rows) and IGNORE (ignores existing rows).\r
+*/\r
+if( !defined( 'XMLS_MODE_INSERT' ) ) {\r
+ define( 'XMLS_MODE_INSERT', 0 );\r
+}\r
+if( !defined( 'XMLS_MODE_UPDATE' ) ) {\r
+ define( 'XMLS_MODE_UPDATE', 1 );\r
+}\r
+if( !defined( 'XMLS_MODE_IGNORE' ) ) {\r
+ define( 'XMLS_MODE_IGNORE', 2 );\r
+}\r
+if( !defined( 'XMLS_EXISTING_DATA' ) ) {\r
+ define( 'XMLS_EXISTING_DATA', XMLS_MODE_INSERT );\r
+}\r
+\r
+/**\r
+* Default Schema Version. Used for Schemas without an explicit version set.\r
+*/\r
+if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {\r
+ define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );\r
+}\r
+\r
+/**\r
+* Include the main ADODB library\r
+*/\r
+if( !defined( '_ADODB_LAYER' ) ) {\r
+ require( 'adodb.inc.php' );\r
+ require( 'adodb-datadict.inc.php' );\r
+}\r
+\r
+/**\r
+* Abstract DB Object. This class provides basic methods for database objects, such\r
+* as tables and indexes.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbObject {\r
+ \r
+ /**\r
+ * var object Parent\r
+ */\r
+ var $parent;\r
+ \r
+ /**\r
+ * var string current element\r
+ */\r
+ var $currentElement;\r
+ \r
+ /**\r
+ * NOP\r
+ */\r
+ function dbObject( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ \r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ \r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ \r
+ }\r
+ \r
+ function create() {\r
+ return array();\r
+ }\r
+ \r
+ /**\r
+ * Destroys the object\r
+ */\r
+ function destroy() {\r
+ unset( $this );\r
+ }\r
+ \r
+ /**\r
+ * Checks whether the specified RDBMS is supported by the current\r
+ * database object or its ranking ancestor.\r
+ *\r
+ * @param string $platform RDBMS platform name (from ADODB platform list).\r
+ * @return boolean TRUE if RDBMS is supported; otherwise returns FALSE.\r
+ */\r
+ function supportedPlatform( $platform = NULL ) {\r
+ return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Returns the prefix set by the ranking ancestor of the database object.\r
+ *\r
+ * @param string $name Prefix string.\r
+ * @return string Prefix.\r
+ */\r
+ function prefix( $name = '' ) {\r
+ return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;\r
+ }\r
+ \r
+ /**\r
+ * Extracts a field ID from the specified field.\r
+ *\r
+ * @param string $field Field.\r
+ * @return string Field ID.\r
+ */\r
+ function FieldID( $field ) {\r
+ return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );\r
+ }\r
+}\r
+\r
+/**\r
+* Creates a table object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database table. As charactaristics\r
+* of the table are loaded from the external source, methods and properties\r
+* of this class are used to build up the table description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbTable extends dbObject {\r
+ \r
+ /**\r
+ * @var string Table name\r
+ */\r
+ var $name;\r
+ \r
+ /**\r
+ * @var array Field specifier: Meta-information about each field\r
+ */\r
+ var $fields = array();\r
+ \r
+ /**\r
+ * @var array List of table indexes.\r
+ */\r
+ var $indexes = array();\r
+ \r
+ /**\r
+ * @var array Table options: Table-level options\r
+ */\r
+ var $opts = array();\r
+ \r
+ /**\r
+ * @var string Field index: Keeps track of which field is currently being processed\r
+ */\r
+ var $current_field;\r
+ \r
+ /**\r
+ * @var boolean Mark table for destruction\r
+ * @access private\r
+ */\r
+ var $drop_table;\r
+ \r
+ /**\r
+ * @var boolean Mark field for destruction (not yet implemented)\r
+ * @access private\r
+ */\r
+ var $drop_field = array();\r
+ \r
+ /**\r
+ * @var array Platform-specific options\r
+ * @access private\r
+ */\r
+ var $currentPlatform = true;\r
+ \r
+ \r
+ /**\r
+ * Iniitializes a new table object.\r
+ *\r
+ * @param string $prefix DB Object prefix\r
+ * @param array $attributes Array of table attributes.\r
+ */\r
+ function dbTable( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ $this->name = $this->prefix($attributes['NAME']);\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements. Elements currently \r
+ * processed are: INDEX, DROP, FIELD, KEY, NOTNULL, AUTOINCREMENT & DEFAULT. \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'INDEX':\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ xml_set_object( $parser, $this->addIndex( $attributes ) );\r
+ }\r
+ break;\r
+ case 'DATA':\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ xml_set_object( $parser, $this->addData( $attributes ) );\r
+ }\r
+ break;\r
+ case 'DROP':\r
+ $this->drop();\r
+ break;\r
+ case 'FIELD':\r
+ // Add a field\r
+ $fieldName = $attributes['NAME'];\r
+ $fieldType = $attributes['TYPE'];\r
+ $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;\r
+ $fieldOpts = !empty( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;\r
+ \r
+ $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );\r
+ break;\r
+ case 'KEY':\r
+ case 'NOTNULL':\r
+ case 'AUTOINCREMENT':\r
+ case 'DEFDATE':\r
+ case 'DEFTIMESTAMP':\r
+ case 'UNSIGNED':\r
+ // Add a field option\r
+ $this->addFieldOpt( $this->current_field, $this->currentElement );\r
+ break;\r
+ case 'DEFAULT':\r
+ // Add a field option to the table object\r
+ \r
+ // Work around ADOdb datadict issue that misinterprets empty strings.\r
+ if( $attributes['VALUE'] == '' ) {\r
+ $attributes['VALUE'] = " '' ";\r
+ }\r
+ \r
+ $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );\r
+ break;\r
+ case 'OPT':\r
+ case 'CONSTRAINT':\r
+ // Accept platform-specific options\r
+ $this->currentPlatform = ( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) );\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Table/field constraint\r
+ case 'CONSTRAINT':\r
+ if( isset( $this->current_field ) ) {\r
+ $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );\r
+ } else {\r
+ $this->addTableOpt( $cdata );\r
+ }\r
+ break;\r
+ // Table/field option\r
+ case 'OPT':\r
+ if( isset( $this->current_field ) ) {\r
+ $this->addFieldOpt( $this->current_field, $cdata );\r
+ } else {\r
+ $this->addTableOpt( $cdata );\r
+ }\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'TABLE':\r
+ $this->parent->addSQL( $this->create( $this->parent ) );\r
+ xml_set_object( $parser, $this->parent );\r
+ $this->destroy();\r
+ break;\r
+ case 'FIELD':\r
+ unset($this->current_field);\r
+ break;\r
+ case 'OPT':\r
+ case 'CONSTRAINT':\r
+ $this->currentPlatform = true;\r
+ break;\r
+ default:\r
+\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds an index to a table object\r
+ *\r
+ * @param array $attributes Index attributes\r
+ * @return object dbIndex object\r
+ */\r
+ function addIndex( $attributes ) {\r
+ $name = strtoupper( $attributes['NAME'] );\r
+ $this->indexes[$name] = new dbIndex( $this, $attributes );\r
+ return $this->indexes[$name];\r
+ }\r
+ \r
+ /**\r
+ * Adds data to a table object\r
+ *\r
+ * @param array $attributes Data attributes\r
+ * @return object dbData object\r
+ */\r
+ function addData( $attributes ) {\r
+ if( !isset( $this->data ) ) {\r
+ $this->data = new dbData( $this, $attributes );\r
+ }\r
+ return $this->data;\r
+ }\r
+ \r
+ /**\r
+ * Adds a field to a table object\r
+ *\r
+ * $name is the name of the table to which the field should be added. \r
+ * $type is an ADODB datadict field type. The following field types\r
+ * are supported as of ADODB 3.40:\r
+ * - C: varchar\r
+ * - X: CLOB (character large object) or largest varchar size\r
+ * if CLOB is not supported\r
+ * - C2: Multibyte varchar\r
+ * - X2: Multibyte CLOB\r
+ * - B: BLOB (binary large object)\r
+ * - D: Date (some databases do not support this, and we return a datetime type)\r
+ * - T: Datetime or Timestamp\r
+ * - L: Integer field suitable for storing booleans (0 or 1)\r
+ * - I: Integer (mapped to I4)\r
+ * - I1: 1-byte integer\r
+ * - I2: 2-byte integer\r
+ * - I4: 4-byte integer\r
+ * - I8: 8-byte integer\r
+ * - F: Floating point number\r
+ * - N: Numeric or decimal number\r
+ *\r
+ * @param string $name Name of the table to which the field will be added.\r
+ * @param string $type ADODB datadict field type.\r
+ * @param string $size Field size\r
+ * @param array $opts Field options array\r
+ * @return array Field specifier array\r
+ */\r
+ function addField( $name, $type, $size = NULL, $opts = NULL ) {\r
+ $field_id = $this->FieldID( $name );\r
+ \r
+ // Set the field index so we know where we are\r
+ $this->current_field = $field_id;\r
+ \r
+ // Set the field name (required)\r
+ $this->fields[$field_id]['NAME'] = $name;\r
+ \r
+ // Set the field type (required)\r
+ $this->fields[$field_id]['TYPE'] = $type;\r
+ \r
+ // Set the field size (optional)\r
+ if( isset( $size ) ) {\r
+ $this->fields[$field_id]['SIZE'] = $size;\r
+ }\r
+ \r
+ // Set the field options\r
+ if( isset( $opts ) ) {\r
+ $this->fields[$field_id]['OPTS'] = array($opts);\r
+ } else {\r
+ $this->fields[$field_id]['OPTS'] = array();\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds a field option to the current field specifier\r
+ *\r
+ * This method adds a field option allowed by the ADOdb datadict \r
+ * and appends it to the given field.\r
+ *\r
+ * @param string $field Field name\r
+ * @param string $opt ADOdb field option\r
+ * @param mixed $value Field option value\r
+ * @return array Field specifier array\r
+ */\r
+ function addFieldOpt( $field, $opt, $value = NULL ) {\r
+ if( $this->currentPlatform ) {\r
+ if( !isset( $value ) ) {\r
+ $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;\r
+ // Add the option and value\r
+ } else {\r
+ $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );\r
+ }\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds an option to the table\r
+ *\r
+ * This method takes a comma-separated list of table-level options\r
+ * and appends them to the table object.\r
+ *\r
+ * @param string $opt Table option\r
+ * @return array Options\r
+ */\r
+ function addTableOpt( $opt ) {\r
+ if( $this->currentPlatform ) {\r
+ $this->opts[] = $opt;\r
+ }\r
+ return $this->opts;\r
+ }\r
+ \r
+ /**\r
+ * Generates the SQL that will create the table in the database\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Array containing table creation SQL\r
+ */\r
+ function create( &$xmls ) {\r
+ $sql = array();\r
+ \r
+ // drop any existing indexes\r
+ if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {\r
+ foreach( $legacy_indexes as $index => $index_details ) {\r
+ $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );\r
+ }\r
+ }\r
+ \r
+ // remove fields to be dropped from table object\r
+ foreach( $this->drop_field as $field ) {\r
+ unset( $this->fields[$field] );\r
+ }\r
+ \r
+ // if table exists\r
+ if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {\r
+ // drop table\r
+ if( $this->drop_table ) {\r
+ $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+ \r
+ return $sql;\r
+ }\r
+ \r
+ // drop any existing fields not in schema\r
+ foreach( $legacy_fields as $field_id => $field ) {\r
+ if( !isset( $this->fields[$field_id] ) ) {\r
+ $sql[] = $xmls->dict->DropColumnSQL( $this->name, $field->name );\r
+ }\r
+ }\r
+ // if table doesn't exist\r
+ } else {\r
+ if( $this->drop_table ) {\r
+ return $sql;\r
+ }\r
+ \r
+ $legacy_fields = array();\r
+ }\r
+ \r
+ // Loop through the field specifier array, building the associative array for the field options\r
+ $fldarray = array();\r
+ \r
+ foreach( $this->fields as $field_id => $finfo ) {\r
+ // Set an empty size if it isn't supplied\r
+ if( !isset( $finfo['SIZE'] ) ) {\r
+ $finfo['SIZE'] = '';\r
+ }\r
+ \r
+ // Initialize the field array with the type and size\r
+ $fldarray[$field_id] = array(\r
+ 'NAME' => $finfo['NAME'],\r
+ 'TYPE' => $finfo['TYPE'],\r
+ 'SIZE' => $finfo['SIZE']\r
+ );\r
+ \r
+ // Loop through the options array and add the field options. \r
+ if( isset( $finfo['OPTS'] ) ) {\r
+ foreach( $finfo['OPTS'] as $opt ) {\r
+ // Option has an argument.\r
+ if( is_array( $opt ) ) {\r
+ $key = key( $opt );\r
+ $value = $opt[key( $opt )];\r
+ @$fldarray[$field_id][$key] .= $value;\r
+ // Option doesn't have arguments\r
+ } else {\r
+ $fldarray[$field_id][$opt] = $opt;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ if( empty( $legacy_fields ) ) {\r
+ // Create the new table\r
+ $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+ logMsg( end( $sql ), 'Generated CreateTableSQL' );\r
+ } else {\r
+ // Upgrade an existing table\r
+ logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );\r
+ switch( $xmls->upgrade ) {\r
+ // Use ChangeTableSQL\r
+ case 'ALTER':\r
+ logMsg( 'Generated ChangeTableSQL (ALTERing table)' );\r
+ $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );\r
+ break;\r
+ case 'REPLACE':\r
+ logMsg( 'Doing upgrade REPLACE (testing)' );\r
+ $sql[] = $xmls->dict->DropTableSQL( $this->name );\r
+ $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );\r
+ break;\r
+ // ignore table\r
+ default:\r
+ return array();\r
+ }\r
+ }\r
+ \r
+ foreach( $this->indexes as $index ) {\r
+ $sql[] = $index->create( $xmls );\r
+ }\r
+ \r
+ if( isset( $this->data ) ) {\r
+ $sql[] = $this->data->create( $xmls );\r
+ }\r
+ \r
+ return $sql;\r
+ }\r
+ \r
+ /**\r
+ * Marks a field or table for destruction\r
+ */\r
+ function drop() {\r
+ if( isset( $this->current_field ) ) {\r
+ // Drop the current field\r
+ logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );\r
+ // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );\r
+ $this->drop_field[$this->current_field] = $this->current_field;\r
+ } else {\r
+ // Drop the current table\r
+ logMsg( "Dropping table '{$this->name}'" );\r
+ // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );\r
+ $this->drop_table = TRUE;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+* Creates an index object in ADOdb's datadict format\r
+*\r
+* This class stores information about a database index. As charactaristics\r
+* of the index are loaded from the external source, methods and properties\r
+* of this class are used to build up the index description in ADOdb's\r
+* datadict format.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbIndex extends dbObject {\r
+ \r
+ /**\r
+ * @var string Index name\r
+ */\r
+ var $name;\r
+ \r
+ /**\r
+ * @var array Index options: Index-level options\r
+ */\r
+ var $opts = array();\r
+ \r
+ /**\r
+ * @var array Indexed fields: Table columns included in this index\r
+ */\r
+ var $columns = array();\r
+ \r
+ /**\r
+ * @var boolean Mark index for destruction\r
+ * @access private\r
+ */\r
+ var $drop = FALSE;\r
+ \r
+ /**\r
+ * Initializes the new dbIndex object.\r
+ *\r
+ * @param object $parent Parent object\r
+ * @param array $attributes Attributes\r
+ *\r
+ * @internal\r
+ */\r
+ function dbIndex( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ \r
+ $this->name = $this->prefix ($attributes['NAME']);\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * Processes XML opening tags. \r
+ * Elements currently processed are: DROP, CLUSTERED, BITMAP, UNIQUE, FULLTEXT & HASH. \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'DROP':\r
+ $this->drop();\r
+ break;\r
+ case 'CLUSTERED':\r
+ case 'BITMAP':\r
+ case 'UNIQUE':\r
+ case 'FULLTEXT':\r
+ case 'HASH':\r
+ // Add index Option\r
+ $this->addIndexOpt( $this->currentElement );\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * Processes XML cdata.\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Index field name\r
+ case 'COL':\r
+ $this->addField( $cdata );\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'INDEX':\r
+ xml_set_object( $parser, $this->parent );\r
+ break;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds a field to the index\r
+ *\r
+ * @param string $name Field name\r
+ * @return string Field list\r
+ */\r
+ function addField( $name ) {\r
+ $this->columns[$this->FieldID( $name )] = $name;\r
+ \r
+ // Return the field list\r
+ return $this->columns;\r
+ }\r
+ \r
+ /**\r
+ * Adds options to the index\r
+ *\r
+ * @param string $opt Comma-separated list of index options.\r
+ * @return string Option list\r
+ */\r
+ function addIndexOpt( $opt ) {\r
+ $this->opts[] = $opt;\r
+ \r
+ // Return the options list\r
+ return $this->opts;\r
+ }\r
+ \r
+ /**\r
+ * Generates the SQL that will create the index in the database\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Array containing index creation SQL\r
+ */\r
+ function create( &$xmls ) {\r
+ if( $this->drop ) {\r
+ return NULL;\r
+ }\r
+ \r
+ // eliminate any columns that aren't in the table\r
+ foreach( $this->columns as $id => $col ) {\r
+ if( !isset( $this->parent->fields[$id] ) ) {\r
+ unset( $this->columns[$id] );\r
+ }\r
+ }\r
+ \r
+ return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );\r
+ }\r
+ \r
+ /**\r
+ * Marks an index for destruction\r
+ */\r
+ function drop() {\r
+ $this->drop = TRUE;\r
+ }\r
+}\r
+\r
+/**\r
+* Creates a data object in ADOdb's datadict format\r
+*\r
+* This class stores information about table data, and is called\r
+* when we need to load field data into a table.\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbData extends dbObject {\r
+ \r
+ var $data = array();\r
+ \r
+ var $row;\r
+ \r
+ /**\r
+ * Initializes the new dbData object.\r
+ *\r
+ * @param object $parent Parent object\r
+ * @param array $attributes Attributes\r
+ *\r
+ * @internal\r
+ */\r
+ function dbData( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * Processes XML opening tags. \r
+ * Elements currently processed are: ROW and F (field). \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'ROW':\r
+ $this->row = count( $this->data );\r
+ $this->data[$this->row] = array();\r
+ break;\r
+ case 'F':\r
+ $this->addField($attributes);\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * Processes XML cdata.\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Index field name\r
+ case 'F':\r
+ $this->addData( $cdata );\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'DATA':\r
+ xml_set_object( $parser, $this->parent );\r
+ break;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds a field to the insert\r
+ *\r
+ * @param string $name Field name\r
+ * @return string Field list\r
+ */\r
+ function addField( $attributes ) {\r
+ // check we're in a valid row\r
+ if( !isset( $this->row ) || !isset( $this->data[$this->row] ) ) {\r
+ return;\r
+ }\r
+ \r
+ // Set the field index so we know where we are\r
+ if( isset( $attributes['NAME'] ) ) {\r
+ $this->current_field = $this->FieldID( $attributes['NAME'] );\r
+ } else {\r
+ $this->current_field = count( $this->data[$this->row] );\r
+ }\r
+ \r
+ // initialise data\r
+ if( !isset( $this->data[$this->row][$this->current_field] ) ) {\r
+ $this->data[$this->row][$this->current_field] = '';\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Adds options to the index\r
+ *\r
+ * @param string $opt Comma-separated list of index options.\r
+ * @return string Option list\r
+ */\r
+ function addData( $cdata ) {\r
+ // check we're in a valid field\r
+ if ( isset( $this->data[$this->row][$this->current_field] ) ) {\r
+ // add data to field\r
+ $this->data[$this->row][$this->current_field] .= $cdata;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Generates the SQL that will add/update the data in the database\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Array containing index creation SQL\r
+ */\r
+ function create( &$xmls ) {\r
+ $table = $xmls->dict->TableName($this->parent->name);\r
+ $table_field_count = count($this->parent->fields);\r
+ $tables = $xmls->db->MetaTables(); \r
+ $sql = array();\r
+ \r
+ $ukeys = $xmls->db->MetaPrimaryKeys( $table );\r
+ if( !empty( $this->parent->indexes ) and !empty( $ukeys ) ) {\r
+ foreach( $this->parent->indexes as $indexObj ) {\r
+ if( !in_array( $indexObj->name, $ukeys ) ) $ukeys[] = $indexObj->name;\r
+ }\r
+ }\r
+ \r
+ // eliminate any columns that aren't in the table\r
+ foreach( $this->data as $row ) {\r
+ $table_fields = $this->parent->fields;\r
+ $fields = array();\r
+ $rawfields = array(); // Need to keep some of the unprocessed data on hand.\r
+ \r
+ foreach( $row as $field_id => $field_data ) {\r
+ if( !array_key_exists( $field_id, $table_fields ) ) {\r
+ if( is_numeric( $field_id ) ) {\r
+ $field_id = reset( array_keys( $table_fields ) );\r
+ } else {\r
+ continue;\r
+ }\r
+ }\r
+ \r
+ $name = $table_fields[$field_id]['NAME'];\r
+ \r
+ switch( $table_fields[$field_id]['TYPE'] ) {\r
+ case 'I':\r
+ case 'I1':\r
+ case 'I2':\r
+ case 'I4':\r
+ case 'I8':\r
+ $fields[$name] = intval($field_data);\r
+ break;\r
+ case 'C':\r
+ case 'C2':\r
+ case 'X':\r
+ case 'X2':\r
+ default:\r
+ $fields[$name] = $xmls->db->qstr( $field_data );\r
+ $rawfields[$name] = $field_data;\r
+ }\r
+ \r
+ unset($table_fields[$field_id]);\r
+ \r
+ }\r
+ \r
+ // check that at least 1 column is specified\r
+ if( empty( $fields ) ) {\r
+ continue;\r
+ }\r
+ \r
+ // check that no required columns are missing\r
+ if( count( $fields ) < $table_field_count ) {\r
+ foreach( $table_fields as $field ) {\r
+ if( isset( $field['OPTS'] ) and ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {\r
+ continue(2);\r
+ }\r
+ }\r
+ }\r
+ \r
+ // The rest of this method deals with updating existing data records.\r
+ \r
+ if( !in_array( $table, $tables ) or ( $mode = $xmls->existingData() ) == XMLS_MODE_INSERT ) {\r
+ // Table doesn't yet exist, so it's safe to insert.\r
+ logMsg( "$table doesn't exist, inserting or mode is INSERT" );\r
+ $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';\r
+ continue;\r
+ }\r
+ \r
+ // Prepare to test for potential violations. Get primary keys and unique indexes\r
+ $mfields = array_merge( $fields, $rawfields );\r
+ $keyFields = array_intersect( $ukeys, array_keys( $mfields ) );\r
+ \r
+ if( empty( $ukeys ) or count( $keyFields ) == 0 ) {\r
+ // No unique keys in schema, so safe to insert\r
+ logMsg( "Either schema or data has no unique keys, so safe to insert" );\r
+ $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';\r
+ continue;\r
+ }\r
+ \r
+ // Select record containing matching unique keys.\r
+ $where = '';\r
+ foreach( $ukeys as $key ) {\r
+ if( isset( $mfields[$key] ) and $mfields[$key] ) {\r
+ if( $where ) $where .= ' AND ';\r
+ $where .= $key . ' = ' . $xmls->db->qstr( $mfields[$key] );\r
+ }\r
+ }\r
+ $records = $xmls->db->Execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where );\r
+ switch( $records->RecordCount() ) {\r
+ case 0:\r
+ // No matching record, so safe to insert.\r
+ logMsg( "No matching records. Inserting new row with unique data" );\r
+ $sql[] = $xmls->db->GetInsertSQL( $records, $mfields );\r
+ break;\r
+ case 1:\r
+ // Exactly one matching record, so we can update if the mode permits.\r
+ logMsg( "One matching record..." );\r
+ if( $mode == XMLS_MODE_UPDATE ) {\r
+ logMsg( "...Updating existing row from unique data" );\r
+ $sql[] = $xmls->db->GetUpdateSQL( $records, $mfields );\r
+ }\r
+ break;\r
+ default:\r
+ // More than one matching record; the result is ambiguous, so we must ignore the row.\r
+ logMsg( "More than one matching record. Ignoring row." );\r
+ }\r
+ }\r
+ return $sql;\r
+ }\r
+}\r
+\r
+/**\r
+* Creates the SQL to execute a list of provided SQL queries\r
+*\r
+* @package axmls\r
+* @access private\r
+*/\r
+class dbQuerySet extends dbObject {\r
+ \r
+ /**\r
+ * @var array List of SQL queries\r
+ */\r
+ var $queries = array();\r
+ \r
+ /**\r
+ * @var string String used to build of a query line by line\r
+ */\r
+ var $query;\r
+ \r
+ /**\r
+ * @var string Query prefix key\r
+ */\r
+ var $prefixKey = '';\r
+ \r
+ /**\r
+ * @var boolean Auto prefix enable (TRUE)\r
+ */\r
+ var $prefixMethod = 'AUTO';\r
+ \r
+ /**\r
+ * Initializes the query set.\r
+ *\r
+ * @param object $parent Parent object\r
+ * @param array $attributes Attributes\r
+ */\r
+ function dbQuerySet( &$parent, $attributes = NULL ) {\r
+ $this->parent = $parent;\r
+ \r
+ // Overrides the manual prefix key\r
+ if( isset( $attributes['KEY'] ) ) {\r
+ $this->prefixKey = $attributes['KEY'];\r
+ }\r
+ \r
+ $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';\r
+ \r
+ // Enables or disables automatic prefix prepending\r
+ switch( $prefixMethod ) {\r
+ case 'AUTO':\r
+ $this->prefixMethod = 'AUTO';\r
+ break;\r
+ case 'MANUAL':\r
+ $this->prefixMethod = 'MANUAL';\r
+ break;\r
+ case 'NONE':\r
+ $this->prefixMethod = 'NONE';\r
+ break;\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements. Elements currently \r
+ * processed are: QUERY. \r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ $this->currentElement = strtoupper( $tag );\r
+ \r
+ switch( $this->currentElement ) {\r
+ case 'QUERY':\r
+ // Create a new query in a SQL queryset.\r
+ // Ignore this query set if a platform is specified and it's different than the \r
+ // current connection platform.\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ $this->newQuery();\r
+ } else {\r
+ $this->discardQuery();\r
+ }\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ switch( $this->currentElement ) {\r
+ // Line of queryset SQL data\r
+ case 'QUERY':\r
+ $this->buildQuery( $cdata );\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ $this->currentElement = '';\r
+ \r
+ switch( strtoupper( $tag ) ) {\r
+ case 'QUERY':\r
+ // Add the finished query to the open query set.\r
+ $this->addQuery();\r
+ break;\r
+ case 'SQL':\r
+ $this->parent->addSQL( $this->create( $this->parent ) );\r
+ xml_set_object( $parser, $this->parent );\r
+ $this->destroy();\r
+ break;\r
+ default:\r
+ \r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Re-initializes the query.\r
+ *\r
+ * @return boolean TRUE\r
+ */\r
+ function newQuery() {\r
+ $this->query = '';\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Discards the existing query.\r
+ *\r
+ * @return boolean TRUE\r
+ */\r
+ function discardQuery() {\r
+ unset( $this->query );\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ /** \r
+ * Appends a line to a query that is being built line by line\r
+ *\r
+ * @param string $data Line of SQL data or NULL to initialize a new query\r
+ * @return string SQL query string.\r
+ */\r
+ function buildQuery( $sql = NULL ) {\r
+ if( !isset( $this->query ) OR empty( $sql ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $this->query .= $sql;\r
+ \r
+ return $this->query;\r
+ }\r
+ \r
+ /**\r
+ * Adds a completed query to the query list\r
+ *\r
+ * @return string SQL of added query\r
+ */\r
+ function addQuery() {\r
+ if( !isset( $this->query ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $this->queries[] = $return = trim($this->query);\r
+ \r
+ unset( $this->query );\r
+ \r
+ return $return;\r
+ }\r
+ \r
+ /**\r
+ * Creates and returns the current query set\r
+ *\r
+ * @param object $xmls adoSchema object\r
+ * @return array Query set\r
+ */\r
+ function create( &$xmls ) {\r
+ foreach( $this->queries as $id => $query ) {\r
+ switch( $this->prefixMethod ) {\r
+ case 'AUTO':\r
+ // Enable auto prefix replacement\r
+ \r
+ // Process object prefix.\r
+ // Evaluate SQL statements to prepend prefix to objects\r
+ $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+ $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+ $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );\r
+ \r
+ // SELECT statements aren't working yet\r
+ #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );\r
+ \r
+ case 'MANUAL':\r
+ // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.\r
+ // If prefixKey is not set, we use the default constant XMLS_PREFIX\r
+ if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {\r
+ // Enable prefix override\r
+ $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );\r
+ } else {\r
+ // Use default replacement\r
+ $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );\r
+ }\r
+ }\r
+ \r
+ $this->queries[$id] = trim( $query );\r
+ }\r
+ \r
+ // Return the query set array\r
+ return $this->queries;\r
+ }\r
+ \r
+ /**\r
+ * Rebuilds the query with the prefix attached to any objects\r
+ *\r
+ * @param string $regex Regex used to add prefix\r
+ * @param string $query SQL query string\r
+ * @param string $prefix Prefix to be appended to tables, indices, etc.\r
+ * @return string Prefixed SQL query string.\r
+ */\r
+ function prefixQuery( $regex, $query, $prefix = NULL ) {\r
+ if( !isset( $prefix ) ) {\r
+ return $query;\r
+ }\r
+ \r
+ if( preg_match( $regex, $query, $match ) ) {\r
+ $preamble = $match[1];\r
+ $postamble = $match[5];\r
+ $objectList = explode( ',', $match[3] );\r
+ // $prefix = $prefix . '_';\r
+ \r
+ $prefixedList = '';\r
+ \r
+ foreach( $objectList as $object ) {\r
+ if( $prefixedList !== '' ) {\r
+ $prefixedList .= ', ';\r
+ }\r
+ \r
+ $prefixedList .= $prefix . trim( $object );\r
+ }\r
+ \r
+ $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;\r
+ }\r
+ \r
+ return $query;\r
+ }\r
+}\r
+\r
+/**\r
+* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements\r
+* \r
+* This class is used to load and parse the XML file, to create an array of SQL statements\r
+* that can be used to build a database, and to build the database using the SQL array.\r
+*\r
+* @tutorial getting_started.pkg\r
+*\r
+* @author Richard Tango-Lowy & Dan Cech\r
+* @version $Revision$\r
+*\r
+* @package axmls\r
+*/\r
+class adoSchema {\r
+ \r
+ /**\r
+ * @var array Array containing SQL queries to generate all objects\r
+ * @access private\r
+ */\r
+ var $sqlArray;\r
+ \r
+ /**\r
+ * @var object ADOdb connection object\r
+ * @access private\r
+ */\r
+ var $db;\r
+ \r
+ /**\r
+ * @var object ADOdb Data Dictionary\r
+ * @access private\r
+ */\r
+ var $dict;\r
+ \r
+ /**\r
+ * @var string Current XML element\r
+ * @access private\r
+ */\r
+ var $currentElement = '';\r
+ \r
+ /**\r
+ * @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database\r
+ * @access private\r
+ */\r
+ var $upgrade = '';\r
+ \r
+ /**\r
+ * @var string Optional object prefix\r
+ * @access private\r
+ */\r
+ var $objectPrefix = '';\r
+ \r
+ /**\r
+ * @var long Original Magic Quotes Runtime value\r
+ * @access private\r
+ */\r
+ var $mgq;\r
+ \r
+ /**\r
+ * @var long System debug\r
+ * @access private\r
+ */\r
+ var $debug;\r
+ \r
+ /**\r
+ * @var string Regular expression to find schema version\r
+ * @access private\r
+ */\r
+ var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';\r
+ \r
+ /**\r
+ * @var string Current schema version\r
+ * @access private\r
+ */\r
+ var $schemaVersion;\r
+ \r
+ /**\r
+ * @var int Success of last Schema execution\r
+ */\r
+ var $success;\r
+ \r
+ /**\r
+ * @var bool Execute SQL inline as it is generated\r
+ */\r
+ var $executeInline;\r
+ \r
+ /**\r
+ * @var bool Continue SQL execution if errors occur\r
+ */\r
+ var $continueOnError;\r
+ \r
+ /**\r
+ * @var int How to handle existing data rows (insert, update, or ignore)\r
+ */\r
+ var $existingData;\r
+ \r
+ /**\r
+ * Creates an adoSchema object\r
+ *\r
+ * Creating an adoSchema object is the first step in processing an XML schema.\r
+ * The only parameter is an ADOdb database connection object, which must already\r
+ * have been created.\r
+ *\r
+ * @param object $db ADOdb database connection object.\r
+ */\r
+ function adoSchema( &$db ) {\r
+ // Initialize the environment\r
+ $this->mgq = get_magic_quotes_runtime();\r
+ set_magic_quotes_runtime(0);\r
+ \r
+ $this->db = $db;\r
+ $this->debug = $this->db->debug;\r
+ $this->dict = NewDataDictionary( $this->db );\r
+ $this->sqlArray = array();\r
+ $this->schemaVersion = XMLS_SCHEMA_VERSION;\r
+ $this->executeInline( XMLS_EXECUTE_INLINE );\r
+ $this->continueOnError( XMLS_CONTINUE_ON_ERROR );\r
+ $this->existingData( XMLS_EXISTING_DATA );\r
+ $this->setUpgradeMethod();\r
+ }\r
+ \r
+ /**\r
+ * Sets the method to be used for upgrading an existing database\r
+ *\r
+ * Use this method to specify how existing database objects should be upgraded.\r
+ * The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to\r
+ * alter each database object directly, REPLACE attempts to rebuild each object\r
+ * from scratch, BEST attempts to determine the best upgrade method for each\r
+ * object, and NONE disables upgrading.\r
+ *\r
+ * This method is not yet used by AXMLS, but exists for backward compatibility.\r
+ * The ALTER method is automatically assumed when the adoSchema object is\r
+ * instantiated; other upgrade methods are not currently supported.\r
+ *\r
+ * @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)\r
+ * @returns string Upgrade method used\r
+ */\r
+ function SetUpgradeMethod( $method = '' ) {\r
+ if( !is_string( $method ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $method = strtoupper( $method );\r
+ \r
+ // Handle the upgrade methods\r
+ switch( $method ) {\r
+ case 'ALTER':\r
+ $this->upgrade = $method;\r
+ break;\r
+ case 'REPLACE':\r
+ $this->upgrade = $method;\r
+ break;\r
+ case 'BEST':\r
+ $this->upgrade = 'ALTER';\r
+ break;\r
+ case 'NONE':\r
+ $this->upgrade = 'NONE';\r
+ break;\r
+ default:\r
+ // Use default if no legitimate method is passed.\r
+ $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;\r
+ }\r
+ \r
+ return $this->upgrade;\r
+ }\r
+ \r
+ /**\r
+ * Specifies how to handle existing data row when there is a unique key conflict.\r
+ *\r
+ * The existingData setting specifies how the parser should handle existing rows\r
+ * when a unique key violation occurs during the insert. This can happen when inserting\r
+ * data into an existing table with one or more primary keys or unique indexes.\r
+ * The existingData method takes one of three options: XMLS_MODE_INSERT attempts\r
+ * to always insert the data as a new row. In the event of a unique key violation,\r
+ * the database will generate an error. XMLS_MODE_UPDATE attempts to update the \r
+ * any existing rows with the new data based upon primary or unique key fields in\r
+ * the schema. If the data row in the schema specifies no unique fields, the row\r
+ * data will be inserted as a new row. XMLS_MODE_IGNORE specifies that any data rows\r
+ * that would result in a unique key violation be ignored; no inserts or updates will\r
+ * take place. For backward compatibility, the default setting is XMLS_MODE_INSERT,\r
+ * but XMLS_MODE_UPDATE will generally be the most appropriate setting.\r
+ *\r
+ * @param int $mode XMLS_MODE_INSERT, XMLS_MODE_UPDATE, or XMLS_MODE_IGNORE\r
+ * @return int current mode\r
+ */\r
+ function ExistingData( $mode = NULL ) {\r
+ if( is_int( $mode ) ) {\r
+ switch( $mode ) {\r
+ case XMLS_MODE_UPDATE:\r
+ $mode = XMLS_MODE_UPDATE;\r
+ break;\r
+ case XMLS_MODE_IGNORE:\r
+ $mode = XMLS_MODE_IGNORE;\r
+ break;\r
+ case XMLS_MODE_INSERT:\r
+ $mode = XMLS_MODE_INSERT;\r
+ break;\r
+ default:\r
+ $mode = XMLS_EXISITNG_DATA;\r
+ break;\r
+ }\r
+ $this->existingData = $mode;\r
+ }\r
+ \r
+ return $this->existingData;\r
+ }\r
+ \r
+ /**\r
+ * Enables/disables inline SQL execution.\r
+ *\r
+ * Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),\r
+ * AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode\r
+ * is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()\r
+ * to apply the schema to the database.\r
+ *\r
+ * @param bool $mode execute\r
+ * @return bool current execution mode\r
+ *\r
+ * @see ParseSchema(), ExecuteSchema()\r
+ */\r
+ function ExecuteInline( $mode = NULL ) {\r
+ if( is_bool( $mode ) ) {\r
+ $this->executeInline = $mode;\r
+ }\r
+ \r
+ return $this->executeInline;\r
+ }\r
+ \r
+ /**\r
+ * Enables/disables SQL continue on error.\r
+ *\r
+ * Call this method to enable or disable continuation of SQL execution if an error occurs.\r
+ * If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.\r
+ * If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing\r
+ * of the schema will continue.\r
+ *\r
+ * @param bool $mode execute\r
+ * @return bool current continueOnError mode\r
+ *\r
+ * @see addSQL(), ExecuteSchema()\r
+ */\r
+ function ContinueOnError( $mode = NULL ) {\r
+ if( is_bool( $mode ) ) {\r
+ $this->continueOnError = $mode;\r
+ }\r
+ \r
+ return $this->continueOnError;\r
+ }\r
+ \r
+ /**\r
+ * Loads an XML schema from a file and converts it to SQL.\r
+ *\r
+ * Call this method to load the specified schema (see the DTD for the proper format) from\r
+ * the filesystem and generate the SQL necessary to create the database\r
+ * described. This method automatically converts the schema to the latest\r
+ * axmls schema version.\r
+ * @see ParseSchemaString()\r
+ *\r
+ * @param string $file Name of XML schema file.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute\r
+ */\r
+ function ParseSchema( $filename, $returnSchema = FALSE ) {\r
+ return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+ }\r
+ \r
+ /**\r
+ * Loads an XML schema from a file and converts it to SQL.\r
+ *\r
+ * Call this method to load the specified schema directly from a file (see\r
+ * the DTD for the proper format) and generate the SQL necessary to create\r
+ * the database described by the schema. Use this method when you are dealing\r
+ * with large schema files. Otherwise, ParseSchema() is faster.\r
+ * This method does not automatically convert the schema to the latest axmls\r
+ * schema version. You must convert the schema manually using either the\r
+ * ConvertSchemaFile() or ConvertSchemaString() method.\r
+ * @see ParseSchema()\r
+ * @see ConvertSchemaFile()\r
+ * @see ConvertSchemaString()\r
+ *\r
+ * @param string $file Name of XML schema file.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute.\r
+ *\r
+ * @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()\r
+ * @see ParseSchema(), ParseSchemaString()\r
+ */\r
+ function ParseSchemaFile( $filename, $returnSchema = FALSE ) {\r
+ // Open the file\r
+ if( !($fp = fopen( $filename, 'r' )) ) {\r
+ logMsg( 'Unable to open file' );\r
+ return FALSE;\r
+ }\r
+ \r
+ // do version detection here\r
+ if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {\r
+ logMsg( 'Invalid Schema Version' );\r
+ return FALSE;\r
+ }\r
+ \r
+ if( $returnSchema ) {\r
+ $xmlstring = '';\r
+ while( $data = fread( $fp, 4096 ) ) {\r
+ $xmlstring .= $data . "\n";\r
+ }\r
+ return $xmlstring;\r
+ }\r
+ \r
+ $this->success = 2;\r
+ \r
+ $xmlParser = $this->create_parser();\r
+ \r
+ // Process the file\r
+ while( $data = fread( $fp, 4096 ) ) {\r
+ if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {\r
+ die( sprintf(\r
+ "XML error: %s at line %d",\r
+ xml_error_string( xml_get_error_code( $xmlParser) ),\r
+ xml_get_current_line_number( $xmlParser)\r
+ ) );\r
+ }\r
+ }\r
+ \r
+ xml_parser_free( $xmlParser );\r
+ \r
+ return $this->sqlArray;\r
+ }\r
+ \r
+ /**\r
+ * Converts an XML schema string to SQL.\r
+ *\r
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+ * and generate the SQL necessary to create the database described by the schema. \r
+ * @see ParseSchema()\r
+ *\r
+ * @param string $xmlstring XML schema string.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute.\r
+ */\r
+ function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {\r
+ if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+ logMsg( 'Empty or Invalid Schema' );\r
+ return FALSE;\r
+ }\r
+ \r
+ // do version detection here\r
+ if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {\r
+ logMsg( 'Invalid Schema Version' );\r
+ return FALSE;\r
+ }\r
+ \r
+ if( $returnSchema ) {\r
+ return $xmlstring;\r
+ }\r
+ \r
+ $this->success = 2;\r
+ \r
+ $xmlParser = $this->create_parser();\r
+ \r
+ if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {\r
+ die( sprintf(\r
+ "XML error: %s at line %d",\r
+ xml_error_string( xml_get_error_code( $xmlParser) ),\r
+ xml_get_current_line_number( $xmlParser)\r
+ ) );\r
+ }\r
+ \r
+ xml_parser_free( $xmlParser );\r
+ \r
+ return $this->sqlArray;\r
+ }\r
+ \r
+ /**\r
+ * Loads an XML schema from a file and converts it to uninstallation SQL.\r
+ *\r
+ * Call this method to load the specified schema (see the DTD for the proper format) from\r
+ * the filesystem and generate the SQL necessary to remove the database described.\r
+ * @see RemoveSchemaString()\r
+ *\r
+ * @param string $file Name of XML schema file.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute\r
+ */\r
+ function RemoveSchema( $filename, $returnSchema = FALSE ) {\r
+ return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );\r
+ }\r
+ \r
+ /**\r
+ * Converts an XML schema string to uninstallation SQL.\r
+ *\r
+ * Call this method to parse a string containing an XML schema (see the DTD for the proper format)\r
+ * and generate the SQL necessary to uninstall the database described by the schema. \r
+ * @see RemoveSchema()\r
+ *\r
+ * @param string $schema XML schema string.\r
+ * @param bool $returnSchema Return schema rather than parsing.\r
+ * @return array Array of SQL queries, ready to execute.\r
+ */\r
+ function RemoveSchemaString( $schema, $returnSchema = FALSE ) {\r
+ \r
+ // grab current version\r
+ if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );\r
+ }\r
+ \r
+ /**\r
+ * Applies the current XML schema to the database (post execution).\r
+ *\r
+ * Call this method to apply the current schema (generally created by calling \r
+ * ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes, \r
+ * and executing other SQL specified in the schema) after parsing.\r
+ * @see ParseSchema(), ParseSchemaString(), ExecuteInline()\r
+ *\r
+ * @param array $sqlArray Array of SQL statements that will be applied rather than\r
+ * the current schema.\r
+ * @param boolean $continueOnErr Continue to apply the schema even if an error occurs.\r
+ * @returns integer 0 if failure, 1 if errors, 2 if successful.\r
+ */\r
+ function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {\r
+ if( !is_bool( $continueOnErr ) ) {\r
+ $continueOnErr = $this->ContinueOnError();\r
+ }\r
+ \r
+ if( !isset( $sqlArray ) ) {\r
+ $sqlArray = $this->sqlArray;\r
+ }\r
+ \r
+ if( !is_array( $sqlArray ) ) {\r
+ $this->success = 0;\r
+ } else {\r
+ $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );\r
+ }\r
+ \r
+ return $this->success;\r
+ }\r
+ \r
+ /**\r
+ * Returns the current SQL array. \r
+ *\r
+ * Call this method to fetch the array of SQL queries resulting from \r
+ * ParseSchema() or ParseSchemaString(). \r
+ *\r
+ * @param string $format Format: HTML, TEXT, or NONE (PHP array)\r
+ * @return array Array of SQL statements or FALSE if an error occurs\r
+ */\r
+ function PrintSQL( $format = 'NONE' ) {\r
+ $sqlArray = null;\r
+ return $this->getSQL( $format, $sqlArray );\r
+ }\r
+ \r
+ /**\r
+ * Saves the current SQL array to the local filesystem as a list of SQL queries.\r
+ *\r
+ * Call this method to save the array of SQL queries (generally resulting from a\r
+ * parsed XML schema) to the filesystem.\r
+ *\r
+ * @param string $filename Path and name where the file should be saved.\r
+ * @return boolean TRUE if save is successful, else FALSE. \r
+ */\r
+ function SaveSQL( $filename = './schema.sql' ) {\r
+ \r
+ if( !isset( $sqlArray ) ) {\r
+ $sqlArray = $this->sqlArray;\r
+ }\r
+ if( !isset( $sqlArray ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $fp = fopen( $filename, "w" );\r
+ \r
+ foreach( $sqlArray as $key => $query ) {\r
+ fwrite( $fp, $query . ";\n" );\r
+ }\r
+ fclose( $fp );\r
+ }\r
+ \r
+ /**\r
+ * Create an xml parser\r
+ *\r
+ * @return object PHP XML parser object\r
+ *\r
+ * @access private\r
+ */\r
+ function create_parser() {\r
+ // Create the parser\r
+ $xmlParser = xml_parser_create();\r
+ xml_set_object( $xmlParser, $this );\r
+ \r
+ // Initialize the XML callback functions\r
+ xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );\r
+ xml_set_character_data_handler( $xmlParser, '_tag_cdata' );\r
+ \r
+ return $xmlParser;\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process start elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_open( &$parser, $tag, $attributes ) {\r
+ switch( strtoupper( $tag ) ) {\r
+ case 'TABLE':\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ $this->obj = new dbTable( $this, $attributes );\r
+ xml_set_object( $parser, $this->obj );\r
+ }\r
+ break;\r
+ case 'SQL':\r
+ if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {\r
+ $this->obj = new dbQuerySet( $this, $attributes );\r
+ xml_set_object( $parser, $this->obj );\r
+ }\r
+ break;\r
+ default:\r
+ // print_r( array( $tag, $attributes ) );\r
+ }\r
+ \r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process CDATA elements\r
+ *\r
+ * @access private\r
+ */\r
+ function _tag_cdata( &$parser, $cdata ) {\r
+ }\r
+ \r
+ /**\r
+ * XML Callback to process end elements\r
+ *\r
+ * @access private\r
+ * @internal\r
+ */\r
+ function _tag_close( &$parser, $tag ) {\r
+ \r
+ }\r
+ \r
+ /**\r
+ * Converts an XML schema string to the specified DTD version.\r
+ *\r
+ * Call this method to convert a string containing an XML schema to a different AXMLS\r
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+ * parameter is specified, the schema will be converted to the current DTD version. \r
+ * If the newFile parameter is provided, the converted schema will be written to the specified\r
+ * file.\r
+ * @see ConvertSchemaFile()\r
+ *\r
+ * @param string $schema String containing XML schema that will be converted.\r
+ * @param string $newVersion DTD version to convert to.\r
+ * @param string $newFile File name of (converted) output file.\r
+ * @return string Converted XML schema or FALSE if an error occurs.\r
+ */\r
+ function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {\r
+ \r
+ // grab current version\r
+ if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if( !isset ($newVersion) ) {\r
+ $newVersion = $this->schemaVersion;\r
+ }\r
+ \r
+ if( $version == $newVersion ) {\r
+ $result = $schema;\r
+ } else {\r
+ $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);\r
+ }\r
+ \r
+ if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+ fwrite( $fp, $result );\r
+ fclose( $fp );\r
+ }\r
+ \r
+ return $result;\r
+ }\r
+\r
+ /*\r
+ // compat for pre-4.3 - jlim\r
+ function _file_get_contents($path)\r
+ {\r
+ if (function_exists('file_get_contents')) return file_get_contents($path);\r
+ return join('',file($path));\r
+ }*/\r
+ \r
+ /**\r
+ * Converts an XML schema file to the specified DTD version.\r
+ *\r
+ * Call this method to convert the specified XML schema file to a different AXMLS\r
+ * DTD version. For instance, to convert a schema created for an pre-1.0 version for \r
+ * AXMLS (DTD version 0.1) to a newer version of the DTD (e.g. 0.2). If no DTD version \r
+ * parameter is specified, the schema will be converted to the current DTD version. \r
+ * If the newFile parameter is provided, the converted schema will be written to the specified\r
+ * file.\r
+ * @see ConvertSchemaString()\r
+ *\r
+ * @param string $filename Name of XML schema file that will be converted.\r
+ * @param string $newVersion DTD version to convert to.\r
+ * @param string $newFile File name of (converted) output file.\r
+ * @return string Converted XML schema or FALSE if an error occurs.\r
+ */\r
+ function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {\r
+ \r
+ // grab current version\r
+ if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if( !isset ($newVersion) ) {\r
+ $newVersion = $this->schemaVersion;\r
+ }\r
+ \r
+ if( $version == $newVersion ) {\r
+ $result = _file_get_contents( $filename );\r
+ \r
+ // remove unicode BOM if present\r
+ if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {\r
+ $result = substr( $result, 3 );\r
+ }\r
+ } else {\r
+ $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );\r
+ }\r
+ \r
+ if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {\r
+ fwrite( $fp, $result );\r
+ fclose( $fp );\r
+ }\r
+ \r
+ return $result;\r
+ }\r
+ \r
+ function TransformSchema( $schema, $xsl, $schematype='string' )\r
+ {\r
+ // Fail if XSLT extension is not available\r
+ if( ! function_exists( 'xslt_create' ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';\r
+ \r
+ // look for xsl\r
+ if( !is_readable( $xsl_file ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ switch( $schematype )\r
+ {\r
+ case 'file':\r
+ if( !is_readable( $schema ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ $schema = _file_get_contents( $schema );\r
+ break;\r
+ case 'string':\r
+ default:\r
+ if( !is_string( $schema ) ) {\r
+ return FALSE;\r
+ }\r
+ }\r
+ \r
+ $arguments = array (\r
+ '/_xml' => $schema,\r
+ '/_xsl' => _file_get_contents( $xsl_file )\r
+ );\r
+ \r
+ // create an XSLT processor\r
+ $xh = xslt_create ();\r
+ \r
+ // set error handler\r
+ xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));\r
+ \r
+ // process the schema\r
+ $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments); \r
+ \r
+ xslt_free ($xh);\r
+ \r
+ return $result;\r
+ }\r
+ \r
+ /**\r
+ * Processes XSLT transformation errors\r
+ *\r
+ * @param object $parser XML parser object\r
+ * @param integer $errno Error number\r
+ * @param integer $level Error level\r
+ * @param array $fields Error information fields\r
+ *\r
+ * @access private\r
+ */\r
+ function xslt_error_handler( $parser, $errno, $level, $fields ) {\r
+ if( is_array( $fields ) ) {\r
+ $msg = array(\r
+ 'Message Type' => ucfirst( $fields['msgtype'] ),\r
+ 'Message Code' => $fields['code'],\r
+ 'Message' => $fields['msg'],\r
+ 'Error Number' => $errno,\r
+ 'Level' => $level\r
+ );\r
+ \r
+ switch( $fields['URI'] ) {\r
+ case 'arg:/_xml':\r
+ $msg['Input'] = 'XML';\r
+ break;\r
+ case 'arg:/_xsl':\r
+ $msg['Input'] = 'XSL';\r
+ break;\r
+ default:\r
+ $msg['Input'] = $fields['URI'];\r
+ }\r
+ \r
+ $msg['Line'] = $fields['line'];\r
+ } else {\r
+ $msg = array(\r
+ 'Message Type' => 'Error',\r
+ 'Error Number' => $errno,\r
+ 'Level' => $level,\r
+ 'Fields' => var_export( $fields, TRUE )\r
+ );\r
+ }\r
+ \r
+ $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"\r
+ . '<table>' . "\n";\r
+ \r
+ foreach( $msg as $label => $details ) {\r
+ $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";\r
+ }\r
+ \r
+ $error_details .= '</table>';\r
+ \r
+ trigger_error( $error_details, E_USER_ERROR );\r
+ }\r
+ \r
+ /**\r
+ * Returns the AXMLS Schema Version of the requested XML schema file.\r
+ *\r
+ * Call this method to obtain the AXMLS DTD version of the requested XML schema file.\r
+ * @see SchemaStringVersion()\r
+ *\r
+ * @param string $filename AXMLS schema file\r
+ * @return string Schema version number or FALSE on error\r
+ */\r
+ function SchemaFileVersion( $filename ) {\r
+ // Open the file\r
+ if( !($fp = fopen( $filename, 'r' )) ) {\r
+ // die( 'Unable to open file' );\r
+ return FALSE;\r
+ }\r
+ \r
+ // Process the file\r
+ while( $data = fread( $fp, 4096 ) ) {\r
+ if( preg_match( $this->versionRegex, $data, $matches ) ) {\r
+ return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+ }\r
+ }\r
+ \r
+ return FALSE;\r
+ }\r
+ \r
+ /**\r
+ * Returns the AXMLS Schema Version of the provided XML schema string.\r
+ *\r
+ * Call this method to obtain the AXMLS DTD version of the provided XML schema string.\r
+ * @see SchemaFileVersion()\r
+ *\r
+ * @param string $xmlstring XML schema string\r
+ * @return string Schema version number or FALSE on error\r
+ */\r
+ function SchemaStringVersion( $xmlstring ) {\r
+ if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {\r
+ return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;\r
+ }\r
+ \r
+ return FALSE;\r
+ }\r
+ \r
+ /**\r
+ * Extracts an XML schema from an existing database.\r
+ *\r
+ * Call this method to create an XML schema string from an existing database.\r
+ * If the data parameter is set to TRUE, AXMLS will include the data from the database\r
+ * in the schema. \r
+ *\r
+ * @param boolean $data Include data in schema dump\r
+ * @indent string indentation to use\r
+ * @prefix string extract only tables with given prefix\r
+ * @stripprefix strip prefix string when storing in XML schema\r
+ * @return string Generated XML schema\r
+ */\r
+ function ExtractSchema( $data = FALSE, $indent = ' ', $prefix = '' , $stripprefix=false) {\r
+ $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );\r
+ \r
+ $schema = '<?xml version="1.0"?>' . "\n"\r
+ . '<schema version="' . $this->schemaVersion . '">' . "\n";\r
+ \r
+ if( is_array( $tables = $this->db->MetaTables( 'TABLES' , ($prefix) ? $prefix.'%' : '') ) ) {\r
+ foreach( $tables as $table ) {\r
+ if ($stripprefix) $table = str_replace(str_replace('\\_', '_', $pfx ), '', $table);\r
+ $schema .= $indent . '<table name="' . htmlentities( $table ) . '">' . "\n";\r
+ \r
+ // grab details from database\r
+ $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE -1' );\r
+ $fields = $this->db->MetaColumns( $table );\r
+ $indexes = $this->db->MetaIndexes( $table );\r
+ \r
+ if( is_array( $fields ) ) {\r
+ foreach( $fields as $details ) {\r
+ $extra = '';\r
+ $content = array();\r
+ \r
+ if( isset($details->max_length) && $details->max_length > 0 ) {\r
+ $extra .= ' size="' . $details->max_length . '"';\r
+ }\r
+ \r
+ if( isset($details->primary_key) && $details->primary_key ) {\r
+ $content[] = '<KEY/>';\r
+ } elseif( isset($details->not_null) && $details->not_null ) {\r
+ $content[] = '<NOTNULL/>';\r
+ }\r
+ \r
+ if( isset($details->has_default) && $details->has_default ) {\r
+ $content[] = '<DEFAULT value="' . htmlentities( $details->default_value ) . '"/>';\r
+ }\r
+ \r
+ if( isset($details->auto_increment) && $details->auto_increment ) {\r
+ $content[] = '<AUTOINCREMENT/>';\r
+ }\r
+ \r
+ if( isset($details->unsigned) && $details->unsigned ) {\r
+ $content[] = '<UNSIGNED/>';\r
+ }\r
+ \r
+ // this stops the creation of 'R' columns,\r
+ // AUTOINCREMENT is used to create auto columns\r
+ $details->primary_key = 0;\r
+ $type = $rs->MetaType( $details );\r
+ \r
+ $schema .= str_repeat( $indent, 2 ) . '<field name="' . htmlentities( $details->name ) . '" type="' . $type . '"' . $extra;\r
+ \r
+ if( !empty( $content ) ) {\r
+ $schema .= ">\n" . str_repeat( $indent, 3 )\r
+ . implode( "\n" . str_repeat( $indent, 3 ), $content ) . "\n"\r
+ . str_repeat( $indent, 2 ) . '</field>' . "\n";\r
+ } else {\r
+ $schema .= "/>\n";\r
+ }\r
+ }\r
+ }\r
+ \r
+ if( is_array( $indexes ) ) {\r
+ foreach( $indexes as $index => $details ) {\r
+ $schema .= str_repeat( $indent, 2 ) . '<index name="' . $index . '">' . "\n";\r
+ \r
+ if( $details['unique'] ) {\r
+ $schema .= str_repeat( $indent, 3 ) . '<UNIQUE/>' . "\n";\r
+ }\r
+ \r
+ foreach( $details['columns'] as $column ) {\r
+ $schema .= str_repeat( $indent, 3 ) . '<col>' . htmlentities( $column ) . '</col>' . "\n";\r
+ }\r
+ \r
+ $schema .= str_repeat( $indent, 2 ) . '</index>' . "\n";\r
+ }\r
+ }\r
+ \r
+ if( $data ) {\r
+ $rs = $this->db->Execute( 'SELECT * FROM ' . $table );\r
+ \r
+ if( is_object( $rs ) && !$rs->EOF ) {\r
+ $schema .= str_repeat( $indent, 2 ) . "<data>\n";\r
+ \r
+ while( $row = $rs->FetchRow() ) {\r
+ foreach( $row as $key => $val ) {\r
+ if ( $val != htmlentities( $val ) ) {\r
+ $row[$key] = '<![CDATA[' . $val . ']]>';\r
+ }\r
+ }\r
+ \r
+ $schema .= str_repeat( $indent, 3 ) . '<row><f>' . implode( '</f><f>', $row ) . "</f></row>\n";\r
+ }\r
+ \r
+ $schema .= str_repeat( $indent, 2 ) . "</data>\n";\r
+ }\r
+ }\r
+ \r
+ $schema .= $indent . "</table>\n";\r
+ }\r
+ }\r
+ \r
+ $this->db->SetFetchMode( $old_mode );\r
+ \r
+ $schema .= '</schema>';\r
+ return $schema;\r
+ }\r
+ \r
+ /**\r
+ * Sets a prefix for database objects\r
+ *\r
+ * Call this method to set a standard prefix that will be prepended to all database tables \r
+ * and indices when the schema is parsed. Calling setPrefix with no arguments clears the prefix.\r
+ *\r
+ * @param string $prefix Prefix that will be prepended.\r
+ * @param boolean $underscore If TRUE, automatically append an underscore character to the prefix.\r
+ * @return boolean TRUE if successful, else FALSE\r
+ */\r
+ function SetPrefix( $prefix = '', $underscore = TRUE ) {\r
+ switch( TRUE ) {\r
+ // clear prefix\r
+ case empty( $prefix ):\r
+ logMsg( 'Cleared prefix' );\r
+ $this->objectPrefix = '';\r
+ return TRUE;\r
+ // prefix too long\r
+ case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:\r
+ // prefix contains invalid characters\r
+ case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):\r
+ logMsg( 'Invalid prefix: ' . $prefix );\r
+ return FALSE;\r
+ }\r
+ \r
+ if( $underscore AND substr( $prefix, -1 ) != '_' ) {\r
+ $prefix .= '_';\r
+ }\r
+ \r
+ // prefix valid\r
+ logMsg( 'Set prefix: ' . $prefix );\r
+ $this->objectPrefix = $prefix;\r
+ return TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Returns an object name with the current prefix prepended.\r
+ *\r
+ * @param string $name Name\r
+ * @return string Prefixed name\r
+ *\r
+ * @access private\r
+ */\r
+ function prefix( $name = '' ) {\r
+ // if prefix is set\r
+ if( !empty( $this->objectPrefix ) ) {\r
+ // Prepend the object prefix to the table name\r
+ // prepend after quote if used\r
+ return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );\r
+ }\r
+ \r
+ // No prefix set. Use name provided.\r
+ return $name;\r
+ }\r
+ \r
+ /**\r
+ * Checks if element references a specific platform\r
+ *\r
+ * @param string $platform Requested platform\r
+ * @returns boolean TRUE if platform check succeeds\r
+ *\r
+ * @access private\r
+ */\r
+ function supportedPlatform( $platform = NULL ) {\r
+ if( !empty( $platform ) ) {\r
+ $regex = '/(^|\|)' . $this->db->databaseType . '(\||$)/i';\r
+ \r
+ if( preg_match( '/^- /', $platform ) ) {\r
+ if (preg_match ( $regex, substr( $platform, 2 ) ) ) {\r
+ logMsg( 'Platform ' . $platform . ' is NOT supported' );\r
+ return FALSE;\r
+ }\r
+ } else {\r
+ if( !preg_match ( $regex, $platform ) ) {\r
+ logMsg( 'Platform ' . $platform . ' is NOT supported' );\r
+ return FALSE;\r
+ }\r
+ }\r
+ }\r
+ \r
+ logMsg( 'Platform ' . $platform . ' is supported' );\r
+ return TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Clears the array of generated SQL.\r
+ *\r
+ * @access private\r
+ */\r
+ function clearSQL() {\r
+ $this->sqlArray = array();\r
+ }\r
+ \r
+ /**\r
+ * Adds SQL into the SQL array.\r
+ *\r
+ * @param mixed $sql SQL to Add\r
+ * @return boolean TRUE if successful, else FALSE.\r
+ *\r
+ * @access private\r
+ */ \r
+ function addSQL( $sql = NULL ) {\r
+ if( is_array( $sql ) ) {\r
+ foreach( $sql as $line ) {\r
+ $this->addSQL( $line );\r
+ }\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ if( is_string( $sql ) ) {\r
+ $this->sqlArray[] = $sql;\r
+ \r
+ // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.\r
+ if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {\r
+ $saved = $this->db->debug;\r
+ $this->db->debug = $this->debug;\r
+ $ok = $this->db->Execute( $sql );\r
+ $this->db->debug = $saved;\r
+ \r
+ if( !$ok ) {\r
+ if( $this->debug ) {\r
+ ADOConnection::outp( $this->db->ErrorMsg() );\r
+ }\r
+ \r
+ $this->success = 1;\r
+ }\r
+ }\r
+ \r
+ return TRUE;\r
+ }\r
+ \r
+ return FALSE;\r
+ }\r
+ \r
+ /**\r
+ * Gets the SQL array in the specified format.\r
+ *\r
+ * @param string $format Format\r
+ * @return mixed SQL\r
+ * \r
+ * @access private\r
+ */\r
+ function getSQL( $format = NULL, $sqlArray = NULL ) {\r
+ if( !is_array( $sqlArray ) ) {\r
+ $sqlArray = $this->sqlArray;\r
+ }\r
+ \r
+ if( !is_array( $sqlArray ) ) {\r
+ return FALSE;\r
+ }\r
+ \r
+ switch( strtolower( $format ) ) {\r
+ case 'string':\r
+ case 'text':\r
+ return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';\r
+ case'html':\r
+ return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';\r
+ }\r
+ \r
+ return $this->sqlArray;\r
+ }\r
+ \r
+ /**\r
+ * Destroys an adoSchema object.\r
+ *\r
+ * Call this method to clean up after an adoSchema object that is no longer in use.\r
+ * @deprecated adoSchema now cleans up automatically.\r
+ */\r
+ function Destroy() {\r
+ set_magic_quotes_runtime( $this->mgq );\r
+ unset( $this );\r
+ }\r
+}\r
+\r
+/**\r
+* Message logging function\r
+*\r
+* @access private\r
+*/\r
+function logMsg( $msg, $title = NULL, $force = FALSE ) {\r
+ if( XMLS_DEBUG or $force ) {\r
+ echo '<pre>';\r
+ \r
+ if( isset( $title ) ) {\r
+ echo '<h3>' . htmlentities( $title ) . '</h3>';\r
+ }\r
+ \r
+ if( @is_object( $this ) ) {\r
+ echo '[' . get_class( $this ) . '] ';\r
+ }\r
+ \r
+ print_r( $msg );\r
+ \r
+ echo '</pre>';\r
+ }\r
+}\r
?>
\ No newline at end of file
-<?php
+<?php
/*
* Set tabs to 4 for best viewing.
*
- * Latest version is available at http://adodb.sourceforge.net/
+ * Latest version is available at http://adodb.sourceforge.net
*
* This is the main include file for ADOdb.
* Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php
/**
\mainpage
- @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license. You can choose which license
you prefer.
define('ADODB_PHPVER',0x5200);
} else if ($_adodb_ver >= 5.0) {
define('ADODB_PHPVER',0x5000);
- } else if ($_adodb_ver > 4.299999) { # 4.3
- define('ADODB_PHPVER',0x4300);
- } else if ($_adodb_ver > 4.199999) { # 4.2
- define('ADODB_PHPVER',0x4200);
- } else if (strnatcmp(PHP_VERSION,'4.0.5')>=0) {
- define('ADODB_PHPVER',0x4050);
- } else {
- define('ADODB_PHPVER',0x4000);
- }
+ } else
+ die("PHP5 or later required. You are running ".PHP_VERSION);
}
//if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
/**
* ADODB version as a string.
*/
- $ADODB_vers = 'V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
+ $ADODB_vers = 'V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.';
/**
* Determines whether recordset->RecordCount() is used.
die('Virtual Class -- cannot instantiate');
}
- function Version()
+ static function Version()
{
global $ADODB_vers;
* All error messages go through this bottleneck function.
* You can define your own handler by defining the function name in ADODB_OUTP.
*/
- function outp($msg,$newline=true)
+ static function outp($msg,$newline=true)
{
global $ADODB_FLUSH,$ADODB_OUTP;
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;
return $ret;
}
+ function outp_throw($msg,$src='WARN',$sql='')
+ {
+ if (defined('ADODB_ERROR_HANDLER') && ADODB_ERROR_HANDLER == 'adodb_throw') {
+ adodb_throw($this->databaseType,$src,-9999,$msg,$sql,false,$this);
+ return;
+ }
+ ADOConnection::outp($msg);
+ }
+
// Format date column in sql string given an input format that understands Y M D
function SQLDate($fmt, $col=false)
{
{
return $sql;
}
-
+
/**
* Some databases, eg. mssql require a different function for preparing
* stored procedures. So we cannot use Prepare().
{
return $this->Prepare($sql,$param);
}
-
+
/**
* PEAR DB Compat
*/
/**
* PEAR DB Compat - do not use internally.
*/
- function &Query($sql, $inputarr=false)
+ function Query($sql, $inputarr=false)
{
- $rs = &$this->Execute($sql, $inputarr);
+ $rs = $this->Execute($sql, $inputarr);
if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
return $rs;
}
/**
* PEAR DB Compat - do not use internally
*/
- function &LimitQuery($sql, $offset, $count, $params=false)
+ function LimitQuery($sql, $offset, $count, $params=false)
{
- $rs = &$this->SelectLimit($sql, $count, $offset, $params);
+ $rs = $this->SelectLimit($sql, $count, $offset, $params);
if (!$rs && defined('ADODB_PEAR')) return ADODB_PEAR_Error();
return $rs;
}
* @param [inputarr] holds the input data to bind to. Null elements will be set to null.
* @return RecordSet or false
*/
- function &Execute($sql,$inputarr=false)
+ function Execute($sql,$inputarr=false)
{
if ($this->fnExecute) {
$fn = $this->fnExecute;
- $ret =& $fn($this,$sql,$inputarr);
+ $ret = $fn($this,$sql,$inputarr);
if (isset($ret)) return $ret;
}
if ($inputarr) {
}
if (isset($sqlarr[$i])) {
$sql .= $sqlarr[$i];
- if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql));
+ if ($i+1 != sizeof($sqlarr)) $this->outp_throw( "Input Array does not match ?: ".htmlspecialchars($sql),'Execute');
} else if ($i != sizeof($sqlarr))
- ADOConnection::outp( "Input array does not match ?: ".htmlspecialchars($sql));
+ $this->outp_throw( "Input array does not match ?: ".htmlspecialchars($sql),'Execute');
- $ret =& $this->_Execute($sql);
+ $ret = $this->_Execute($sql);
if (!$ret) return $ret;
}
} else {
$stmt = $sql;
foreach($inputarr as $arr) {
- $ret =& $this->_Execute($stmt,$arr);
+ $ret = $this->_Execute($stmt,$arr);
if (!$ret) return $ret;
}
} else {
- $ret =& $this->_Execute($sql,$inputarr);
+ $ret = $this->_Execute($sql,$inputarr);
}
}
} else {
- $ret =& $this->_Execute($sql,false);
+ $ret = $this->_Execute($sql,false);
}
return $ret;
}
- function &_Execute($sql,$inputarr=false)
+ function _Execute($sql,$inputarr=false)
{
if ($this->debug) {
global $ADODB_INCLUDED_LIB;
// return real recordset from select statement
$rsclass = $this->rsPrefix.$this->databaseType;
$rs = new $rsclass($this->_queryID,$this->fetchMode);
- $rs->connection = &$this; // Pablo suggestion
+ $rs->connection = $this; // Pablo suggestion
$rs->Init();
if (is_array($sql)) $rs->sql = $sql[0];
else $rs->sql = $sql;
global $ADODB_COUNTRECS;
if ($ADODB_COUNTRECS) {
if (!$rs->EOF) {
- $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql));
+ $rs = $this->_rs2rs($rs,-1,-1,!is_array($sql));
$rs->_queryID = $this->_queryID;
} else
$rs->_numOfRows = 0;
{
// owner not used in base class - see oci8
$p = array();
- $objs =& $this->MetaColumns($table);
+ $objs = $this->MetaColumns($table);
if ($objs) {
foreach($objs as $v) {
if (!empty($v->primary_key))
* @param [secs2cache] is a private parameter only used by jlim
* @return the recordset ($rs->databaseType == 'array')
*/
- function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
if ($this->hasTop && $nrows > 0) {
// suggested by Reinhard Balling. Access requires top after distinct
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
if ($secs2cache != 0) {
- $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr);
+ $ret = $this->CacheExecute($secs2cache, $sql,$inputarr);
} else {
- $ret =& $this->Execute($sql,$inputarr);
+ $ret = $this->Execute($sql,$inputarr);
}
return $ret; // PHP5 fix
} else if ($ismssql){
$ADODB_COUNTRECS = false;
if ($offset>0){
- if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
- else $rs = &$this->Execute($sql,$inputarr);
+ if ($secs2cache != 0) $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+ else $rs = $this->Execute($sql,$inputarr);
} else {
- if ($secs2cache != 0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
- else $rs = &$this->Execute($sql,$inputarr);
+ if ($secs2cache != 0) $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+ else $rs = $this->Execute($sql,$inputarr);
}
$ADODB_COUNTRECS = $savec;
if ($rs && !$rs->EOF) {
- $rs =& $this->_rs2rs($rs,$nrows,$offset);
+ $rs = $this->_rs2rs($rs,$nrows,$offset);
}
//print_r($rs);
return $rs;
*
* @param rs the recordset to serialize
*/
- function &SerializableRS(&$rs)
+ function SerializableRS(&$rs)
{
- $rs2 =& $this->_rs2rs($rs);
+ $rs2 = $this->_rs2rs($rs);
$ignore = false;
- $rs2->connection =& $ignore;
+ $rs2->connection = $ignore;
return $rs2;
}
}
$dbtype = $rs->databaseType;
if (!$dbtype) {
- $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
+ $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
return $rs;
}
if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) {
$rs->MoveFirst();
- $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
+ $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
return $rs;
}
$flds = array();
$flds[] = $rs->FetchField($i);
}
- $arr =& $rs->GetArrayLimit($nrows,$offset);
+ $arr = $rs->GetArrayLimit($nrows,$offset);
//print_r($arr);
if ($close) $rs->Close();
$arrayClass = $this->arrayClass;
$rs2 = new $arrayClass();
- $rs2->connection = &$this;
+ $rs2->connection = $this;
$rs2->sql = $rs->sql;
$rs2->dataProvider = $this->dataProvider;
$rs2->InitArrayFields($arr,$flds);
/*
* Return all rows. Compat with PEAR DB
*/
- function &GetAll($sql, $inputarr=false)
+ function GetAll($sql, $inputarr=false)
{
- $arr =& $this->GetArray($sql,$inputarr);
+ $arr = $this->GetArray($sql,$inputarr);
return $arr;
}
- function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false)
+ function GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false)
{
- $rs =& $this->Execute($sql, $inputarr);
+ $rs = $this->Execute($sql, $inputarr);
if (!$rs) {
$false = false;
return $false;
}
- $arr =& $rs->GetAssoc($force_array,$first2cols);
+ $arr = $rs->GetAssoc($force_array,$first2cols);
return $arr;
}
- function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false)
+ function CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false)
{
if (!is_numeric($secs2cache)) {
$first2cols = $force_array;
$force_array = $inputarr;
}
- $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr);
+ $rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
if (!$rs) {
$false = false;
return $false;
}
- $arr =& $rs->GetAssoc($force_array,$first2cols);
+ $arr = $rs->GetAssoc($force_array,$first2cols);
return $arr;
}
$ADODB_COUNTRECS = false;
$ret = false;
- $rs = &$this->Execute($sql,$inputarr);
+ $rs = $this->Execute($sql,$inputarr);
if ($rs) {
if ($rs->EOF) $ret = null;
else $ret = reset($rs->fields);
function CacheGetOne($secs2cache,$sql=false,$inputarr=false)
{
$ret = false;
- $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr);
- if ($rs) {
+ $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
+ if ($rs) {
if ($rs->EOF) $ret = null;
else $ret = reset($rs->fields);
$rs->Close();
function GetCol($sql, $inputarr = false, $trim = false)
{
- $rs = &$this->Execute($sql, $inputarr);
+ $rs = $this->Execute($sql, $inputarr);
if ($rs) {
$rv = array();
if ($trim) {
function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false)
{
- $rs = &$this->CacheExecute($secs, $sql, $inputarr);
+ $rs = $this->CacheExecute($secs, $sql, $inputarr);
if ($rs) {
$rv = array();
if ($trim) {
}
}
$rs->Close();
- } else
- $rv = false;
-
- return $rv;
+ } else
+ $rv = false;
+
+ return $rv;
}
- function &Transpose(&$rs,$addfieldnames=true)
+ function Transpose(&$rs,$addfieldnames=true)
{
- $rs2 =& $this->_rs2rs($rs);
+ $rs2 = $this->_rs2rs($rs);
$false = false;
if (!$rs2) return $false;
* @param sql SQL statement
* @param [inputarr] input bind array
*/
- function &GetArray($sql,$inputarr=false)
+ function GetArray($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
$savec = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = false;
- $rs =& $this->Execute($sql,$inputarr);
+ $rs = $this->Execute($sql,$inputarr);
$ADODB_COUNTRECS = $savec;
if (!$rs)
if (defined('ADODB_PEAR')) {
$false = false;
return $false;
}
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$rs->Close();
return $arr;
}
- function &CacheGetAll($secs2cache,$sql=false,$inputarr=false)
+ function CacheGetAll($secs2cache,$sql=false,$inputarr=false)
{
- $arr =& $this->CacheGetArray($secs2cache,$sql,$inputarr);
+ $arr = $this->CacheGetArray($secs2cache,$sql,$inputarr);
return $arr;
}
- function &CacheGetArray($secs2cache,$sql=false,$inputarr=false)
+ function CacheGetArray($secs2cache,$sql=false,$inputarr=false)
{
global $ADODB_COUNTRECS;
$savec = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = false;
- $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
+ $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
$ADODB_COUNTRECS = $savec;
if (!$rs)
$false = false;
return $false;
}
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$rs->Close();
return $arr;
}
* @param sql SQL statement
* @param [inputarr] input bind array
*/
- function &GetRow($sql,$inputarr=false)
+ function GetRow($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
$crecs = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = false;
- $rs =& $this->Execute($sql,$inputarr);
+ $rs = $this->Execute($sql,$inputarr);
$ADODB_COUNTRECS = $crecs;
if ($rs) {
return $false;
}
- function &CacheGetRow($secs2cache,$sql=false,$inputarr=false)
+ function CacheGetRow($secs2cache,$sql=false,$inputarr=false)
{
- $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr);
+ $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
if ($rs) {
- $arr = array();
if (!$rs->EOF) $arr = $rs->fields;
+ else $arr = array();
+
$rs->Close();
return $arr;
}
* @param [inputarr] array of bind variables
* @return the recordset ($rs->databaseType == 'array')
*/
- function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
+ function CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false)
{
if (!is_numeric($secs2cache)) {
if ($sql === false) $sql = -1;
if ($offset == -1) $offset = false;
// sql, nrows, offset,inputarr
- $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
+ $rs = $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
} else {
- if ($sql === false) ADOConnection::outp( "Warning: \$sql missing from CacheSelectLimit()");
- $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ if ($sql === false) $this->outp_throw("Warning: \$sql missing from CacheSelectLimit()",'CacheSelectLimit');
+ $rs = $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
}
return $rs;
}
*
* Just specify the directory, and tell it if you want to delete the directory or just clear it out.
* Note: $kill_top_level is used internally in the function to flush subdirectories.
+ *
*/
function _dirFlush($dir, $kill_top_level = false)
{
return true;
}
-
+ // this only deletes .cache files
function xCacheFlush($sql=false,$inputarr=false)
{
global $ADODB_CACHE_DIR;
* @param [inputarr] holds the input data to bind to
* @return RecordSet or false
*/
- function &CacheExecute($secs2cache,$sql=false,$inputarr=false)
+ function CacheExecute($secs2cache,$sql=false,$inputarr=false)
{
-
-
if (!is_numeric($secs2cache)) {
$inputarr = $sql;
$sql = $secs2cache;
if ($secs2cache > 0){
if ($this->memCache)
- $rs = &getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort);
+ $rs = getmemCache($md5file,$err,$secs2cache, $this->memCacheHost, $this->memCachePort);
else
- $rs = &csv2rs($md5file,$err,$secs2cache,$this->arrayClass);
+ $rs = csv2rs($md5file,$err,$secs2cache,$this->arrayClass);
$this->numCacheHits += 1;
} else {
$err='Timeout 1';
$rs = false;
$this->numCacheMisses += 1;
}
+
if (!$rs) {
// no cached rs found
if ($this->debug) {
if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)");
}
- $rs = &$this->Execute($sqlparam,$inputarr);
+ $rs = $this->Execute($sqlparam,$inputarr);
if ($rs && $this->memCache) {
- $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately
+ $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately
if(!putmemCache($md5file, $rs, $this->memCacheHost, $this->memCachePort, $this->memCacheCompress, $this->debug)) {
if ($fn = $this->raiseErrorFn)
$fn($this->databaseType,'CacheExecute',-32000,"Cache write error",$md5file,$sql,$this);
}
} else if ($rs) {
$eof = $rs->EOF;
- $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately
+ $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately
$txt = _rs2serialize($rs,false,$sql); // serialize
-
+
$ok = adodb_write_file($md5file,$txt,$this->debug);
if (!$ok) {
if ($ok === false) {
}
if ($rs->EOF && !$eof) {
$rs->MoveFirst();
- //$rs = &csv2rs($md5file,$err);
- $rs->connection = &$this; // Pablo suggestion
+ //$rs = csv2rs($md5file,$err);
+ $rs->connection = $this; // Pablo suggestion
}
} else
$fn($this, $secs2cache, $sql, $inputarr);
}
// ok, set cached object found
- $rs->connection = &$this; // Pablo suggestion
- if ($this->debug){
-
+ $rs->connection = $this; // Pablo suggestion
+ if ($this->debug){
+ if ($this->debug == 99) adodb_backtrace();
$inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
$ttl = $rs->timeCreated + $secs2cache - time();
$s = is_array($sql) ? $sql[0] : $sql;
$forceUpdate means that even if the data has not changed, perform update.
*/
- function& AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false)
+ function AutoExecute($table, $fields_values, $mode = 'INSERT', $where = FALSE, $forceUpdate=true, $magicq=false)
{
$false = false;
$sql = 'SELECT * FROM '.$table;
if ($where!==FALSE) $sql .= ' WHERE '.$where;
else if ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) {
- ADOConnection::outp('AutoExecute: Illegal mode=UPDATE with empty WHERE clause');
+ $this->outp_throw('AutoExecute: Illegal mode=UPDATE with empty WHERE clause','AutoExecute');
return $false;
}
- $rs =& $this->SelectLimit($sql,1);
+ $rs = $this->SelectLimit($sql,1);
if (!$rs) return $false; // table does not exist
$rs->tableName = $table;
$sql = $this->GetInsertSQL($rs, $fields_values, $magicq);
break;
default:
- ADOConnection::outp("AutoExecute: Unknown mode=$mode");
+ $this->outp_throw("AutoExecute: Unknown mode=$mode",'AutoExecute');
return $false;
}
$ret = false;
if (empty($this->_metars)) {
$rsclass = $this->rsPrefix.$this->databaseType;
$this->_metars = new $rsclass(false,$this->fetchMode);
- $this->_metars->connection =& $this;
+ $this->_metars->connection = $this;
}
return $this->_metars->MetaType($t,$len,$fieldobj);
}
}
}
- function &GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false)
+ function GetActiveRecordsClass($class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false)
{
global $_ADODB_ACTIVE_DBS;
include(ADODB_DIR.'/adodb-active-record.inc.php');
}
if (!class_exists($class)) {
- ADOConnection::outp("Unknown class $class in GetActiveRcordsClass()");
+ $this->outp_throw("Unknown class $class in GetActiveRecordsClass()",'GetActiveRecordsClass');
return $false;
}
$arr = array();
return $arr;
}
- function &GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false)
+ function GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false)
{
- $arr =& $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
+ $arr = $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
return $arr;
}
*
* @return array of tables for current database.
*/
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
global $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = $save;
if ($rs === false) return $false;
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$arr2 = array();
if ($hast = ($ttype && isset($arr[0][1]))) {
*
* @return array of ADOFieldObjects for current table.
*/
- function &MetaColumns($table,$normalize=true)
+ function MetaColumns($table,$normalize=true)
{
global $ADODB_FETCH_MODE;
)
)
*/
- function &MetaIndexes($table, $primary = false, $owner = false)
+ function MetaIndexes($table, $primary = false, $owner = false)
{
$false = false;
return $false;
*
* @return array of column names for current table.
*/
- function &MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */)
+ function MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */)
{
- $objarr =& $this->MetaColumns($table);
+ $objarr = $this->MetaColumns($table);
if (!is_array($objarr)) {
$false = false;
return $false;
*
* @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
*/
- function UnixDate($v)
+ static function UnixDate($v)
{
if (is_object($v)) {
// odbtp support
*
* @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
*/
- function UnixTimeStamp($v)
+ static function UnixTimeStamp($v)
{
if (is_object($v)) {
// odbtp support
* NOTE: phpLens uses a different algorithm and does not use PageExecute().
*
*/
- function &PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0)
+ function PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0)
{
global $ADODB_INCLUDED_LIB;
if (empty($ADODB_INCLUDED_LIB)) include(ADODB_DIR.'/adodb-lib.inc.php');
- if ($this->pageExecuteCountRows) $rs =& _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
- else $rs =& _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
+ if ($this->pageExecuteCountRows) $rs = _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
+ else $rs = _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
return $rs;
}
* @param [inputarr] array of bind variables
* @return the recordset ($rs->databaseType == 'array')
*/
- function &CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false)
+ function CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false)
{
/*switch($this->dataProvider) {
case 'postgres':
break;
default: $secs2cache = 0; break;
}*/
- $rs =& $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
+ $rs = $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
return $rs;
}
// CLASS ADORecordSet_empty
//==============================================================================================
+ class ADODB_Iterator_empty implements Iterator {
+
+ private $rs;
+
+ function __construct($rs)
+ {
+ $this->rs = $rs;
+ }
+ function rewind()
+ {
+ }
+
+ function valid()
+ {
+ return !$this->rs->EOF;
+ }
+
+ function key()
+ {
+ return $false;
+ }
+
+ function current()
+ {
+ return $false;
+ }
+
+ function next()
+ {
+ }
+
+ function __call($func, $params)
+ {
+ return call_user_func_array(array($this->rs, $func), $params);
+ }
+
+ function hasMore()
+ {
+ return false;
+ }
+
+ }
+
+
/**
* Lightweight recordset when there are no records to be returned
*/
- class ADORecordSet_empty
+ class ADORecordSet_empty implements IteratorAggregate
{
var $dataProvider = 'empty';
var $databaseType = false;
function FetchRow() {return false;}
function FieldCount(){ return 0;}
function Init() {}
+ function getIterator() {return new ADODB_Iterator_empty($this);}
}
//==============================================================================================
// CLASS ADORecordSet
//==============================================================================================
- if (PHP_VERSION < 5) include_once(ADODB_DIR.'/adodb-php4.inc.php');
- else include_once(ADODB_DIR.'/adodb-iterator.inc.php');
+ class ADODB_Iterator implements Iterator {
+
+ private $rs;
+
+ function __construct($rs)
+ {
+ $this->rs = $rs;
+ }
+ function rewind()
+ {
+ $this->rs->MoveFirst();
+ }
+
+ function valid()
+ {
+ return !$this->rs->EOF;
+ }
+
+ function key()
+ {
+ return $this->rs->_currentRow;
+ }
+
+ function current()
+ {
+ return $this->rs->fields;
+ }
+
+ function next()
+ {
+ $this->rs->MoveNext();
+ }
+
+ function __call($func, $params)
+ {
+ return call_user_func_array(array($this->rs, $func), $params);
+ }
+
+
+ function hasMore()
+ {
+ return !$this->rs->EOF;
+ }
+
+ }
+
+
+
/**
* RecordSet class that represents the dataset returned by the database.
* To keep memory overhead low, this class holds only the current row in memory.
* No prefetching of data is done, so the RecordCount() can return -1 ( which
* means recordcount not known).
*/
- class ADORecordSet extends ADODB_BASE_RS {
+ class ADORecordSet implements IteratorAggregate {
/*
* public variables
*/
$this->_queryID = $queryID;
}
+ function getIterator()
+ {
+ return new ADODB_Iterator($this);
+ }
+
+ /* this is experimental - i don't really know what to return... */
+ function __toString()
+ {
+ include_once(ADODB_DIR.'/toexport.inc.php');
+ return _adodb_export($this,',',',',false,true);
+ }
function Init()
*
* @return an array indexed by the rows (0-based) from the recordset
*/
- function &GetArray($nRows = -1)
+ function GetArray($nRows = -1)
{
global $ADODB_EXTENSION; if ($ADODB_EXTENSION) {
$results = adodb_getall($this,$nRows);
return $results;
}
- function &GetAll($nRows = -1)
+ function GetAll($nRows = -1)
{
- $arr =& $this->GetArray($nRows);
+ $arr = $this->GetArray($nRows);
return $arr;
}
*
* @return an array indexed by the rows (0-based) from the recordset
*/
- function &GetArrayLimit($nrows,$offset=-1)
+ function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
- $arr =& $this->GetArray($nrows);
+ $arr = $this->GetArray($nrows);
return $arr;
}
*
* @return an array indexed by the rows (0-based) from the recordset
*/
- function &GetRows($nRows = -1)
+ function GetRows($nRows = -1)
{
- $arr =& $this->GetArray($nRows);
+ $arr = $this->GetArray($nRows);
return $arr;
}
* @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;
}
}
- $ref =& $results; # workaround accelerator incompat with PHP 4.4 :(
+ $ref = $results; # workaround accelerator incompat with PHP 4.4 :(
return $ref;
}
*
* @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
*/
- function UnixDate($v)
+ static function UnixDate($v)
{
return ADOConnection::UnixDate($v);
}
*
* @return date in unix timestamp format, or 0 if before TIMESTAMP_FIRST_YEAR, or false if invalid date format
*/
- function UnixTimeStamp($v)
+ static function UnixTimeStamp($v)
{
return ADOConnection::UnixTimeStamp($v);
}
*
* @return false or array containing the current record
*/
- function &FetchRow()
+ function FetchRow()
{
if ($this->EOF) {
$false = false;
*
* $upper 0 = lowercase, 1 = uppercase, 2 = whatever is returned by FetchField
*/
- function &GetRowAssoc($upper=1)
+ function GetRowAssoc($upper=1)
{
$record = array();
// if (!$this->fields) return $record;
if ($lnumrows == -1 && $this->connection) {
IF ($table) {
if ($condition) $condition = " WHERE " . $condition;
- $resultrows = &$this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
+ $resultrows = $this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
if ($resultrows) $lnumrows = reset($resultrows->fields);
}
}
*
* @return the ADOFieldObject for that column, or false.
*/
- function &FetchField($fieldoffset = -1)
+ function FetchField($fieldoffset = -1)
{
// must be defined by child class
* Get the ADOFieldObjects of all columns in an array.
*
*/
- function& FieldTypesArray()
+ function FieldTypesArray()
{
$arr = array();
for ($i=0, $max=$this->_numOfFields; $i < $max; $i++)
*
* @return the object with the properties set to the fields of the current row
*/
- function &FetchObj()
+ function FetchObj()
{
- $o =& $this->FetchObject(false);
+ $o = $this->FetchObject(false);
return $o;
}
*
* @return the object with the properties set to the fields of the current row
*/
- function &FetchObject($isupper=true)
+ function FetchObject($isupper=true)
{
if (empty($this->_obj)) {
$this->_obj = new ADOFetchObj();
*
* Fixed bug reported by tim@orotech.net
*/
- function &FetchNextObj()
+ function FetchNextObj()
{
- $o =& $this->FetchNextObject(false);
+ $o = $this->FetchNextObject(false);
return $o;
}
*
* Fixed bug reported by tim@orotech.net
*/
- function &FetchNextObject($isupper=true)
+ function FetchNextObject($isupper=true)
{
$o = false;
if ($this->_numOfRows != 0 && !$this->EOF) {
//adodb_pr($newarr);
$this->_skiprow1 = false;
- $this->_array =& $newarr;
+ $this->_array = $newarr;
$this->_colnames = $hdr;
adodb_probetypes($newarr,$this->_types);
*/
function InitArrayFields(&$array,&$fieldarr)
{
- $this->_array =& $array;
+ $this->_array = $array;
$this->_skiprow1= false;
if ($fieldarr) {
- $this->_fieldobjects =& $fieldarr;
+ $this->_fieldobjects = $fieldarr;
}
$this->Init();
}
- function &GetArray($nRows=-1)
+ function GetArray($nRows=-1)
{
if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) {
return $this->_array;
} else {
- $arr =& ADORecordSet::GetArray($nRows);
+ $arr = ADORecordSet::GetArray($nRows);
return $arr;
}
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
if (isset($this->_fieldobjects)) {
return $this->_fieldobjects[$fieldOffset];
/**
* synonym for ADONewConnection for people like me who cannot remember the correct name
*/
- function &NewADOConnection($db='')
+ function NewADOConnection($db='')
{
- $tmp =& ADONewConnection($db);
+ $tmp = ADONewConnection($db);
return $tmp;
}
*
* @return the freshly created instance of the Connection class.
*/
- function &ADONewConnection($db='')
+ function ADONewConnection($db='')
{
GLOBAL $ADODB_NEWCONNECTION, $ADODB_LASTDB;
if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
$errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
$false = false;
- if ($at = strpos($db,'://')) {
+ if (($at = strpos($db,'://')) !== FALSE) {
$origdsn = $db;
- if (PHP_VERSION < 5) $dsna = @parse_url($db);
- else {
- $fakedsn = 'fake'.substr($db,$at);
+ $fakedsn = 'fake'.substr($origdsn,$at);
+ if (($at2 = strpos($origdsn,'@/')) !== FALSE) {
+ // special handling of oracle, which might not have host
+ $fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn);
+ }
$dsna = @parse_url($fakedsn);
- $dsna['scheme'] = substr($db,0,$at);
+ if (!$dsna) {
+ return $false;
+ }
+ $dsna['scheme'] = substr($origdsn,0,$at);
+ if ($at2 !== FALSE) {
+ $dsna['host'] = '';
+ }
- if (strncmp($db,'pdo',3) == 0) {
- $sch = explode('_',$dsna['scheme']);
- if (sizeof($sch)>1) {
- $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
- $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
- $dsna['scheme'] = 'pdo';
- }
+ if (strncmp($origdsn,'pdo',3) == 0) {
+ $sch = explode('_',$dsna['scheme']);
+ if (sizeof($sch)>1) {
+ $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
+ $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
+ $dsna['scheme'] = 'pdo';
}
}
- 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']) : '';
return $drivername;
}
- function &NewPerfMonitor(&$conn)
+ function NewPerfMonitor(&$conn)
{
$false = false;
$drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true);
return $perf;
}
- function &NewDataDictionary(&$conn,$drivername=false)
+ function NewDataDictionary(&$conn,$drivername=false)
{
$false = false;
if (!$drivername) $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType);
$class = "ADODB2_$drivername";
$dict = new $class();
$dict->dataProvider = $conn->dataProvider;
- $dict->connection = &$conn;
+ $dict->connection = $conn;
$dict->upperName = strtoupper($drivername);
$dict->quote = $conn->nameQuote;
if (!empty($conn->_connectionID))
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
$validTypes = array("CHAR","VARC");
$invalidTypes = array("BIGI","BLOB","CLOB","DATE", "DECI","DOUB", "INTE", "REAL","SMAL", "TIME");
// check table exists
- $cols = &$this->MetaColumns($tablename);
+ $cols = $this->MetaColumns($tablename);
if ( empty($cols)) {
return $this->CreateTableSQL($tablename, $flds, $tableoptions);
}
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
return $sql;
}
-
+
function DropIndexSQL ($idxname, $tabname = NULL)
{
* @param array/ $tableoptions options for the new table see CreateTableSQL, default ''
* @return array with SQL strings
*/
- /*function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
+ /*
+ function AlterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
{
if (!$tableflds) {
if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL");
<?php
/**
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
return " IIF(IsNull($field), $ifNull, $field) "; // if Access
}
/*
- function &MetaTables()
+ function MetaTables()
{
global $ADODB_FETCH_MODE;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
- $arr = &$rs->GetArray();
+ $arr = $rs->GetArray();
//print_pre($arr);
$arr2 = array();
for ($i=0; $i < sizeof($arr); $i++) {
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
*/
- function &MetaTables()
+ function MetaTables()
{
$arr= array();
$dbc = $this->_connectionID;
return $arr;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
$table = strtoupper($table);
$arr = array();
/* returns queryID or false */
- function &_query($sql,$inputarr=false)
+ function _query($sql,$inputarr=false)
{
$dbc = $this->_connectionID;
// returns the field object
- function &FetchField($fieldOffset = -1) {
+ function FetchField($fieldOffset = -1) {
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
$this->fields[] = $val;
break;
-
default:
$this->fields[] = $f->value;
break;
@$rs->MoveNext(); // @ needed for some versions of PHP!
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
return true;
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
if ($argProvider) $dbc->Provider = $argProvider;
+ if ($argProvider) $argHostname = "PROVIDER=$argProvider;DRIVER={SQL Server};SERVER=$argHostname";
+
+
if ($argDatabasename) $argHostname .= ";DATABASE=$argDatabasename";
if ($argUsername) $argHostname .= ";$u=$argUsername";
if ($argPassword)$argHostname .= ";$p=$argPassword";
*/
- function &MetaTables()
+ function MetaTables()
{
$arr= array();
$dbc = $this->_connectionID;
return $arr;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
$table = strtoupper($table);
$arr= array();
}
/* returns queryID or false */
- function &_query($sql,$inputarr=false)
+ function _query($sql,$inputarr=false)
{
try { // In PHP5, all COM errors are exceptions, so to maintain old behaviour...
// returns the field object
- function &FetchField($fieldOffset = -1) {
+ function FetchField($fieldOffset = -1) {
$off=$fieldOffset+1; // offsets begin at 1
$o= new ADOFieldObject();
@$rs->MoveNext(); // @ needed for some versions of PHP!
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
return true;
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
// Firebird uses
// SELECT FIRST 5 SKIP 2 col1, col2 FROM TABLE
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
if ($nrows > 0) {
if ($offset <= 0) $str = " ROWS $nrows ";
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
return $this->_affectedrows;
}
- function &MetaDatabases()
+ function MetaDatabases()
{
return false;
}
return true;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
return false;
}
// parameters use PostgreSQL convention, not MySQL
- function &SelectLimit($sql,$nrows=-1,$offset=-1)
+ function SelectLimit($sql,$nrows=-1,$offset=-1)
{
global $ADODB_FETCH_MODE;
$rs->databaseType='csv';
$rs->fetchMode = ($this->fetchMode !== false) ? $this->fetchMode : $ADODB_FETCH_MODE;
- $rs->connection = &$this;
+ $rs->connection = $this;
}
return $rs;
}
// returns queryID or false
- function &_Execute($sql,$inputarr=false)
+ function _Execute($sql,$inputarr=false)
{
global $ADODB_FETCH_MODE;
$this->_affectedrows = $rs->affectedrows;
$this->_insertid = $rs->insertid;
$rs->databaseType='csv';
- $rs->connection = &$this;
+ $rs->connection = $this;
}
return $rs;
}
<?php
/*
- V4.98 13 Feb 2008 (c) 2006 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2006 John Lim (jlim#natsoft.com.my). All rights reserved.
This is a version of the ADODB driver for DB2. It uses the 'ibm_db2' PECL extension
for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or
if (!$rs) return false;
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
for ($i=0; $i < sizeof($arr); $i++) {
}
- function &MetaTables($ttype=false,$schema=false)
+ function MetaTables($ttype=false,$schema=false)
{
global $ADODB_FETCH_MODE;
return $false;
}
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$rs->Close();
$arr2 = array();
}
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
global $ADODB_FETCH_MODE;
$qid = db2_columns($this->_connectionID, "", $schema, $table, $colname);
if (empty($qid)) return $false;
- $rs =& new ADORecordSet_db2($qid);
+ $rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $false;
$qid = db2_primary_keys($this->_connectionID, "", $schema, $table);
if (empty($qid)) return $false;
- $rs =& new ADORecordSet_db2($qid);
+ $rs = new ADORecordSet_db2($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $retarr;
// returns the field object
- function &FetchField($offset = -1)
+ function FetchField($offset = -1)
{
$o= new ADOFieldObject();
$o->name = @db2_field_name($this->_queryID,$offset);
}
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
- function &GetArrayLimit($nrows,$offset=-1)
+ function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
- $rs =& $this->GetArray($nrows);
+ $rs = $this->GetArray($nrows);
return $rs;
}
$savem = $this->fetchMode;
$this->fetchMode = $savem;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
$results = array();
$this->fields = @db2_fetch_array($this->_queryID);
if ($this->fields) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
return true;
}
$this->fields = db2_fetch_array($this->_queryID);
if ($this->fields) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
return true;
}
<?php
/*
- @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
return fbsql_affected_rows($this->_connectionID);
}
- function &MetaDatabases()
+ function MetaDatabases()
{
$qid = fbsql_list_dbs($this->_connectionID);
$arr = array();
return true;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
if ($this->metaColumnsSQL) {
- function &FetchField($fieldOffset = -1) {
+ function FetchField($fieldOffset = -1) {
if ($fieldOffset != -1) {
$o = @fbsql_fetch_field($this->_queryID, $fieldOffset);
//$o->max_length = -1; // fbsql returns the max length less spaces -- so it is unrealiable
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
// Note that Interbase 6.5 uses this ROWS instead - don't you love forking wars!
// SELECT col1, col2 FROM table ROWS 5 -- get 5 rows
// SELECT col1, col2 FROM TABLE ORDER BY col1 ROWS 3 TO 7 -- first 5 skip 2
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false, $secs=0)
{
$nrows = (integer) $nrows;
$offset = (integer) $offset;
$sql = preg_replace('/^[ \t]*select/i',$str,$sql);
if ($secs)
- $rs =& $this->CacheExecute($secs,$sql,$inputarr);
+ $rs = $this->CacheExecute($secs,$sql,$inputarr);
else
- $rs =& $this->Execute($sql,$inputarr);
+ $rs = $this->Execute($sql,$inputarr);
return $rs;
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
// there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
// it appears that ibase extension cannot support multiple concurrent queryid's
- function &_Execute($sql,$inputarr=false)
+ function _Execute($sql,$inputarr=false)
{
global $ADODB_COUNTRECS;
if ($this->_logsql) {
$savecrecs = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = true; // force countrecs
- $ret =& ADOConnection::_Execute($sql,$inputarr);
+ $ret = ADOConnection::_Execute($sql,$inputarr);
$ADODB_COUNTRECS = $savecrecs;
} else {
- $ret =& ADOConnection::_Execute($sql,$inputarr);
+ $ret = ADOConnection::_Execute($sql,$inputarr);
}
return $ret;
}
return $ret;
}
- function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+ function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
if (is_array($iarr)) {
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
- $fnarr =& array_merge( array($sql) , $iarr);
+ $fnarr = array_merge( array($sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
} else {
switch(sizeof($iarr)) {
if (is_array($iarr)) {
if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4
if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
- $fnarr =& array_merge( array($conn,$sql) , $iarr);
+ $fnarr = array_merge( array($conn,$sql) , $iarr);
$ret = call_user_func_array($fn,$fnarr);
} else {
switch(sizeof($iarr)) {
}
//OPN STUFF end
// returns array of ADOFieldObjects for current table
- function &MetaColumns($table)
+ function MetaColumns($table)
{
global $ADODB_FETCH_MODE;
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$ibf = ibase_field_info($this->_queryID,$fieldOffset);
$this->fields = $f;
if ($this->fetchMode == ADODB_FETCH_ASSOC) {
- $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
} else if ($this->fetchMode == ADODB_FETCH_BOTH) {
- $this->fields =& array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));
+ $this->fields = array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));
}
return true;
}
<?php
/**
-* @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+* @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim. All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim. All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
global $ADODB_FETCH_MODE;
return $false;
}
- function &xMetaColumns($table)
+ function xMetaColumns($table)
{
return ADOConnection::MetaColumns($table,false);
}
$rs = $this->Execute($sql);
if (!$rs || $rs->EOF) return false;
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$a = array();
foreach($arr as $v) {
$coldest=$this->metaColumnNames($v["tabname"]);
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
if (empty($this->_fieldprops)) {
$fp = ifx_fieldproperties($this->_queryID);
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
# Options configuration information
var $LDAP_CONNECT_OPTIONS;
-
+
# error on binding, eg. "Binding: invalid credentials"
var $_bind_errmsg = "Binding: %s";
-
+
function ADODB_ldap()
{
}
// returns true or false
+
function _connect( $host, $username, $password, $ldapbase)
{
global $LDAP_CONNECT_OPTIONS;
}
if (!$bind) {
- $e = sprintf($this->_bind_errmsg,ldap_error($this->_connectionID));;
+ $e = sprintf($this->_bind_errmsg,ldap_error($this->_connectionID));
$this->_errorMsg = $e;
if ($this->debug) ADOConnection::outp($e);
return false;
function _query($sql,$inputarr)
{
$rs = @ldap_search( $this->_connectionID, $this->database, $sql );
- $this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql.': '. ldap_error($this->_connectionID);
+ $this->_errorMsg = ($rs) ? '' : 'Search error on '.$sql.': '.ldap_error($this->_connectionID);
return $rs;
}
-
+
function ErrorMsg()
{
return $this->_errorMsg;
{
return @ldap_errno($this->_connectionID);
}
-
+
/* closes the LDAP connection */
function _close()
{
/*
Return whole recordset as a multi-dimensional associative array
*/
- function &GetAssoc($force_array = false, $first2cols = false)
+ function GetAssoc($force_array = false, $first2cols = false)
{
$records = $this->_numOfRows;
$results = array();
return $results;
}
- function &GetRowAssoc()
+ function GetRowAssoc()
{
$results = array();
foreach ( $this->fields as $k=>$v ) {
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
*/
+
// security - hide paths
if (!defined('ADODB_DIR')) die();
// http://support.microsoft.com/default.aspx?scid=kb;EN-US;q220918
// Alternatively use:
// CONVERT(char(12),datecol,120)
-//
-// Also if your month is showing as month-1,
-// e.g. Jan 13, 2002 is showing as 13/0/2002, then see
-// http://phplens.com/lens/lensforum/msgs.php?id=7048&x=1
-// it's a localisation problem.
//----------------------------------------------------------------
}
- function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
if ($nrows > 0 && $offset <= 0) {
$sql = preg_replace(
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
- $rs =& $this->Execute($sql,$inputarr);
+ $rs = $this->Execute($sql,$inputarr);
} else
- $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
}
- function &MetaIndexes($table,$primary=false)
+ function MetaIndexes($table,$primary=false)
{
$table = $this->qstr($table);
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
- $constraints =& $this->GetArray($sql);
+ $constraints = $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
// "Stein-Aksel Basma" <basma@accelero.no>
// tested with MSSQL 2000
- function &MetaPrimaryKeys($table)
+ function MetaPrimaryKeys($table)
{
global $ADODB_FETCH_MODE;
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(($mask));
$this->metaTablesSQL .= " AND name like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
// mssql uses a default date like Dec 30 2000 12:00AM
- function UnixDate($v)
+ static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
}
- function UnixTimeStamp($v)
+ static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
}
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$f = @mssql_fetch_field($this->_queryID, $fieldOffset);
return $rez;
}
// mssql uses a default date like Dec 30 2000 12:00AM
- function UnixDate($v)
+ static function UnixDate($v)
{
return ADORecordSet_array_mssql::UnixDate($v);
}
- function UnixTimeStamp($v)
+ static function UnixTimeStamp($v)
{
return ADORecordSet_array_mssql::UnixTimeStamp($v);
}
}
// mssql uses a default date like Dec 30 2000 12:00AM
- function UnixDate($v)
+ static function UnixDate($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixDate($v);
return mktime(0,0,0,$themth,$theday,$rr[3]);
}
- function UnixTimeStamp($v)
+ static function UnixTimeStamp($v)
{
if (is_numeric(substr($v,0,1)) && ADODB_PHPVER >= 0x4200) return parent::UnixTimeStamp($v);
<?php
/**
-* @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+* @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
$this->metaTablesSQL = $save;
return $ret;
}
- function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+ function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
function qstr($s,$magic_quotes=false)
{
if (is_null($s)) return 'NULL';
-
if (!$magic_quotes) {
if (ADODB_PHPVER >= 0x4300) {
function GetOne($sql,$inputarr=false)
{
if ($this->compat323 == false && strncasecmp($sql,'sele',4) == 0) {
- $rs =& $this->SelectLimit($sql,1,-1,$inputarr);
+ $rs = $this->SelectLimit($sql,1,-1,$inputarr);
if ($rs) {
$rs->Close();
if ($rs->EOF) return false;
return mysql_affected_rows($this->_connectionID);
}
- // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
+ // See http://www.mysql.com/doc/M/i/Miscellaneous_functions.html
// Reference on Last_Insert_ID on the recommended way to simulate sequences
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_genSeqSQL = "create table %s (id int not null)";
return $this->genID;
}
- function &MetaDatabases()
+ function MetaDatabases()
{
$qid = mysql_list_dbs($this->_connectionID);
$arr = array();
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename);
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
$this->_findschema($table,$schema);
if ($schema) {
$fld->primary_key = ($rs->fields[3] == 'PRI');
$fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
$fld->binary = (strpos($type,'blob') !== false);
- $fld->unsigned = (strpos($type,'unsigned') !== false);
+ $fld->unsigned = (strpos($type,'unsigned') !== false);
$fld->zerofill = (strpos($type,'zerofill') !== false);
-
+
if (!$fld->binary) {
$d = $rs->fields[4];
if ($d != '' && $d != 'NULL') {
}
// parameters use PostgreSQL convention, not MySQL
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
{
$offsetStr =($offset>=0) ? ((integer)$offset)."," : '';
// jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
- $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
+ $rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
else
- $rs =& $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
+ $rs = $this->Execute($sql." LIMIT $offsetStr".((integer)$nrows),$inputarr);
return $rs;
}
$this->_numOfFields = @mysql_num_fields($this->_queryID);
}
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$o = @mysql_fetch_field($this->_queryID, $fieldOffset);
$f = @mysql_field_flags($this->_queryID,$fieldOffset);
- $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com)
+ if ($o) $o->max_length = @mysql_field_len($this->_queryID,$fieldOffset); // suggested by: Jim Nicholson (jnich#att.com)
//$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
- $o->binary = (strpos($f,'binary')!== false);
+ if ($o) $o->binary = (strpos($f,'binary')!== false);
}
else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
$o = @mysql_fetch_field($this->_queryID);
- $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
+ if ($o) $o->max_length = @mysql_field_len($this->_queryID); // suggested by: Jim Nicholson (jnich#att.com)
//$o->max_length = -1; // mysql returns the max length less spaces -- so it is unrealiable
}
return $o;
}
- function &GetRowAssoc($upper=true)
+ function GetRowAssoc($upper=true)
{
if ($this->fetchMode == MYSQL_ASSOC && !$upper) $row = $this->fields;
- else $row =& ADORecordSet::GetRowAssoc($upper);
+ else $row = ADORecordSet::GetRowAssoc($upper);
return $row;
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
function GetOne($sql,$inputarr=false)
{
$ret = false;
- $rs = &$this->Execute($sql,$inputarr);
+ $rs = $this->Execute($sql,$inputarr);
if ($rs) {
if (!$rs->EOF) $ret = reset($rs->fields);
$rs->Close();
{
if ($this->transCnt==0) $this->BeginTrans();
if ($where) $where = ' where '.$where;
- $rs =& $this->Execute("select $flds from $tables $where for update");
+ $rs = $this->Execute("select $flds from $tables $where for update");
return !empty($rs);
}
// Reference on Last_Insert_ID on the recommended way to simulate sequences
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_genSeqSQL = "create table %s (id int not null)";
+ var $_genSeqCountSQL = "select count(*) from %s";
var $_genSeq2SQL = "insert into %s values (%s)";
var $_dropSeqSQL = "drop table %s";
return $this->genID;
}
- function &MetaDatabases()
+ function MetaDatabases()
{
$query = "SHOW DATABASES";
- $ret =& $this->Execute($query);
+ $ret = $this->Execute($query);
if ($ret && is_object($ret)){
$arr = array();
while (!$ret->EOF){
}
- function &MetaIndexes ($table, $primary = FALSE)
+ function MetaIndexes ($table, $primary = FALSE)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
// return "from_unixtime(unix_timestamp($date)+$fraction)";
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
$this->metaTablesSQL = $save;
return $ret;
return $foreign_keys;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
$false = false;
if (!$this->metaColumnsSQL)
}
// parameters use PostgreSQL convention, not MySQL
- function &SelectLimit($sql,
+ function SelectLimit($sql,
$nrows = -1,
$offset = -1,
$inputarr = false,
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
- $rs =& $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr);
+ $rs = $this->CacheExecute($secs, $sql . " LIMIT $offsetStr$nrows" , $inputarr );
else
- $rs =& $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr);
+ $rs = $this->Execute($sql . " LIMIT $offsetStr$nrows" , $inputarr );
return $rs;
}
131072 = MYSQLI_BINCMP_FLAG
*/
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
$fieldnr = $fieldOffset;
if ($fieldOffset != -1) {
return $o;
}
- function &GetRowAssoc($upper = true)
+ function GetRowAssoc($upper = true)
{
if ($this->fetchMode == MYSQLI_ASSOC && !$upper)
return $this->fields;
- $row =& ADORecordSet::GetRowAssoc($upper);
+ $row = ADORecordSet::GetRowAssoc($upper);
return $row;
}
}
class ADORecordSet_array_mysqli extends ADORecordSet_array {
+
function ADORecordSet_array_mysqli($id=-1,$mode=false)
{
$this->ADORecordSet_array($id,$mode);
}
-
function MetaType($t, $len = -1, $fieldobj = false)
{
if (is_object($t)) {
}
-?>
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/*
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ Released under both BSD license and Lesser GPL library license.
+ Whenever there is any discrepancy between the two licenses,
+ the BSD license will take precedence.
+ Set tabs to 8.
+
+ MySQL code that supports transactions. For MySQL 3.23 or later.
+ Code from James Poon <jpoon88@yahoo.com>
+
+ Requires mysql client. Works on Windows and Unix.
+*/
+
+// security - hide paths
+if (!defined('ADODB_DIR')) die();
+
+include_once(ADODB_DIR."/drivers/adodb-mysql.inc.php");
+
+
+class ADODB_mysqlt extends ADODB_mysql {
+ var $databaseType = 'mysqlt';
+ var $ansiOuter = true; // for Version 3.23.17 or later
+ var $hasTransactions = true;
+ var $autoRollback = true; // apparently mysql does not autorollback properly
+
+ function ADODB_mysqlt()
+ {
+ global $ADODB_EXTENSION; if ($ADODB_EXTENSION) $this->rsPrefix .= 'ext_';
+ }
+
+ function BeginTrans()
+ {
+ if ($this->transOff) return true;
+ $this->transCnt += 1;
+ $this->Execute('SET AUTOCOMMIT=0');
+ $this->Execute('BEGIN');
+ return true;
+ }
+
+ function CommitTrans($ok=true)
+ {
+ if ($this->transOff) return true;
+ if (!$ok) return $this->RollbackTrans();
+
+ if ($this->transCnt) $this->transCnt -= 1;
+ $this->Execute('COMMIT');
+ $this->Execute('SET AUTOCOMMIT=1');
+ return true;
+ }
+
+ function RollbackTrans()
+ {
+ if ($this->transOff) return true;
+ if ($this->transCnt) $this->transCnt -= 1;
+ $this->Execute('ROLLBACK');
+ $this->Execute('SET AUTOCOMMIT=1');
+ return true;
+ }
+
+ function RowLock($tables,$where='',$flds='1 as adodb_ignore')
+ {
+ if ($this->transCnt==0) $this->BeginTrans();
+ if ($where) $where = ' where '.$where;
+ $rs = $this->Execute("select $flds from $tables $where for update");
+ return !empty($rs);
+ }
+
+}
+
+class ADORecordSet_mysqlt extends ADORecordSet_mysql{
+ var $databaseType = "mysqlt";
+
+ function ADORecordSet_mysqlt($queryID,$mode=false)
+ {
+ if ($mode === false) {
+ global $ADODB_FETCH_MODE;
+ $mode = $ADODB_FETCH_MODE;
+ }
+
+ switch ($mode)
+ {
+ case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
+ case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
+
+ case ADODB_FETCH_DEFAULT:
+ case ADODB_FETCH_BOTH:
+ default: $this->fetchMode = MYSQL_BOTH; break;
+ }
+
+ $this->adodbFetchMode = $mode;
+ $this->ADORecordSet($queryID);
+ }
+
+ function MoveNext()
+ {
+ if (@$this->fields = mysql_fetch_array($this->_queryID,$this->fetchMode)) {
+ $this->_currentRow += 1;
+ return true;
+ }
+ if (!$this->EOF) {
+ $this->_currentRow += 1;
+ $this->EOF = true;
+ }
+ return false;
+ }
+}
+
+class ADORecordSet_ext_mysqlt extends ADORecordSet_mysqlt {
+
+ function ADORecordSet_ext_mysqlt($queryID,$mode=false)
+ {
+ if ($mode === false) {
+ global $ADODB_FETCH_MODE;
+ $mode = $ADODB_FETCH_MODE;
+ }
+ switch ($mode)
+ {
+ case ADODB_FETCH_NUM: $this->fetchMode = MYSQL_NUM; break;
+ case ADODB_FETCH_ASSOC:$this->fetchMode = MYSQL_ASSOC; break;
+
+ case ADODB_FETCH_DEFAULT:
+ case ADODB_FETCH_BOTH:
+ default:
+ $this->fetchMode = MYSQL_BOTH; break;
+ }
+ $this->adodbFetchMode = $mode;
+ $this->ADORecordSet($queryID);
+ }
+
+ function MoveNext()
+ {
+ return adodb_movenext($this);
+ }
+}
+
+?>
\ No newline at end of file
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
{
if ($this->transCnt==0) $this->BeginTrans();
if ($where) $where = ' where '.$where;
- $rs =& $this->Execute("select $flds from $tables $where for update");
+ $rs = $this->Execute("select $flds from $tables $where for update");
return !empty($rs);
}
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
First cut at the Netezza Driver by Josh Eldridge joshuae74#hotmail.com
Based on the previous postgres drivers.
}
- function &MetaColumns($table,$upper=true)
+ function MetaColumns($table,$upper=true)
{
// Changed this function to support Netezza which has no concept of keys
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
- $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+ $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
<?php
/*
- version V4.98 13 Feb 2008 (c) 2000-2008 John Lim. All rights reserved.
+ version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim. All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
var $firstrows = true; // enable first rows optimization on SelectLimit()
var $selectOffsetAlg1 = 100; // when to use 1st algorithm of selectlimit.
var $NLS_DATE_FORMAT = 'YYYY-MM-DD'; // To include time, use 'RRRR-MM-DD HH24:MI:SS'
- var $dateformat = 'YYYY-MM-DD'; // for DBDate()
+ var $dateformat = 'YYYY-MM-DD'; // DBDate format
var $useDBDateFormatForTextInput=false;
var $datetime = false; // MetaType('DATE') returns 'D' (datetime==false) or 'T' (datetime == true)
var $_refLOBs = array();
-
+
// var $ansiOuter = true; // if oracle9
function ADODB_oci8()
if (defined('ADODB_EXTENSION')) $this->rsPrefix .= 'ext_';
}
- /* Function &MetaColumns($table) added by smondino@users.sourceforge.net*/
- function &MetaColumns($table)
+ /* function MetaColumns($table) added by smondino@users.sourceforge.net*/
+ function MetaColumns($table)
{
global $ADODB_FETCH_MODE;
function Time()
{
- $rs =& $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
+ $rs = $this->Execute("select TO_CHAR($this->sysTimeStamp,'YYYY-MM-DD HH24:MI:SS') from dual");
if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
return false;
return $this->GetOne("select $flds from $tables where $where for update");
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(strtoupper($mask));
$this->metaTablesSQL .= " AND upper(table_name) like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
}
// Mark Newnham
- function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+ function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
This implementation does not appear to work with oracle 8.0.5 or earlier. Comment
out this function then, and the slower SelectLimit() in the base class will be used.
*/
- function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
// seems that oracle only supports 1 hint comment in 8i
if ($this->firstrows) {
$sql = preg_replace('/^[ \t\n]*select/i','SELECT /*+FIRST_ROWS*/',$sql);
}
- if ($offset < $this->selectOffsetAlg1 && 0 < $nrows && $nrows < 1000) {
+ if ($offset < $this->selectOffsetAlg1 && 0 < $nrows && $nrows < 1000) {
if ($nrows > 0) {
if ($offset > 0) $nrows += $offset;
//$inputarr['adodb_rownum'] = $nrows;
}
// note that $nrows = 0 still has to work ==> no rows returned
- $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
} else {
$inputarr['adodb_nrows'] = $nrows;
$inputarr['adodb_offset'] = $offset;
- if ($secs2cache>0) $rs =& $this->CacheExecute($secs2cache, $sql,$inputarr);
- else $rs =& $this->Execute($sql,$inputarr);
+ if ($secs2cache>0) $rs = $this->CacheExecute($secs2cache, $sql,$inputarr);
+ else $rs = $this->Execute($sql,$inputarr);
return $rs;
}
* @param [inputarr] holds the input data to bind to. Null elements will be set to null.
* @return RecordSet or false
*/
- function &Execute($sql,$inputarr=false)
+ function Execute($sql,$inputarr=false)
{
if ($this->fnExecute) {
$fn = $this->fnExecute;
- $ret =& $fn($this,$sql,$inputarr);
+ $ret = $fn($this,$sql,$inputarr);
if (isset($ret)) return $ret;
}
if ($inputarr) {
#if (!is_array($inputarr)) $inputarr = array($inputarr);
+
$element0 = reset($inputarr);
+ if (!$this->_bindInputArray) {
# is_object check because oci8 descriptors can be passed in
if (is_array($element0) && !is_object(reset($element0))) {
if (is_string($sql))
$stmt = $sql;
foreach($inputarr as $arr) {
- $ret =& $this->_Execute($stmt,$arr);
+ $ret = $this->_Execute($stmt,$arr);
if (!$ret) return $ret;
}
} else {
- $ret =& $this->_Execute($sql,$inputarr);
+ $sqlarr = explode(':',$sql);
+ $sql = '';
+ $lastnomatch = -2;
+ #var_dump($sqlarr);echo "<hr>";var_dump($inputarr);echo"<hr>";
+ foreach($sqlarr as $k => $str) {
+ if ($k == 0) { $sql = $str; continue; }
+ // we need $lastnomatch because of the following datetime,
+ // eg. '10:10:01', which causes code to think that there is bind param :10 and :1
+ $ok = preg_match('/^([0-9]*)/', $str, $arr);
+
+ if (!$ok) $sql .= $str;
+ else {
+ $at = $arr[1];
+ if (isset($inputarr[$at]) || is_null($inputarr[$at])) {
+ if ((strlen($at) == strlen($str) && $k < sizeof($arr)-1)) {
+ $sql .= ':'.$str;
+ $lastnomatch = $k;
+ } else if ($lastnomatch == $k-1) {
+ $sql .= ':'.$str;
+ } else {
+ if (is_null($inputarr[$at])) $sql .= 'null';
+ else $sql .= $this->qstr($inputarr[$at]);
+ $sql .= substr($str, strlen($at));
+ }
+ } else {
+ $sql .= ':'.$str;
+ }
+
+ }
+ }
+ $inputarr = false;
+ }
}
+ $ret = $this->_Execute($sql,$inputarr);
+
} else {
- $ret =& $this->_Execute($sql,false);
+ $ret = $this->_Execute($sql,false);
}
return $ret;
array('VAR1' => 'Mr Bean'));
*/
- function &ExecuteCursor($sql,$cursorName='rs',$params=false)
+ function ExecuteCursor($sql,$cursorName='rs',$params=false)
{
if (is_array($sql)) $stmt = $sql;
else $stmt = ADODB_oci8::Prepare($sql,true); # true to allocate OCINewCursor
} else
$hasref = false;
- $rs =& $this->Execute($stmt);
+ $rs = $this->Execute($stmt);
if ($rs) {
if ($rs->databaseType == 'array') OCIFreeCursor($stmt[4]);
else if ($hasref) $rs->_refcursor = $stmt[4];
$this->_refLOBs[$numlob]['LOB'] = OCINewDescriptor($this->_connectionID, oci_lob_desc($type));
$this->_refLOBs[$numlob]['TYPE'] = $isOutput;
- $tmp = &$this->_refLOBs[$numlob]['LOB'];
+ $tmp = $this->_refLOBs[$numlob]['LOB'];
$rez = OCIBindByName($stmt[1], ":".$name, $tmp, -1, $type);
if ($this->debug) {
ADOConnection::outp("<b>Bind</b>: descriptor has been allocated, var (".$name.") binded");
if ($isOutput == false) {
$var = $this->BlobEncode($var);
$tmp->WriteTemporary($var);
- $this->_refLOBs[$numlob]['VAR'] = &$var;
+ $this->_refLOBs[$numlob]['VAR'] = $var;
if ($this->debug) {
ADOConnection::outp("<b>Bind</b>: LOB has been written to temp");
}
} else {
- $this->_refLOBs[$numlob]['VAR'] = &$var;
+ $this->_refLOBs[$numlob]['VAR'] = $var;
}
$rez = $tmp;
} else {
$bindpos = $sql[3];
if (isset($this->_bind[$bindpos])) {
// all tied up already
- $bindarr = &$this->_bind[$bindpos];
+ $bindarr = $this->_bind[$bindpos];
} else {
// one statement to bind them all
$bindarr = array();
$bindarr[$k] = $v;
OCIBindByName($stmt,":$k",$bindarr[$k],is_string($v) && strlen($v)>4000 ? -1 : 4000);
}
- $this->_bind[$bindpos] = &$bindarr;
+ $this->_bind[$bindpos] = $bindarr;
}
}
} else {
else
OCIBindByName($stmt,":$k",$inputarr[$k][0],$v[1],$v[2]);
- if ($this->debug==99) echo "name=:$k",' var='.$inputarr[$k][0],' len='.$v[1],' type='.$v[2],'<br>';
+ if ($this->debug==99) {
+ if (is_object($v[0]))
+ echo "name=:$k",' len='.$v[1],' type='.$v[2],'<br>';
+ else
+ echo "name=:$k",' var='.$inputarr[$k][0],' len='.$v[1],' type='.$v[2],'<br>';
+
+ }
} else {
$len = -1;
if ($v === ' ') $len = 1;
$rs = $this->Execute($sql);
if ($rs && !$rs->EOF) {
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$a = array();
foreach($arr as $v) {
$a[] = reset($v);
from {$tabp}constraints
where constraint_type = 'R' and table_name = $table $owner";
- $constraints =& $this->GetArray($sql);
+ $constraints = $this->GetArray($sql);
$arr = false;
foreach($constraints as $constr) {
$cons = $this->qstr($constr[0]);
}
/* For some reason, OCIcolumnname fails when called after _initrs() so we cache it */
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
return $this->_fieldobjs[$fieldOffset];
}
/*
# does not work as first record is retrieved in _initrs(), so is not included in GetArray()
- function &GetArray($nRows = -1)
+ function GetArray($nRows = -1)
{
global $ADODB_OCI8_GETARRAY;
if (ADODB_ASSOC_CASE != 2 || $this->databaseType != 'oci8') break;
$ncols = @OCIfetchstatement($this->_queryID, $assoc, 0, $nRows, OCI_FETCHSTATEMENT_BY_ROW);
- $results =& array_merge(array($this->fields),$assoc);
+ $results = array_merge(array($this->fields),$assoc);
return $results;
default:
}
}
- $results =& ADORecordSet::GetArray($nRows);
+ $results = ADORecordSet::GetArray($nRows);
return $results;
} */
/* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
- function &GetArrayLimit($nrows,$offset=-1)
+ function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
- $arr =& $this->GetArray($nrows);
+ $arr = $this->GetArray($nrows);
return $arr;
}
$arr = array();
<?php
/**
- * @version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ * @version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
$this->ADODB_oci8();
}
- function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
// seems that oracle only supports 1 hint comment in 8i
if (strpos($sql,'/*+') !== false)
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim. All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim. All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
// lowercase field names...
- function &_FetchField($fieldOffset = -1)
+ function _FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$fieldOffset += 1;
}
/* Optimize SelectLimit() by using OCIFetch() instead of OCIFetchInto() */
- function &GetArrayLimit($nrows,$offset=-1)
+ function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
$arr = $this->GetArray($nrows);
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
if (!$rs) return false;
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$rs->Close();
//print_r($arr);
$arr2 = array();
- function &MetaTables($ttype=false)
+ function MetaTables($ttype=false)
{
global $ADODB_FETCH_MODE;
}
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
//print_r($arr);
$rs->Close();
}
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
global $ADODB_FETCH_MODE;
}
if (empty($qid)) return $false;
- $rs =& new ADORecordSet_odbc($qid);
+ $rs = new ADORecordSet_odbc($qid);
$ADODB_FETCH_MODE = $savem;
if (!$rs) return $false;
// returns the field object
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
$off=$fieldOffset+1; // offsets begin at 1
}
// speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated
- function &GetArrayLimit($nrows,$offset=-1)
+ function GetArrayLimit($nrows,$offset=-1)
{
if ($offset <= 0) {
- $rs =& $this->GetArray($nrows);
+ $rs = $this->GetArray($nrows);
return $rs;
}
$savem = $this->fetchMode;
$this->fetchMode = $savem;
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
$results = array();
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
return true;
}
}
if ($rez) {
if ($this->fetchMode & ADODB_FETCH_ASSOC) {
- $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE);
+ $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
}
return true;
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
return $this->GetOne("select $flds from $tables where $where for update");
}
- function &MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%")
+ function MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%")
{
global $ADODB_FETCH_MODE;
}
$rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
//print_r($arr);
$rs->Close();
return $arr2;
}
- function &MetaIndexes ($table, $primary = FALSE, $owner=false)
+ function MetaIndexes ($table, $primary = FALSE, $owner=false)
{
// save old fetch mode
global $ADODB_FETCH_MODE;
}
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
{
$nrows = (integer) $nrows;
if ($offset <= 0) {
// could also use " OPTIMIZE FOR $nrows ROWS "
if ($nrows >= 0) $sql .= " FETCH FIRST $nrows ROWS ONLY ";
- $rs =& $this->Execute($sql,$inputArr);
+ $rs = $this->Execute($sql,$inputArr);
} else {
if ($offset > 0 && $nrows < 0);
else {
$nrows += $offset;
$sql .= " FETCH FIRST $nrows ROWS ONLY ";
}
- $rs =& ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
+ $rs = ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
}
return $rs;
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
where upper(object_name(fkeyid)) = $table
order by constraint_name, referenced_table_name, keyno";
- $constraints =& $this->GetArray($sql);
+ $constraints = $this->GetArray($sql);
$ADODB_FETCH_MODE = $save;
return $arr2;
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {$this->debug=1;
$save = $this->metaTablesSQL;
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " AND name like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
return $ret;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
$arr = ADOConnection::MetaColumns($table);
return $arr;
}
- function &MetaIndexes($table,$primary=false)
+ function MetaIndexes($table,$primary=false)
{
$table = $this->qstr($table);
// "Stein-Aksel Basma" <basma@accelero.no>
// tested with MSSQL 2000
- function &MetaPrimaryKeys($table)
+ function MetaPrimaryKeys($table)
{
global $ADODB_FETCH_MODE;
return $false;
}
- function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
if ($nrows > 0 && $offset <= 0) {
$sql = preg_replace(
'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
- $rs =& $this->Execute($sql,$inputarr);
+ $rs = $this->Execute($sql,$inputarr);
} else
- $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
$this->ADODB_odbc();
}
- function &MetaTables()
+ function MetaTables()
{
$false = false;
$rs = $this->Execute($this->metaTablesSQL);
return $arr2;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
global $ADODB_FETCH_MODE;
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
return true;
}
- function &MetaTables($ttype='',$showSchema=false,$mask=false)
+ function MetaTables($ttype='',$showSchema=false,$mask=false)
{
global $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savefm = $this->SetFetchMode(false);
- $arr =& $this->GetArray("||SQLTables||||$ttype");
+ $arr = $this->GetArray("||SQLTables||||$ttype");
if (isset($savefm)) $this->SetFetchMode($savefm);
$ADODB_FETCH_MODE = $savem;
return $arr2;
}
- function &MetaColumns($table,$upper=true)
+ function MetaColumns($table,$upper=true)
{
global $ADODB_FETCH_MODE;
return $retarr;
}
- function &MetaPrimaryKeys($table, $owner='')
+ function MetaPrimaryKeys($table, $owner='')
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- $arr =& $this->GetArray("||SQLPrimaryKeys||$owner|$table");
+ $arr = $this->GetArray("||SQLPrimaryKeys||$owner|$table");
$ADODB_FETCH_MODE = $savem;
//print_r($arr);
return $arr2;
}
- function &MetaForeignKeys($table, $owner='', $upper=false)
+ function MetaForeignKeys($table, $owner='', $upper=false)
{
global $ADODB_FETCH_MODE;
$savem = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- $constraints =& $this->GetArray("||SQLForeignKeys|||||$owner|$table");
+ $constraints = $this->GetArray("||SQLForeignKeys|||||$owner|$table");
$ADODB_FETCH_MODE = $savem;
$arr = false;
return $ret;
}
- function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
// TOP requires ORDER BY for Visual FoxPro
if( $this->odbc_driver == ODB_DRIVER_FOXPRO ) {
if (!preg_match('/ORDER[ \t\r\n]+BY/is',$sql)) $sql .= ' ORDER BY 1';
}
- $ret =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $ret;
}
}
}
- function &FetchField($fieldOffset = 0)
+ function FetchField($fieldOffset = 0)
{
$off=$fieldOffset; // offsets begin at 0
$o= new ADOFieldObject();
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$fld->name = ora_columnname($this->_queryID, $fieldOffset);
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
+
+
+
class ADODB_pdo extends ADOConnection {
var $databaseType = "pdo";
var $dataProvider = "pdo";
function _UpdatePDO()
{
- $d = &$this->_driver;
+ $d = $this->_driver;
$this->fmtDate = $d->fmtDate;
$this->fmtTimeStamp = $d->fmtTimeStamp;
$this->replaceQuote = $d->replaceQuote;
if (!empty($this->_driver->_hasdual)) $sql = "select $this->sysTimeStamp from dual";
else $sql = "select $this->sysTimeStamp";
- $rs =& $this->_Execute($sql);
+ $rs = $this->_Execute($sql);
if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
return false;
}
}
-
-
class ADODB_pdo_base extends ADODB_pdo {
var $sysDate = "'?'";
}
}
-
class ADOPDOStatement {
var $databaseType = "pdo";
}
// returns the field object
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
$off=$fieldOffset+1; // offsets begin at 1
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
var $hasGenID = true;
var $_genIDSQL = "update %s set id=LAST_INSERT_ID(id+1);";
var $_dropSeqSQL = "drop table %s";
-
+
var $nameQuote = '`';
function _init($parentDriver)
return $arr;
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$save = $this->metaTablesSQL;
if ($showSchema && is_string($showSchema)) {
$mask = $this->qstr($mask);
$this->metaTablesSQL .= " like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
$this->metaTablesSQL = $save;
return $ret;
$this->Execute("SET SESSION TRANSACTION ".$transaction_mode);
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
$this->_findschema($table,$schema);
if ($schema) {
// parameters use PostgreSQL convention, not MySQL
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs=0)
{
$offsetStr =($offset>=0) ? "$offset," : '';
// jason judge, see http://phplens.com/lens/lensforum/msgs.php?id=9220
if ($nrows < 0) $nrows = '18446744073709551615';
if ($secs)
- $rs =& $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
+ $rs = $this->CacheExecute($secs,$sql." LIMIT $offsetStr$nrows",$inputarr);
else
- $rs =& $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
+ $rs = $this->Execute($sql." LIMIT $offsetStr$nrows",$inputarr);
return $rs;
}
}
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
if ($mask) {
$save = $this->metaTablesSQL;
$mask = $this->qstr(strtoupper($mask));
$this->metaTablesSQL .= " AND table_name like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
return $ret;
}
- function &MetaColumns($table)
+ function MetaColumns($table)
{
global $ADODB_FETCH_MODE;
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
return $arr;
}
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : '';
if ($secs2cache)
- $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+ $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
else
- $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+ $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
return $rs;
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$info = $this->ServerInfo();
if ($info['version'] >= 7.3) {
union
select viewname,'V' from pg_views where viewname like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
return $ret;
}
- function &MetaColumns($table,$normalize=true)
+ function MetaColumns($table,$normalize=true)
{
global $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
- if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
- else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+ if ($schema) $rs = $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
+ else $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
$rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
// fetch all result in once for performance.
- $keys =& $rskey->GetArray();
+ $keys = $rskey->GetArray();
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
return @pg_Exec($this->_connectionID, "rollback");
}
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$info = $this->ServerInfo();
if ($info['version'] >= 7.3) {
union
select viewname,'V' from pg_views where viewname like $mask";
}
- $ret =& ADOConnection::MetaTables($ttype,$showSchema);
+ $ret = ADOConnection::MetaTables($ttype,$showSchema);
if ($mask) {
$this->metaTablesSQL = $save;
// for schema support, pass in the $table param "$schema.$tabname".
// converts field names to lowercase, $upper is ignored
// see http://phplens.com/lens/lensforum/msgs.php?id=14018 for more info
- function &MetaColumns($table,$normalize=true)
+ function MetaColumns($table,$normalize=true)
{
global $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
- if ($schema) $rs =& $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
- else $rs =& $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
+ if ($schema) $rs = $this->Execute(sprintf($this->metaColumnsSQL1,$table,$table,$schema));
+ else $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table,$table));
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
$rskey = $this->Execute(sprintf($this->metaKeySQL,($table)));
// fetch all result in once for performance.
- $keys =& $rskey->GetArray();
+ $keys = $rskey->GetArray();
if (isset($savem)) $this->SetFetchMode($savem);
$ADODB_FETCH_MODE = $save;
}
- function &MetaIndexes ($table, $primary = FALSE)
+ function MetaIndexes ($table, $primary = FALSE)
{
global $ADODB_FETCH_MODE;
$this->ADORecordSet($queryID);
}
- function &GetRowAssoc($upper=true)
+ function GetRowAssoc($upper=true)
{
if ($this->fetchMode == PGSQL_ASSOC && !$upper) return $this->fields;
- $row =& ADORecordSet::GetRowAssoc($upper);
+ $row = ADORecordSet::GetRowAssoc($upper);
return $row;
}
return $this->fields[$this->bind[strtoupper($colname)]];
}
- function &FetchField($off = 0)
+ function FetchField($off = 0)
{
// offsets begin at 0
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
// the following should be compat with postgresql 7.2,
// which makes obsolete the LIMIT limit,offset syntax
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$offsetStr = ($offset >= 0) ? " OFFSET ".((integer)$offset) : '';
$limitStr = ($nrows >= 0) ? " LIMIT ".((integer)$nrows) : '';
if ($secs2cache)
- $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+ $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
else
- $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+ $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
return $rs;
}
ORDER BY
t.tgrelid';
- $rs =& $this->Execute($sql);
+ $rs = $this->Execute($sql);
if (!$rs || $rs->EOF) return false;
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$a = array();
foreach($arr as $v) {
$data = explode(chr(0), $v['args']);
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
return $this->GetCol("SELECT columnname FROM COLUMNS WHERE tablename=$table AND mode='KEY' ORDER BY pos");
}
- function &MetaIndexes ($table, $primary = FALSE)
+ function MetaIndexes ($table, $primary = FALSE)
{
$table = $this->Quote(strtoupper($table));
return $indexes;
}
- function &MetaColumns ($table)
+ function MetaColumns ($table)
{
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
<?php
/*
-version V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights
+version V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights
reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
// mark newnham
- function &MetaColumns($tab)
+ function MetaColumns($tab)
{
global $ADODB_FETCH_MODE;
$false = false;
return $rez;
}
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
$offsetStr = ($offset >= 0) ? " OFFSET $offset" : '';
$limitStr = ($nrows >= 0) ? " LIMIT $nrows" : ($offset >= 0 ? ' LIMIT 999999999' : '');
if ($secs2cache)
- $rs =& $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
+ $rs = $this->CacheExecute($secs2cache,$sql."$limitStr$offsetStr",$inputarr);
else
- $rs =& $this->Execute($sql."$limitStr$offsetStr",$inputarr);
+ $rs = $this->Execute($sql."$limitStr$offsetStr",$inputarr);
return $rs;
}
return @sqlite_close($this->_connectionID);
}
- function &MetaIndexes($table, $primary = FALSE, $owner=false)
+ function MetaIndexes($table, $primary = FALSE, $owner=false)
{
$false = false;
// save old fetch mode
}
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
$fld = new ADOFieldObject;
$fld->name = sqlite_field_name($this->_queryID, $fieldOffset);
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim. All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim. All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
// See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
- function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
{
if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
- $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+ $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
return $rs;
}
if ($offset > 0 && $cnt) $cnt += $offset;
$this->Execute("set rowcount $cnt");
- $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0);
+ $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0);
$this->Execute("set rowcount 0");
return $rs;
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
- function &FetchField($fieldOffset = -1)
+ function FetchField($fieldOffset = -1)
{
if ($fieldOffset != -1) {
$o = @sybase_fetch_field($this->_queryID, $fieldOffset);
<?php
/*
- V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+ V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
}
// split the Views, Tables and procedures.
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
+ function MetaTables($ttype=false,$showSchema=false,$mask=false)
{
$false = false;
if ($this->metaTablesSQL) {
if ($rs === false || !method_exists($rs, 'GetArray')){
return $false;
}
- $arr =& $rs->GetArray();
+ $arr = $rs->GetArray();
$arr2 = array();
foreach($arr as $key=>$value){
}
// fix a bug which prevent the metaColumns query to be executed for Sybase ASE
- function &MetaColumns($table,$upper=false)
+ function MetaColumns($table,$upper=false)
{
$false = false;
if (!empty($this->metaColumnsSQL)) {
$retarr = array();
while (!$rs->EOF) {
- $fld =& new ADOFieldObject();
+ $fld = new ADOFieldObject();
$fld->name = $rs->Fields('field_name');
$fld->type = $rs->Fields('type');
$fld->max_length = $rs->Fields('width');
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
// TOP requires ORDER BY for VFP
- function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+ function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
{
$this->hasTop = preg_match('/ORDER[ \t\r\n]+BY/is',$sql) ? 'top' : false;
$ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
function perf_db2(&$conn)
{
- $this->conn =& $conn;
+ $this->conn = $conn;
}
function Explain($sql,$partial=false)
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
function perf_informix(&$conn)
{
- $this->conn =& $conn;
+ $this->conn = $conn;
}
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
$this->sql1 = 'sql1';
//$this->explain = false;
}
- $this->conn =& $conn;
+ $this->conn = $conn;
}
function Explain($sql,$partial=false)
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- $rs =& $this->conn->Execute($sql);
+ $rs = $this->conn->Execute($sql);
//adodb_printr($rs);
$ADODB_FETCH_MODE = $save;
if ($rs) {
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
function perf_mysql(&$conn)
{
- $this->conn =& $conn;
+ $this->conn = $conn;
}
function Explain($sql,$partial=false)
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
where name = 'free memory' and pool = 'shared pool'",
'Percentage of data cache actually in use - should be over 85%'),
- 'shared pool utilization ratio' => array('RATIOU',
+ 'shared pool utilization ratio' => array('RATIOU',
'select round((sga.bytes/case when p.value=0 then sga.bytes else to_number(p.value) end)*100,2)
from v$sgastat sga, v$parameter p
where sga.name = \'free memory\' and sga.pool = \'shared pool\'
'random page cost' => array('COST',
"select value from v\$parameter where name = 'optimizer_index_cost_adj'",
'=WarnPageCost'),
-
+
'Backup',
'Achivelog Mode' => array('BACKUP', 'select log_mode from v$database', 'To turn on archivelog:<br>
<pre>
$savelog = $conn->LogSQL(false);
$this->version = $conn->ServerInfo();
$conn->LogSQL($savelog);
- $this->conn =& $conn;
+ $this->conn = $conn;
}
function WarnPageCost($val)
function Explain($sql,$partial=false)
{
$savelog = $this->conn->LogSQL(false);
- $rs =& $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
+ $rs = $this->conn->SelectLimit("select ID FROM PLAN_TABLE");
if (!$rs) {
echo "<p><b>Missing PLAN_TABLE</b></p>
<pre>
$this->conn->BeginTrans();
$id = "ADODB ".microtime();
- $rs =& $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
+ $rs = $this->conn->Execute("EXPLAIN PLAN SET STATEMENT_ID='$id' FOR $sql");
$m = $this->conn->ErrorMsg();
if ($m) {
$this->conn->RollbackTrans();
$s .= "<p>$m</p>";
return $s;
}
- $rs =& $this->conn->Execute("
+ $rs = $this->conn->Execute("
select
'<pre>'||lpad('--', (level-1)*2,'-') || trim(operation) || ' ' || trim(options)||'</pre>' as Operation,
object_name,COST,CARDINALITY,bytes
{
if ($this->version['version'] < 9) return 'Oracle 9i or later required';
- $rs =& $this->conn->Execute("
+ $rs = $this->conn->Execute("
select a.size_for_estimate as cache_mb_estimate,
case when a.size_factor=1 then
'<<= current'
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
$savelog = $this->conn->LogSQL(false);
- $rs =& $this->conn->SelectLimit($sql);
+ $rs = $this->conn->SelectLimit($sql);
$this->conn->LogSQL($savelog);
if (isset($savem)) $this->conn->SetFetchMode($savem);
if ($this->conn->fetchMode !== false) $savem = $this->conn->SetFetchMode(false);
$savelog = $this->conn->LogSQL(false);
- $rs =& $this->conn->Execute($sql);
+ $rs = $this->conn->Execute($sql);
$this->conn->LogSQL($savelog);
if (isset($savem)) $this->conn->SetFetchMode($savem);
function clearsql()
{
- $this->conn->debug=1;
$perf_table = adodb_perf::table();
// using the naive "delete from $perf_table where created<".$this->conn->sysTimeStamp will cause the table to lock, possibly
// for a long time
$ok = $this->conn->Execute($sql);
}
+
}
?>
\ No newline at end of file
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
function perf_postgres(&$conn)
{
- $this->conn =& $conn;
+ $this->conn = $conn;
}
var $optimizeTableLow = 'VACUUM %s';
return $conn->Execute($sql) !== false;
}
-
-
function Explain($sql,$partial=false)
{
$save = $this->conn->LogSQL(false);
-Description of ADODB v4.98 library import into Moodle
+Description of ADODB V5.04a library import into Moodle
Removed:
* contrib/
}
$rs = RSFilter($rs,'do_ucwords');
*/
-function &RSFilter($rs,$fn)
+function RSFilter($rs,$fn)
{
if ($rs->databaseType != 'array') {
if (!$rs->connection) return false;
- $rs = &$rs->connection->_rs2rs($rs);
+ $rs = $rs->connection->_rs2rs($rs);
}
$rows = $rs->RecordCount();
for ($i=0; $i < $rows; $i++) {
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
/**
*/
function write($data, $key) {
- $md5crypt =& new MD5Crypt();
+ $md5crypt = new MD5Crypt();
return $md5crypt->encrypt($data, $key);
}
/**
*/
function read($data, $key) {
- $md5crypt =& new MD5Crypt();
+ $md5crypt = new MD5Crypt();
return $md5crypt->decrypt($data, $key);
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
-<?php
-if (!defined('ADODB_SESSION')) die();
-
-include_once ADODB_SESSION . '/crypt.inc.php';
-
-
-/**
-
- */
-
-class ADODB_Encrypt_SHA1 {
-
- function write($data, $key)
- {
- $sha1crypt =& new SHA1Crypt();
- return $sha1crypt->encrypt($data, $key);
-
- }
-
-
- function read($data, $key)
- {
- $sha1crypt =& new SHA1Crypt();
- return $sha1crypt->decrypt($data, $key);
-
- }
-}
-
-
-
-return 1;
+<?php\r
+if (!defined('ADODB_SESSION')) die();\r
+\r
+include_once ADODB_SESSION . '/crypt.inc.php';\r
+\r
+\r
+/**\r
+\r
+ */\r
+\r
+class ADODB_Encrypt_SHA1 {\r
+\r
+ function write($data, $key) \r
+ {\r
+ $sha1crypt = new SHA1Crypt();\r
+ return $sha1crypt->encrypt($data, $key);\r
+\r
+ }\r
+\r
+\r
+ function read($data, $key) \r
+ {\r
+ $sha1crypt = new SHA1Crypt();\r
+ return $sha1crypt->decrypt($data, $key);\r
+\r
+ }\r
+}\r
+\r
+\r
+\r
+return 1;\r
?>
\ No newline at end of file
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
*/
function adodb_session_regenerate_id()
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
if (!$conn) return false;
$old_id = session_id();
//@session_start();
}
$new_id = session_id();
- $ok =& $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
+ $ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
/* it is possible that the update statement fails due to a collision */
if (!$ok) {
{
// set default values
if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema.xml';
- if ($conn===null) $conn =& ADODB_Session::_conn();
+ if ($conn===null) $conn = ADODB_Session::_conn();
if (!$conn) return 0;
/*!
*/
- function &_conn($conn=null) {
+ function _conn($conn=null) {
return $GLOBALS['ADODB_SESS_CONN'];
}
/*!
*/
function _dumprs($rs) {
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$debug = ADODB_Session::debug();
if (!$conn) {
*/
function open($save_path, $session_name, $persist = null)
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
if ($conn) {
return true;
# assert('$driver');
# assert('$host');
- $conn =& ADONewConnection($driver);
+ $conn = ADONewConnection($driver);
if ($debug) {
$conn->debug = true;
$ok = $conn->Connect($host, $user, $password, $database);
}
- if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
+ if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn;
else
ADOConnection::outp('<p>Session: connection failed</p>', false);
function close()
{
/*
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
if ($conn) $conn->Close();
*/
return true;
*/
function read($key)
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$data = ADODB_Session::dataFieldName();
$filter = ADODB_Session::filter();
$table = ADODB_Session::table();
developer has commited elsewhere... :(
*/
#if (ADODB_Session::Lock())
- # $rs =& $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), $data);
+ # $rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), $data);
#else
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
//ADODB_Session::_dumprs($rs);
if ($rs) {
if ($rs->EOF) {
if (!empty($ADODB_SESSION_READONLY)) return;
$clob = ADODB_Session::clob();
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$crc = ADODB_Session::_crc();
$data = ADODB_Session::dataFieldName();
$debug = ADODB_Session::debug();
$sql = "UPDATE $table SET expiry = ".$conn->Param('0').",expireref=".$conn->Param('1')." WHERE $binary sesskey = ".$conn->Param('2')." AND expiry >= ".$conn->Param('3');
- $rs =& $conn->Execute($sql,array($expiry,$expirevar,$key,time()));
+ $rs = $conn->Execute($sql,array($expiry,$expirevar,$key,time()));
return true;
}
$val = rawurlencode($val);
$conn->StartTrans();
$expiryref = $conn->qstr($arr['expireref']);
// do we insert or update? => as for sesskey
- $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = $qkey");
+ $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = $qkey");
if ($rs && reset($rs->fields) > 0) {
$sql = "UPDATE $table SET expiry = $expiry, $data = $lob_value, expireref=$expiryref WHERE sesskey = $qkey";
} else {
$err = '';
- $rs1 =& $conn->Execute($sql);
+ $rs1 = $conn->Execute($sql);
if (!$rs1) $err = $conn->ErrorMsg()."\n";
- $rs2 =& $conn->UpdateBlob($table, $data, $val, " sesskey=$qkey", strtoupper($clob));
+ $rs2 = $conn->UpdateBlob($table, $data, $val, " sesskey=$qkey", strtoupper($clob));
if (!$rs2) $err .= $conn->ErrorMsg()."\n";
$rs = ($rs && $rs2) ? true : false;
// properly unless select statement executed in Win2000
if ($conn->databaseType == 'access') {
$sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
if ($rs) {
$rs->Close();
/*!
*/
function destroy($key) {
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$table = ADODB_Session::table();
$expire_notify = ADODB_Session::expireNotify();
$fn = next($expire_notify);
$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
$sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
$conn->SetFetchMode($savem);
if (!$rs) {
}
$sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
return $rs ? true : false;
*/
function gc($maxlifetime)
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$debug = ADODB_Session::debug();
$expire_notify = ADODB_Session::expireNotify();
$optimize = ADODB_Session::optimize();
$fn = next($expire_notify);
$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
$sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
$conn->SetFetchMode($savem);
if ($rs) {
if (1) {
$sql = "SELECT sesskey FROM $table WHERE expiry < $time";
- $arr =& $conn->GetAll($sql);
+ $arr = $conn->GetAll($sql);
foreach ($arr as $row) {
$sql2 = "DELETE FROM $table WHERE sesskey=".$conn->Param('0');
$conn->Execute($sql2,array($row[0]));
}
} else {
$sql = "DELETE FROM $table WHERE expiry < $time";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
if ($rs) $rs->Close();
}
}
$sql .= " FROM $table";
- $rs =& $conn->SelectLimit($sql, 1);
+ $rs = $conn->SelectLimit($sql, 1);
if ($rs && !$rs->EOF) {
$dbts = reset($rs->fields);
$rs->Close();
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.02 24 Sept 2007 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Contributed by Ross Smith (adodb@netebb.com).
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
*/
function adodb_session_regenerate_id()
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
if (!$conn) return false;
$old_id = session_id();
//@session_start();
}
$new_id = session_id();
- $ok =& $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
+ $ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
/* it is possible that the update statement fails due to a collision */
if (!$ok) {
{
// set default values
if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema2.xml';
- if ($conn===null) $conn =& ADODB_Session::_conn();
+ if ($conn===null) $conn = ADODB_Session::_conn();
if (!$conn) return 0;
*/
/*!
*/
- function driver($driver = null)
+ static function driver($driver = null)
{
static $_driver = 'mysql';
static $set = false;
/*!
*/
- function host($host = null) {
+ static function host($host = null) {
static $_host = 'localhost';
static $set = false;
/*!
*/
- function user($user = null)
+ static function user($user = null)
{
static $_user = 'root';
static $set = false;
/*!
*/
- function password($password = null)
+ static function password($password = null)
{
static $_password = '';
static $set = false;
/*!
*/
- function database($database = null)
+ static function database($database = null)
{
static $_database = '';
static $set = false;
/*!
*/
- function persist($persist = null)
+ static function persist($persist = null)
{
static $_persist = true;
/*!
*/
- function lifetime($lifetime = null)
+ static function lifetime($lifetime = null)
{
static $_lifetime;
static $set = false;
/*!
*/
- function debug($debug = null)
+ static function debug($debug = null)
{
static $_debug = false;
static $set = false;
$conn = ADODB_Session::_conn();
if ($conn) {
- $conn->debug = $_debug;
+ #$conn->debug = $_debug;
}
$set = true;
} elseif (!$set) {
/*!
*/
- function expireNotify($expire_notify = null)
+ static function expireNotify($expire_notify = null)
{
static $_expire_notify;
static $set = false;
/*!
*/
- function table($table = null)
+ static function table($table = null)
{
static $_table = 'sessions2';
static $set = false;
/*!
*/
- function optimize($optimize = null)
+ static function optimize($optimize = null)
{
static $_optimize = false;
static $set = false;
/*!
*/
- function syncSeconds($sync_seconds = null) {
+ static function syncSeconds($sync_seconds = null) {
//echo ("<p>WARNING: ADODB_SESSION::syncSeconds is longer used, please remove this function for your code</p>");
return 0;
/*!
*/
- function clob($clob = null) {
+ static function clob($clob = null) {
static $_clob = false;
static $set = false;
/*!
*/
- function dataFieldName($data_field_name = null) {
+ static function dataFieldName($data_field_name = null) {
//echo ("<p>WARNING: ADODB_SESSION::dataFieldName() is longer used, please remove this function for your code</p>");
return '';
}
/*!
*/
- function filter($filter = null) {
+ static function filter($filter = null) {
static $_filter = array();
if (!is_null($filter)) {
/*!
*/
- function encryptionKey($encryption_key = null) {
+ static function encryptionKey($encryption_key = null) {
static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
if (!is_null($encryption_key)) {
/*!
*/
- function &_conn($conn=null)
- {
- if (isset($GLOBALS['ADODB_SESS_CONN'])) {
- $conn =& $GLOBALS['ADODB_SESS_CONN'];
- return $conn;
- }
- $false = false;
- return $false;
+ static function _conn($conn=null) {
+ return @$GLOBALS['ADODB_SESS_CONN'];
}
/*!
*/
- function _crc($crc = null) {
+ static function _crc($crc = null) {
static $_crc = false;
if (!is_null($crc)) {
/*!
*/
- function _init() {
+ static function _init() {
session_module_name('user');
session_set_save_handler(
array('ADODB_Session', 'open'),
/*!
*/
- function _sessionKey() {
+ static function _sessionKey() {
// use this function to create the encryption key for crypted sessions
// crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt
return crypt(ADODB_Session::encryptionKey(), session_id());
/*!
*/
- function _dumprs($rs) {
- $conn =& ADODB_Session::_conn();
+ static function _dumprs($rs) {
+ $conn = ADODB_Session::_conn();
$debug = ADODB_Session::debug();
if (!$conn) {
// public methods
/////////////////////
- function config($driver, $host, $user, $password, $database=false,$options=false)
+ static function config($driver, $host, $user, $password, $database=false,$options=false)
{
ADODB_Session::driver($driver);
ADODB_Session::host($host);
If $conn already exists, reuse that connection
*/
- function open($save_path, $session_name, $persist = null)
+ static function open($save_path, $session_name, $persist = null)
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
if ($conn) {
return true;
# assert('$driver');
# assert('$host');
- $conn =& ADONewConnection($driver);
+ $conn = ADONewConnection($driver);
if ($debug) {
$conn->debug = true;
$ok = $conn->Connect($host, $user, $password, $database);
}
- if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
+ if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn;
else
ADOConnection::outp('<p>Session: connection failed</p>', false);
/*!
Close the connection
*/
- function close()
+ static function close()
{
/*
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
if ($conn) $conn->Close();
*/
return true;
/*
Slurp in the session variables and return the serialized string
*/
- function read($key)
+ static function read($key)
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$filter = ADODB_Session::filter();
$table = ADODB_Session::table();
developer has commited elsewhere... :(
*/
#if (ADODB_Session::Lock())
- # $rs =& $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata);
+ # $rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata);
#else
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
//ADODB_Session::_dumprs($rs);
if ($rs) {
if ($rs->EOF) {
If the data has not been modified since the last read(), we do not write.
*/
- function write($key, $val)
+ static function write($key, $oval)
{
global $ADODB_SESSION_READONLY;
if (!empty($ADODB_SESSION_READONLY)) return;
$clob = ADODB_Session::clob();
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$crc = ADODB_Session::_crc();
$debug = ADODB_Session::debug();
$driver = ADODB_Session::driver();
if (!$conn) {
return false;
}
-
+ if ($debug) $conn->debug = 1;
$sysTimeStamp = $conn->sysTimeStamp;
//assert('$table');
// crc32 optimization since adodb 2.1
// now we only update expiry date, thx to sebastian thom in adodb 2.32
- if ($crc !== false && $crc == (strlen($val) . crc32($val))) {
+ if ($crc !== false && $crc == (strlen($oval) . crc32($oval))) {
if ($debug) {
echo '<p>Session: Only updating date - crc32 not changed</p>';
}
$sql = "UPDATE $table SET expiry = $expiry ,expireref=".$conn->Param('0').", modified = $sysTimeStamp WHERE $binary sesskey = ".$conn->Param('1')." AND expiry >= $sysTimeStamp";
- $rs =& $conn->Execute($sql,array($expirevar,$key));
+ $rs = $conn->Execute($sql,array($expirevar,$key));
return true;
}
- $val = rawurlencode($val);
+ $val = rawurlencode($oval);
foreach ($filter as $f) {
if (is_object($f)) {
$val = $f->write($val, ADODB_Session::_sessionKey());
}
if (!$clob) { // no lobs, simply use replace()
- $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
+ $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
if ($rs) $rs->Close();
if ($rs && reset($rs->fields) > 0) {
}
- $rs =& $conn->Execute($sql,array($val,$expireref,$key));
+ $rs = $conn->Execute($sql,array($val,$expireref,$key));
} else {
// what value shall we insert/update for lob row?
$conn->StartTrans();
- $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
+ $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
if ($rs) $rs->Close();
if ($rs && reset($rs->fields) > 0) {
VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)";
}
- $rs =& $conn->Execute($sql,array($expireref,$key));
+ $rs = $conn->Execute($sql,array($expireref,$key));
$qkey = $conn->qstr($key);
$rs2 = $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob));
+ if ($debug) echo "<hr>",htmlspecialchars($oval), "<hr>";
$rs = @$conn->CompleteTrans();
// properly unless select statement executed in Win2000
if ($conn->databaseType == 'access') {
$sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
if ($rs) {
$rs->Close();
/*!
*/
- function destroy($key) {
- $conn =& ADODB_Session::_conn();
+ static function destroy($key) {
+ $conn = ADODB_Session::_conn();
$table = ADODB_Session::table();
$expire_notify = ADODB_Session::expireNotify();
if (!$conn) {
return false;
}
-
+ $debug = ADODB_Session::debug();
+ if ($debug) $conn->debug = 1;
//assert('$table');
$qkey = $conn->quote($key);
$fn = next($expire_notify);
$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
$sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
$conn->SetFetchMode($savem);
if (!$rs) {
}
$sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
if ($rs) {
$rs->Close();
/*!
*/
- function gc($maxlifetime)
+ static function gc($maxlifetime)
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
$debug = ADODB_Session::debug();
$expire_notify = ADODB_Session::expireNotify();
$optimize = ADODB_Session::optimize();
return false;
}
+
+ $debug = ADODB_Session::debug();
+ if ($debug) $conn->debug = 1;
+
//assert('$table');
$time = $conn->sysTimeStamp;
$fn = next($expire_notify);
$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
$sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
$conn->SetFetchMode($savem);
if ($rs) {
if (0) {
$sql = "SELECT sesskey FROM $table WHERE expiry < $time";
- $arr =& $conn->GetAll($sql);
+ $arr = $conn->GetAll($sql);
foreach ($arr as $row) {
$sql2 = "DELETE FROM $table WHERE sesskey=".$conn->Param('0');
$conn->Execute($sql2,array($row[0]));
}
} else {
$sql = "DELETE FROM $table WHERE expiry < $time";
- $rs =& $conn->Execute($sql);
+ $rs = $conn->Execute($sql);
ADODB_Session::_dumprs($rs);
if ($rs) $rs->Close();
}
<?php
/*
-V4.98 13 Feb 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.04a 25 Mar 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
- $rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
+ $rs = $ADODB_SESS_CONN->SelectLimit($sql,1);
if ($rs && !$rs->EOF) {
$dbts = reset($rs->fields);
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
- $rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
+ $rs = $ADODB_SESS_CONN->SelectLimit($sql,1);
if ($rs && !$rs->EOF) {
$dbts = reset($rs->fields);
*/
function adodb_session_regenerate_id()
{
- $conn =& ADODB_Session::_conn();
+ $conn = ADODB_Session::_conn();
if (!$conn) return false;
$old_id = session_id();
//@session_start();
}
$new_id = session_id();
- $ok =& $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
+ $ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
/* it is possible that the update statement fails due to a collision */
if (!$ok) {
$fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
$savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
$t = time();
- $rs =& $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
+ $rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
$ADODB_SESS_CONN->SetFetchMode($savem);
if ($rs) {
$ADODB_SESS_CONN->BeginTrans();
if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
- $rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
+ $rs = $ADODB_SESS_CONN->SelectLimit($sql,1);
if ($rs && !$rs->EOF) {
$dbts = reset($rs->fields);
$fieldTypes = $rs->FieldTypesArray();
reset($fieldTypes);
while(list(,$o) = each($fieldTypes)) {
-
- $v = $o->name;
+ if (!$o) $v = '';
+ else $v = $o->name;
if ($escquote) $v = str_replace($quote,$escquotequote,$v);
$v = strip_tags(str_replace("\n", $replaceNewLine, str_replace("\r\n",$replaceNewLine,str_replace($sep,$sepreplace,$v))));
$elements[] = $v;
for ($i=0; $i<sizeof($arr); $i++) {
$s .= '<TR>';
- $a = &$arr[$i];
+ $a = $arr[$i];
if (is_array($a))
for ($j=0; $j<sizeof($a); $j++) {
$val = $a[$j];