Skip to content
Browse files

Upgraded to ADOdb 4.5.1. Contains a lot of small fixes and speed-ups.

  • Loading branch information...
1 parent f5f346a commit fab7e07e19490b12b925356394b3fc15ef0812b4 moodler committed Aug 7, 2004
Showing with 1,550 additions and 827 deletions.
  1. +53 −1 lib/adodb/adodb-csvlib.inc.php
  2. +1 −1 lib/adodb/adodb-datadict.inc.php
  3. +1 −1 lib/adodb/adodb-errorhandler.inc.php
  4. +1 −1 lib/adodb/adodb-exceptions.inc.php
  5. +8 −9 lib/adodb/adodb-iterator.inc.php
  6. +146 −37 lib/adodb/adodb-lib.inc.php
  7. +2 −1 lib/adodb/adodb-pager.inc.php
  8. +2 −2 lib/adodb/adodb-perf.inc.php
  9. +1 −1 lib/adodb/adodb-php4.inc.php
  10. +23 −10 lib/adodb/adodb-time.inc.php
  11. +359 −116 lib/adodb/adodb-xmlschema.inc.php
  12. +183 −206 lib/adodb/adodb.inc.php
  13. +1 −1 lib/adodb/datadict/datadict-access.inc.php
  14. +1 −1 lib/adodb/datadict/datadict-db2.inc.php
  15. +1 −1 lib/adodb/datadict/datadict-firebird.inc.php
  16. +1 −1 lib/adodb/datadict/datadict-generic.inc.php
  17. +1 −1 lib/adodb/datadict/datadict-ibase.inc.php
  18. +1 −1 lib/adodb/datadict/datadict-informix.inc.php
  19. +1 −1 lib/adodb/datadict/datadict-mssql.inc.php
  20. +1 −1 lib/adodb/datadict/datadict-mysql.inc.php
  21. +1 −1 lib/adodb/datadict/datadict-oci8.inc.php
  22. +1 −1 lib/adodb/datadict/datadict-postgres.inc.php
  23. +1 −1 lib/adodb/datadict/datadict-sybase.inc.php
  24. +1 −1 lib/adodb/drivers/adodb-access.inc.php
  25. +14 −4 lib/adodb/drivers/adodb-ado.inc.php
  26. +1 −1 lib/adodb/drivers/adodb-ado_access.inc.php
  27. +1 −2 lib/adodb/drivers/adodb-ado_mssql.inc.php
  28. +1 −1 lib/adodb/drivers/adodb-borland_ibase.inc.php
  29. +1 −1 lib/adodb/drivers/adodb-csv.inc.php
  30. +6 −6 lib/adodb/drivers/adodb-db2.inc.php
  31. +1 −1 lib/adodb/drivers/adodb-firebird.inc.php
  32. +40 −43 lib/adodb/drivers/adodb-ibase.inc.php
  33. +1 −2 lib/adodb/drivers/adodb-informix72.inc.php
  34. +1 −1 lib/adodb/drivers/adodb-ldap.inc.php
  35. +28 −7 lib/adodb/drivers/adodb-mssql.inc.php
  36. +68 −41 lib/adodb/drivers/adodb-mysql.inc.php
  37. +76 −79 lib/adodb/drivers/adodb-mysqli.inc.php
  38. +60 −14 lib/adodb/drivers/adodb-mysqlt.inc.php
  39. +1 −2 lib/adodb/drivers/adodb-netezza.inc.php
  40. +49 −6 lib/adodb/drivers/adodb-oci8.inc.php
  41. +59 −43 lib/adodb/drivers/adodb-oci8po.inc.php
  42. +21 −9 lib/adodb/drivers/adodb-odbc.inc.php
  43. +14 −4 lib/adodb/drivers/adodb-odbc_mssql.inc.php
  44. +1 −1 lib/adodb/drivers/adodb-odbc_oracle.inc.php
  45. +2 −7 lib/adodb/drivers/adodb-odbtp.inc.php
  46. +2 −3 lib/adodb/drivers/adodb-odbtp_unicode.inc.php
  47. +3 −3 lib/adodb/drivers/adodb-oracle.inc.php
  48. +1 −1 lib/adodb/drivers/adodb-pdo.inc.php
  49. +1 −1 lib/adodb/drivers/adodb-postgres.inc.php
  50. +7 −7 lib/adodb/drivers/adodb-postgres64.inc.php
  51. +1 −1 lib/adodb/drivers/adodb-postgres7.inc.php
  52. +1 −1 lib/adodb/drivers/adodb-proxy.inc.php
  53. +1 −1 lib/adodb/drivers/adodb-sapdb.inc.php
  54. +1 −1 lib/adodb/drivers/adodb-sqlite.inc.php
  55. +1 −1 lib/adodb/drivers/adodb-sqlitepo.inc.php
  56. +2 −2 lib/adodb/drivers/adodb-sybase.inc.php
  57. +1 −3 lib/adodb/drivers/adodb-vfp.inc.php
  58. +1 −1 lib/adodb/perf/perf-db2.inc.php
  59. +1 −1 lib/adodb/perf/perf-informix.inc.php
  60. +1 −1 lib/adodb/perf/perf-mssql.inc.php
  61. +1 −1 lib/adodb/perf/perf-mysql.inc.php
  62. +20 −5 lib/adodb/perf/perf-oci8.inc.php
  63. +1 −1 lib/adodb/perf/perf-postgres.inc.php
  64. +0 −2 lib/adodb/session/adodb-compress-bzip2.php
  65. +0 −1 lib/adodb/session/adodb-compress-gzip.php
  66. +0 −1 lib/adodb/session/adodb-cryptsession.php
  67. +0 −1 lib/adodb/session/adodb-encrypt-mcrypt.php
  68. +0 −2 lib/adodb/session/adodb-encrypt-md5.php
  69. +0 −2 lib/adodb/session/adodb-encrypt-secret.php
  70. +0 −1 lib/adodb/session/adodb-session-clob.php
  71. +0 −1 lib/adodb/session/adodb-session.php
  72. +1 −1 lib/adodb/tests/benchmark.php
  73. +1 −1 lib/adodb/tests/test-datadict.php
  74. +14 −9 lib/adodb/tests/test-php5.php
  75. +4 −2 lib/adodb/tests/test-xmlschema.php
  76. +94 −23 lib/adodb/tests/test.php
  77. +1 −1 lib/adodb/tests/test2.php
  78. +1 −1 lib/adodb/tests/test3.php
  79. +1 −1 lib/adodb/tests/test4.php
  80. +1 −1 lib/adodb/tests/test5.php
  81. +1 −1 lib/adodb/tests/testcache.php
  82. +24 −25 lib/adodb/tests/testdatabases.inc.php
  83. +17 −3 lib/adodb/tests/testoci8.php
  84. +1 −1 lib/adodb/tests/testoci8cursor.php
  85. +1 −1 lib/adodb/tests/testpaging.php
  86. +1 −1 lib/adodb/tests/testpear.php
  87. +9 −2 lib/adodb/tests/testsessions.php
  88. +1 −1 lib/adodb/tohtml.inc.php
  89. +38 −33 lib/adodb/xmlschema.dtd
  90. +54 −0 lib/adodb/xsl/remove-0.2.xsl
View
54 lib/adodb/adodb-csvlib.inc.php
@@ -7,7 +7,7 @@
$ADODB_INCLUDED_CSV = 1;
/*
- V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+ V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
@@ -249,4 +249,56 @@ function &csv2rs($url,&$err,$timeout=0)
$rs->InitArrayFields($arr,$flds);
return $rs;
}
+
+
+ /**
+ * Save a file $filename and its $contents (normally for caching) with file locking
+ */
+ function adodb_write_file($filename, $contents,$debug=false)
+ {
+ # http://www.php.net/bugs.php?id=9203 Bug that flock fails on Windows
+ # So to simulate locking, we assume that rename is an atomic operation.
+ # First we delete $filename, then we create a $tempfile write to it and
+ # rename to the desired $filename. If the rename works, then we successfully
+ # modified the file exclusively.
+ # What a stupid need - having to simulate locking.
+ # Risks:
+ # 1. $tempfile name is not unique -- very very low
+ # 2. unlink($filename) fails -- ok, rename will fail
+ # 3. adodb reads stale file because unlink fails -- ok, $rs timeout occurs
+ # 4. another process creates $filename between unlink() and rename() -- ok, rename() fails and cache updated
+ if (strncmp(PHP_OS,'WIN',3) === 0) {
+ // skip the decimal place
+ $mtime = substr(str_replace(' ','_',microtime()),2);
+ // getmypid() actually returns 0 on Win98 - never mind!
+ $tmpname = $filename.uniqid($mtime).getmypid();
+ if (!($fd = fopen($tmpname,'a'))) return false;
+ $ok = ftruncate($fd,0);
+ if (!fwrite($fd,$contents)) $ok = false;
+ fclose($fd);
+ chmod($tmpname,0644);
+ // the tricky moment
+ @unlink($filename);
+ if (!@rename($tmpname,$filename)) {
+ unlink($tmpname);
+ $ok = false;
+ }
+ if (!$ok) {
+ if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
+ }
+ return $ok;
+ }
+ if (!($fd = fopen($filename, 'a'))) return false;
+ if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
+ $ok = fwrite( $fd, $contents );
+ fclose($fd);
+ chmod($filename,0644);
+ }else {
+ fclose($fd);
+ if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename<br>\n");
+ $ok = false;
+ }
+
+ return $ok;
+ }
?>
View
2 lib/adodb/adodb-datadict.inc.php
@@ -1,7 +1,7 @@
<?php
/**
- V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+ V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
View
2 lib/adodb/adodb-errorhandler.inc.php
@@ -1,6 +1,6 @@
<?php
/**
- * @version V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+ * @version V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
View
2 lib/adodb/adodb-exceptions.inc.php
@@ -1,7 +1,7 @@
<?php
/**
- * @version V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+ * @version V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
* Released under both BSD license and Lesser GPL library license.
* Whenever there is any discrepancy between the two licenses,
* the BSD license will take precedence.
View
17 lib/adodb/adodb-iterator.inc.php
@@ -1,7 +1,7 @@
<?php
/*
- V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+ V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
@@ -58,14 +58,7 @@ function __call($func, $params)
{
return call_user_func_array(array($this->rs, $func), $params);
}
-
- function __toString()
- {
- if (isset($rs->databaseType)) $s = ' for '.$rs->databaseType;
- else $s = '';
-
- return 'ADODB Iterator'.$s;
- }
+
function hasMore()
{
@@ -79,6 +72,12 @@ class ADODB_BASE_RS implements IteratorAggregate {
function getIterator() {
return new ADODB_Iterator($this);
}
+
+ function __toString()
+ {
+ include_once(ADODB_DIR.'/toexport.inc.php');
+ return _adodb_export($this,',',',',false,true);
+ }
}
?>
View
183 lib/adodb/adodb-lib.inc.php
@@ -63,7 +63,7 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
if ($uSet && $where) {
$update = "UPDATE $table SET $uSet WHERE $where";
- $rs = $zthis->Execute($update);
+ $rs = $zthis->_Execute($update);
if ($rs) {
if ($zthis->poorAffectedRows) {
/*
@@ -77,8 +77,10 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
$cnt = $zthis->GetOne("select count(*) from $table where $where");
if ($cnt > 0) return 1; // record already exists
- } else
- if (($zthis->Affected_Rows()>0)) return 1;
+ } else {
+
+ if (($zthis->Affected_Rows()>0)) return 1;
+ }
}
}
// print "<p>Error=".$this->ErrorNo().'<p>';
@@ -96,7 +98,7 @@ function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_
}
}
$insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
- $rs = $zthis->Execute($insert);
+ $rs = $zthis->_Execute($insert);
return ($rs) ? 2 : 0;
}
@@ -216,7 +218,7 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
- $rstest = &$zthis->Execute($rewritesql,$inputarr);
+ $rstest = &$zthis->_Execute($rewritesql,$inputarr);
if ($rstest) {
$qryRecs = $rstest->RecordCount();
if ($qryRecs == -1) {
@@ -266,11 +268,7 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
$lastpageno = (int) ceil($qryRecs / $nrows);
$zthis->_maxRecordCount = $qryRecs;
- // If page number <= 1, then we are at the first page
- if (!isset($page) || $page <= 1) {
- $page = 1;
- $atfirstpage = true;
- }
+
// ***** Here we check whether $page is the last page or
// whether we are trying to retrieve
@@ -280,6 +278,12 @@ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
$atlastpage = true;
}
+ // If page number <= 1, then we are at the first page
+ if (empty($page) || $page <= 1) {
+ $page = 1;
+ $atfirstpage = true;
+ }
+
// We get the data we want
$offset = $nrows * ($page-1);
if ($secs2cache > 0)
@@ -372,7 +376,7 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
// If the recordset field is one
// of the fields passed in then process.
$upperfname = strtoupper($field->name);
- if (adodb_key_exists($upperfname,$arrFields)) {
+ if (adodb_key_exists($upperfname,$arrFields,$forcenulls)) {
// If the existing field value in the recordset
// is different from the value passed in then
@@ -392,31 +396,32 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
// Based on the datatype of the field
// Format the value properly for the database
- $type = $rs->MetaType($field->type);
-
- // is_null requires php 4.0.4
- if (($forcenulls && is_null($arrFields[$upperfname])) ||
- $arrFields[$upperfname] === 'null') {
- $setFields .= $field->name . " = null, ";
- } else {
- if ($type == 'null') {
- $type = 'C';
+ $type = $rs->MetaType($field->type);
+
+ // is_null requires php 4.0.4
+ if (($forcenulls && is_null($arrFields[$upperfname])) ||
+ $arrFields[$upperfname] === 'null') {
+ $setFields .= $field->name . " = null, ";
+ } else {
+ if ($type == 'null') {
+ $type = 'C';
+ }
+
+ if (strpos($upperfname,' ') !== false)
+ $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
+ else
+ $fnameq = $upperfname;
+
+ //we do this so each driver can customize the sql for
+ //DB specific column types.
+ //Oracle needs BLOB types to be handled with a returning clause
+ //postgres has special needs as well
+ $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
+ $arrFields, $magicq);
}
-
- if (strpos($upperfname,' ') !== false)
- $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
- else
- $fnameq = $upperfname;
- //we do this so each driver can customize the sql for
- //DB specific column types.
- //Oracle needs BLOB types to be handled with a returning clause
- //postgres has special needs as well
- $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
- $arrFields, $magicq);
}
}
}
- }
// If there were any modified fields then build the rest of the update query.
if ($fieldUpdatedCount > 0 || $forceUpdate) {
@@ -429,9 +434,10 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq
$discard = false;
// not a good hack, improvements?
- if ($whereClause)
- preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard);
- else
+ if ($whereClause) {
+ if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
+ else preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard);
+ } else
$whereClause = array(false,false);
if ($discard)
@@ -503,7 +509,7 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$forcenulls=f
// Loop through all of the fields in the recordset
foreach( $columns as $field ) {
$upperfname = strtoupper($field->name);
- if (adodb_key_exists($upperfname,$arrFields)) {
+ if (adodb_key_exists($upperfname,$arrFields,$forcenulls)) {
// Set the counter for the number of fields that will be inserted.
$fieldInsertedCount++;
@@ -539,8 +545,10 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$forcenulls=f
// Get the table name from the existing query.
if (!$tableName) {
- preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
+ if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
$tableName = $tableName[1];
+ else
+ return false;
}
// Strip off the comma and space on the end of both the fields
@@ -693,4 +701,105 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields,
return $sql;
}
+
+
+
+function _adodb_debug_execute(&$zthis, $sql, $inputarr)
+{
+global $HTTP_SERVER_VARS;
+
+ $ss = '';
+ if ($inputarr) {
+ foreach($inputarr as $kk=>$vv) {
+ if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
+ $ss .= "($kk=>'$vv') ";
+ }
+ $ss = "[ $ss ]";
+ }
+ $sqlTxt = str_replace(',',', ',is_array($sql) ? $sql[0] : $sql);
+
+ // check if running from browser or command-line
+ $inBrowser = isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']);
+
+ if ($inBrowser) {
+ $ss = htmlspecialchars($ss);
+ if ($zthis->debug === -1)
+ ADOConnection::outp( "<br>\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<br>\n",false);
+ else
+ ADOConnection::outp( "<hr>\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<hr>\n",false);
+ } else {
+ ADOConnection::outp("-----\n($zthis->databaseType): ".$sqlTxt."\n-----\n",false);
+ }
+
+ $qID = $zthis->_query($sql,$inputarr);
+
+ /*
+ Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
+ because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
+ */
+ if ($zthis->databaseType == 'mssql') {
+ // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
+ if($emsg = $zthis->ErrorMsg()) {
+ if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
+ }
+ } else if (!$qID) {
+ ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
+ }
+
+ return $qID;
+}
+
+
+function _adodb_backtrace($printOrArr=true,$levels=9999)
+{
+ if (PHPVERSION() < 4.3) return '';
+
+ $html = (isset($_SERVER['HTTP_USER_AGENT']));
+ $fmt = ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
+
+ $MAXSTRLEN = 64;
+
+ $s = ($html) ? '<pre align=left>' : '';
+
+ if (is_array($printOrArr)) $traceArr = $printOrArr;
+ else $traceArr = debug_backtrace();
+ array_shift($traceArr);
+ array_shift($traceArr);
+ $tabs = sizeof($traceArr)-2;
+
+ foreach ($traceArr as $arr) {
+ $levels -= 1;
+ if ($levels < 0) break;
+
+ $args = array();
+ for ($i=0; $i < $tabs; $i++) $s .= ($html) ? ' &nbsp; ' : "\t";
+ $tabs -= 1;
+ if ($html) $s .= '<font face="Courier New,Courier">';
+ if (isset($arr['class'])) $s .= $arr['class'].'.';
+ if (isset($arr['args']))
+ foreach($arr['args'] as $v) {
+ if (is_null($v)) $args[] = 'null';
+ else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
+ else if (is_object($v)) $args[] = 'Object:'.get_class($v);
+ else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
+ else {
+ $v = (string) @$v;
+ $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
+ if (strlen($v) > $MAXSTRLEN) $str .= '...';
+ $args[] = $str;
+ }
+ }
+ $s .= $arr['function'].'('.implode(', ',$args).')';
+
+
+ $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
+
+ $s .= "\n";
+ }
+ if ($html) $s .= '</pre>';
+ if ($printOrArr) print $s;
+
+ return $s;
+}
+
?>
View
3 lib/adodb/adodb-pager.inc.php
@@ -1,7 +1,7 @@
<?php
/*
- V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+ V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
@@ -230,6 +230,7 @@ function RenderPageCount()
if (!$this->db->pageExecuteCountRows) return '';
$lastPage = $this->rs->LastPageNo();
if ($lastPage == -1) $lastPage = 1; // check for empty rs.
+ if ($this->curr_page > $lastPage) $this->curr_page = 1;
return "<font size=-1>$this->page ".$this->curr_page."/".$lastPage."</font>";
}
View
4 lib/adodb/adodb-perf.inc.php
@@ -1,6 +1,6 @@
<?php
/*
-V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence. See License.txt.
@@ -622,7 +622,7 @@ function UI($pollsecs=5)
if (empty($HTTP_GET_VARS['hidem']))
echo "<table border=1 width=100% bgcolor=lightyellow><tr><td colspan=2>
- <b><a href=http://php.weblogs.com/adodb?perf=1>ADOdb</a> Performance Monitor</b> <font size=1>for $app</font></tr><tr><td>
+ <b><a href=http://adodb.sourceforge.net/?perf=1>ADOdb</a> Performance Monitor</b> <font size=1>for $app</font></tr><tr><td>
<a href=?do=stats><b>Performance Stats</b></a> &nbsp; <a href=?do=viewsql><b>View SQL</b></a>
&nbsp; <a href=?do=tables><b>View Tables</b></a> &nbsp; <a href=?do=poll><b>Poll Stats</b></a>",
$allowsql ? ' &nbsp; <a href=?do=dosql><b>Run SQL</b></a>' : '',
View
2 lib/adodb/adodb-php4.inc.php
@@ -1,7 +1,7 @@
<?php
/*
- V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
+ V4.51 29 July 2004 (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
View
33 lib/adodb/adodb-time.inc.php
@@ -141,13 +141,13 @@
outside the 1901 to 2038 range.
-FUNCTION adodb_mktime($hr, $min, $sec, $month, $day, $year)
+FUNCTION adodb_mktime($hr, $min, $sec [, $month, $day, $year])
Converts a local date to a unix timestamp. Unlike the function mktime(), it supports
dates outside the 1901 to 2038 range. Differs from mktime() in that all parameters
are currently compulsory.
-FUNCTION adodb_gmmktime($hr, $min, $sec, $month, $day, $year)
+FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year])
Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports
dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters
@@ -174,6 +174,10 @@
CHANGELOG
+- 18 July 2004 0.15
+All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. This
+brings it more in line with mktime (still not identical).
+
- 23 June 2004 0.14
Allow you to define your own daylights savings function, adodb_daylight_sv.
@@ -271,7 +275,7 @@ function adodb_daylight_sv(&$arr, $is_gmt)
/*
Version Number
*/
-define('ADODB_DATE_VERSION',0.14);
+define('ADODB_DATE_VERSION',0.15);
/*
We check for Windows as only +ve ints are accepted as dates on Windows.
@@ -313,6 +317,9 @@ function adodb_date_test()
// This flag disables calling of PHP native functions, so we can properly test the code
if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1);
+ $t = adodb_mktime(0,0,0);
+ if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'<br>';
+
$t = adodb_mktime(0,0,0,6,1,2102);
if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'<br>';
@@ -428,7 +435,7 @@ function adodb_date_test()
// we generate a timestamp, convert it to a date, and convert it back to a timestamp
// and check if the roundtrip broke the original timestamp value.
print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: ";
-
+ $cnt = 0;
for ($max += $i; $i < $max; $i += $offset) {
$ret = adodb_date('m,d,Y,H,i,s',$i);
$arr = explode(',',$ret);
@@ -443,8 +450,9 @@ function adodb_date_test()
$fail = true;
break;
}
+ $cnt += 1;
}
-
+ echo "Tested $cnt dates<br>";
if (!$fail) print "<p>Passed !</p>";
else print "<p><b>Failed</b> :-(</p>";
}
@@ -717,6 +725,8 @@ function adodb_date2($fmt, $d=false, $is_gmt=false)
*/
function adodb_date($fmt,$d=false,$is_gmt=false)
{
+static $daylight;
+
if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt);
if (!defined('ADODB_TEST_DATES')) {
if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range
@@ -728,7 +738,8 @@ function adodb_date($fmt,$d=false,$is_gmt=false)
$_day_power = 86400;
$arr = _adodb_getdate($d,true,$is_gmt);
- if (function_exists('adodb_daylight_sv')) adodb_daylight_sv($arr, $is_gmt);
+ if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
+ if ($daylight) adodb_daylight_sv($arr, $is_gmt);
$year = $arr['year'];
$month = $arr['mon'];
@@ -852,7 +863,7 @@ function adodb_date($fmt,$d=false,$is_gmt=false)
Returns a timestamp given a GMT/UTC time.
Note that $is_dst is not implemented and is ignored.
*/
-function adodb_gmmktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false)
+function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
{
return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
}
@@ -863,13 +874,15 @@ function adodb_gmmktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false)
Not a very fast algorithm - O(n) operation. Could be optimized to O(1).
*/
-function adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false,$is_gmt=false)
+function adodb_mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false)
{
if (!defined('ADODB_TEST_DATES')) {
// for windows, we don't check 1970 because with timezone differences,
// 1 Jan 1970 could generate negative timestamp, which is illegal
- if (!defined('ADODB_NO_NEGATIVE_TS') || ($year >= 1971))
- if (1901 < $year && $year < 2038)
+ if (1971 < $year && $year < 2038
+ || $mon === false
+ || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
+ )
return $is_gmt?
@gmmktime($hr,$min,$sec,$mon,$day,$year):
@mktime($hr,$min,$sec,$mon,$day,$year);
View
475 lib/adodb/adodb-xmlschema.inc.php
@@ -4,31 +4,6 @@
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.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list
- of conditions and the following disclaimer.
-Redistributions in binary form must reproduce the above copyright notice, this l
-ist of conditions and the following disclaimer in the documentation and/or other
- materials provided with the distribution.
-Neither the name of the ars Cognita, Inc., nor the names of its contributors may be used
-to endorse or promote products derived from this software without specific prior
-written permission.
-
-DISCLAIMER:
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WA
-RRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIREC
-T, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR P
-ROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI
-SE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE P
-OSSIBILITY OF SUCH DAMAGE.
-
*******************************************************************************/
/**
* xmlschema is a class that allows the user to quickly and easily
@@ -104,6 +79,7 @@
*/
if( !defined( '_ADODB_LAYER' ) ) {
require( 'adodb.inc.php' );
+ require( 'adodb-datadict.inc.php' );
}
/**
@@ -274,7 +250,14 @@ function _tag_open( &$parser, $tag, $attributes ) {
switch( $this->currentElement ) {
case 'INDEX':
- xml_set_object( $parser, $this->addIndex( $attributes ) );
+ 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();
@@ -288,7 +271,7 @@ function _tag_open( &$parser, $tag, $attributes ) {
$this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
break;
- case 'KEY':
+ case 'KEY':
case 'NOTNULL':
case 'AUTOINCREMENT':
// Add a field option
@@ -304,6 +287,11 @@ function _tag_open( &$parser, $tag, $attributes ) {
$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 ) );
}
@@ -318,6 +306,12 @@ 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 );
@@ -341,6 +335,10 @@ function _tag_close( &$parser, $tag ) {
xml_set_object( $parser, $this->parent );
$this->destroy();
break;
+ case 'FIELD':
+ unset($this->current_field);
+ break;
+
}
}
@@ -357,6 +355,19 @@ function &addIndex( $attributes ) {
}
/**
+ * 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.
@@ -404,7 +415,7 @@ function addField( $name, $type, $size = NULL, $opts = NULL ) {
// Set the field options
if( isset( $opts ) ) {
- $this->fields[$field_id]['OPTS'] = $opts;
+ $this->fields[$field_id]['OPTS'][] = $opts;
}
}
@@ -511,7 +522,7 @@ function create( &$xmls ) {
if( is_array( $opt ) ) {
$key = key( $opt );
$value = $opt[key( $opt )];
- $fldarray[$field_id][$key] = $value;
+ @$fldarray[$field_id][$key] .= $value;
// Option doesn't have arguments
} else {
$fldarray[$field_id][$opt] = $opt;
@@ -548,6 +559,10 @@ function create( &$xmls ) {
$sql[] = $index->create( $xmls );
}
+ if( isset( $this->data ) ) {
+ $sql[] = $this->data->create( $xmls );
+ }
+
return $sql;
}
@@ -734,6 +749,192 @@ function drop() {
}
/**
+* 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( ( 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
@@ -788,8 +989,6 @@ function dbQuerySet( &$parent, $attributes = NULL ) {
case 'NONE':
$this->prefixMethod = 'NONE';
break;
- default:
- $this->prefixMethod = 'AUTO';
}
}
@@ -884,19 +1083,11 @@ function discardQuery() {
* @return string SQL query string.
*/
function buildQuery( $sql = NULL ) {
- if( !isset( $this->query ) ) {
- return FALSE;
- }
-
- if( empty( $sql ) ) {
+ if( !isset( $this->query ) OR empty( $sql ) ) {
return FALSE;
}
- if( !empty( $this->query ) ) {
- $this->query .= ' ';
- }
-
- $this->query .= trim( $sql );
+ $this->query .= $sql;
return $this->query;
}
@@ -911,8 +1102,7 @@ function addQuery() {
return FALSE;
}
- $this->queries[] = $this->query;
- $return = $this->query;
+ $this->queries[] = $return = trim($this->query);
unset( $this->query );
@@ -933,9 +1123,9 @@ function create( &$xmls ) {
// 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 );
- $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query );
- $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query );
+ $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 );
@@ -1099,8 +1289,8 @@ function adoSchema( &$db ) {
$this->mgq = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
- $this->debug = $this->db->debug;
$this->db =& $db;
+ $this->debug = $this->db->debug;
$this->dict = NewDataDictionary( $this->db );
$this->sqlArray = array();
$this->schemaVersion = XMLS_SCHEMA_VERSION;
@@ -1204,10 +1394,11 @@ function ContinueOnError( $mode = NULL ) {
* @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 ) {
- return $this->ParseSchemaString( $this->ConvertSchemaFile ( $filename ) );
+ function ParseSchema( $filename, $returnSchema = FALSE ) {
+ return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
@@ -1217,12 +1408,13 @@ function ParseSchema( $filename ) {
* 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 ) {
+ function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
// die( 'Unable to open file' );
@@ -1234,6 +1426,13 @@ function ParseSchemaFile( $filename ) {
return FALSE;
}
+ if ( $returnSchema )
+ {
+ return $xmlstring;
+ }
+
+ $this->success = 2;
+
$xmlParser = $this->create_parser();
// Process the file
@@ -1260,9 +1459,10 @@ function ParseSchemaFile( $filename ) {
* @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 ) {
+ function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
}
@@ -1272,10 +1472,15 @@ function ParseSchemaString( $xmlstring ) {
return FALSE;
}
- $xmlParser = $this->create_parser();
+ 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",
@@ -1285,10 +1490,47 @@ function ParseSchemaString( $xmlstring ) {
}
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
@@ -1448,38 +1690,12 @@ function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
if( $version == $newVersion ) {
$result = $schema;
} else {
- // Fail if XSLT extension is not available
- if( ! function_exists( 'xslt_create' ) ) {
- return FALSE;
- }
-
- $xsl_file = dirname( __FILE__ ) . '/xsl/convert-' . $version . '-' . $newVersion . '.xsl';
-
- // look for xsl
- if( !is_readable( $xsl_file ) ) {
- 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);
+ $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
}
- if( is_string ($newFile) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
- fwrite ($fp, $result);
- fclose ($fp);
+ if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
+ fwrite( $fp, $result );
+ fclose( $fp );
}
return $result;
@@ -1520,43 +1736,66 @@ function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
$result = substr( $result, 3 );
}
} else {
- // Fail if XSLT extension is not available
- if( ! function_exists( 'xslt_create' ) ) {
- return FALSE;
- }
-
- $xsl_file = dirname( __FILE__ ) . '/xsl/convert-' . $version . '-' . $newVersion . '.xsl';
-
- // look for xsl
- if( !is_readable( $xsl_file ) ) {
- return FALSE;
- }
-
- $arguments = array (
- '/_xml' => file_get_contents ($filename),
- '/_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);
+ $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
}
- if( is_string ($newFile) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
- fwrite ($fp, $result);
- fclose ($fp);
+ 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
*
@@ -1692,7 +1931,7 @@ function ExtractSchema( $data = FALSE ) {
}
if( $details->primary_key ) {
- $content[] = '<PRIMARY/>';
+ $content[] = '<KEY/>';
} elseif( $details->not_null ) {
$content[] = '<NOTNULL/>';
}
@@ -1743,6 +1982,10 @@ function ExtractSchema( $data = FALSE ) {
$schema .= ' <data>' . "\n";
while( $row = $rs->FetchRow() ) {
+ foreach( $row as $key => $val ) {
+ $row[$key] = htmlentities($row);
+ }
+
$schema .= ' <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";
}
@@ -1780,7 +2023,7 @@ function SetPrefix( $prefix = '', $underscore = TRUE ) {
// prefix too long
case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
// prefix contains invalid characters
- case !preg_match( '/^[a-z][a-z0-9]+$/i', $prefix ):
+ case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
logMsg( 'Invalid prefix: ' . $prefix );
return FALSE;
}
@@ -1931,8 +2174,8 @@ function Destroy() {
*
* @access private
*/
-function logMsg( $msg, $title = NULL ) {
- if( XMLS_DEBUG ) {
+function logMsg( $msg, $title = NULL, $force = FALSE ) {
+ if( XMLS_DEBUG or $force ) {
echo '<pre>';
if( isset( $title ) ) {
View
389 lib/adodb/adodb.inc.php
@@ -224,7 +224,7 @@ class ADOConnection {
var $substr = 'substr'; /// substring operator
var $length = 'length'; /// string length operator
var $random = 'rand()'; /// random function
- var $upperCase = false; /// uppercase function
+ var $upperCase = 'upper'; /// uppercase function
var $fmtDate = "'Y-m-d'"; /// used by DBDate() as the default date format used by the database
var $fmtTimeStamp = "'Y-m-d, h:i:s A'"; /// used by DBTimeStamp as the default timestamp fmt.
var $true = '1'; /// string that represents TRUE for a database
@@ -348,15 +348,17 @@ function outp($msg,$newline=true)
if ($newline) $msg .= "<br>\n";
- if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) echo $msg;
+ if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) || !$newline) echo $msg;
else echo strip_tags($msg);
+
+
if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan
}
function Time()
{
- $rs =& $this->Execute("select $this->sysTimeStamp");
+ $rs =& $this->_Execute("select $this->sysTimeStamp");
if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
return false;
@@ -617,7 +619,7 @@ function Disconnect()
For databases that require positioned params, eg $1, $2, $3 for postgresql,
pass in Param(false) before setting the first parameter.
*/
- function Param($name)
+ function Param($name,$type='C')
{
return '?';
}
@@ -754,7 +756,9 @@ function &Execute($sql,$inputarr=false)
$ret =& $fn($this,$sql,$inputarr);
if (isset($ret)) return $ret;
}
- if ($inputarr && is_array($inputarr)) {
+ if ($inputarr) {
+ if (!is_array($inputarr)) $inputarr = array($inputarr);
+
$element0 = reset($inputarr);
# is_object check because oci8 descriptors can be passed in
$array_2d = is_array($element0) && !is_object(reset($element0));
@@ -782,7 +786,7 @@ function &Execute($sql,$inputarr=false)
if ($i+1 != sizeof($sqlarr))
ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql));
- $ret =& $this->_Execute($sql,false);
+ $ret =& $this->_Execute($sql);
if (!$ret) return $ret;
}
} else {
@@ -803,60 +807,23 @@ function &Execute($sql,$inputarr=false)
return $ret;
}
+
function& _Execute($sql,$inputarr=false)
{
if ($this->debug) {
- global $HTTP_SERVER_VARS;
-
- $ss = '';
- if ($inputarr) {
- foreach($inputarr as $kk=>$vv) {
- if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
- $ss .= "($kk=>'$vv') ";
- }
- $ss = "[ $ss ]";
- }
- $sqlTxt = str_replace(',',', ',is_array($sql) ?$sql[0] : $sql);
-
- // check if running from browser or command-line
- $inBrowser = isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']);
-
- if ($inBrowser) {
- if ($this->debug === -1)
- ADOConnection::outp( "<br>\n($this->databaseType): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<br>\n",false);
- else
- ADOConnection::outp( "<hr>\n($this->databaseType): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<hr>\n",false);
- } else {
- ADOConnection::outp("-----\n($this->databaseType): ".($sqlTxt)." \n-----\n",false);
- }
- $this->_queryID = $this->_query($sql,$inputarr);
- /*
- Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
- because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
- */
- if ($this->databaseType == 'mssql') {
- // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
- if($emsg = $this->ErrorMsg()) {
- if ($err = $this->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
- }
- } else if (!$this->_queryID) {
- ADOConnection::outp($this->ErrorNo() .': '. $this->ErrorMsg());
- }
+ global $ADODB_INCLUDED_LIB;
+ if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
+ $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr);
} else {
- //****************************
- // non-debug version of query
- //****************************
-
- $this->_queryID =@$this->_query($sql,$inputarr);
+ $this->_queryID = @$this->_query($sql,$inputarr);
}
/************************
// OK, query executed
*************************/
- if ($this->_queryID === false) {
- // error handling if query fails
+ if ($this->_queryID === false) { // error handling if query fails
if ($this->debug == 99) adodb_backtrace(true,5);
$fn = $this->raiseErrorFn;
if ($fn) {
@@ -866,12 +833,8 @@ function& _Execute($sql,$inputarr=false)
return false;
}
-
- if ($this->_queryID === true) {
- // return simplified empty recordset for inserts/updates/deletes with lower overhead
+ if ($this->_queryID === true) { // return simplified recordset for inserts/updates/deletes with lower overhead
$rs =& new ADORecordSet_empty();
- #if (is_array($sql)) $rs->sql = $sql[0];
- #else $rs->sql = $sql;
return $rs;
}
@@ -885,7 +848,7 @@ function& _Execute($sql,$inputarr=false)
if ($rs->_numOfRows <= 0) {
global $ADODB_COUNTRECS;
if ($ADODB_COUNTRECS) {
- if (!$rs->EOF){
+ if (!$rs->EOF) {
$rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql));
$rs->_queryID = $this->_queryID;
} else
@@ -1241,7 +1204,7 @@ function GetOne($sql,$inputarr=false)
if ($rs) {
if (!$rs->EOF) $ret = reset($rs->fields);
$rs->Close();
- }
+ }
$ADODB_COUNTRECS = $crecs;
return $ret;
}
@@ -1481,6 +1444,10 @@ function CacheFlush($sql=false,$inputarr=false)
}
return;
}
+
+ global $ADODB_INCLUDED_CSV;
+ if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
+
$f = $this->_gencachename($sql.serialize($inputarr),false);
adodb_write_file($f,''); // is adodb_write_file needed?
if (!@unlink($f)) {
@@ -1631,7 +1598,7 @@ function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$forcenu
$forcenulls = defined('ADODB_FORCE_NULLS') ? true : false;
}
if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
- return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq);
+ return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$forcenulls);
}
@@ -1650,7 +1617,7 @@ function GetInsertSQL(&$rs, $arrFields,$magicq=false,$forcenulls=null)
$forcenulls = defined('ADODB_FORCE_NULLS') ? true : false;
}
if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php');
- return _adodb_getinsertsql($this,$rs,$arrFields,$magicq);
+ return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$forcenulls);
}
@@ -2505,7 +2472,10 @@ function &GetRows($nRows = -1)
* @return an associative array indexed by the first column of the array,
* or false if the data has less than 2 cols.
*/
- function &GetAssoc($force_array = false, $first2cols = false) {
+ function &GetAssoc($force_array = false, $first2cols = false)
+ {
+ global $ADODB_EXTENSION;
+
$cols = $this->_numOfFields;
if ($cols < 2) {
return false;
@@ -2514,32 +2484,64 @@ function &GetAssoc($force_array = false, $first2cols = false) {
$results = array();
if (!$first2cols && ($cols > 2 || $force_array)) {
- if ($numIndex) {
- while (!$this->EOF) {
- $results[trim($this->fields[0])] = array_slice($this->fields, 1);
- $this->MoveNext();
+ if ($ADODB_EXTENSION) {
+ if ($numIndex) {
+ while (!$this->EOF) {
+ $results[trim($this->fields[0])] = array_slice($this->fields, 1);
+ adodb_movenext($this);
+ }
+ } else {
+ while (!$this->EOF) {
+ $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
+ adodb_movenext($this);
+ }
}
} else {
- while (!$this->EOF) {
- $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
- $this->MoveNext();
+ if ($numIndex) {
+ while (!$this->EOF) {
+ $results[trim($this->fields[0])] = array_slice($this->fields, 1);
+ $this->MoveNext();
+ }
+ } else {
+ while (!$this->EOF) {
+ $results[trim(reset($this->fields))] = array_slice($this->fields, 1);
+ $this->MoveNext();
+ }
}
}
} else {
- // return scalar values
- if ($numIndex) {
- while (!$this->EOF) {
- // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
- $results[trim(($this->fields[0]))] = $this->fields[1];
- $this->MoveNext();
+ if ($ADODB_EXTENSION) {
+ // return scalar values
+ if ($numIndex) {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $results[trim(($this->fields[0]))] = $this->fields[1];
+ adodb_movenext($this);
+ }
+ } else {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $v1 = trim(reset($this->fields));
+ $v2 = ''.next($this->fields);
+ $results[$v1] = $v2;
+ adodb_movenext($this);
+ }
}
} else {
- while (!$this->EOF) {
- // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
- $v1 = trim(reset($this->fields));
- $v2 = ''.next($this->fields);
- $results[$v1] = $v2;
- $this->MoveNext();
+ if ($numIndex) {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $results[trim(($this->fields[0]))] = $this->fields[1];
+ $this->MoveNext();
+ }
+ } else {
+ while (!$this->EOF) {
+ // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
+ $v1 = trim(reset($this->fields));
+ $v2 = ''.next($this->fields);
+ $results[$v1] = $v2;
+ $this->MoveNext();
+ }
}
}
}
@@ -2728,7 +2730,8 @@ function MoveNext()
}
*/
return false;
- }
+ }
+
/**
* Random access to a specific row in the recordset. Some databases do not support
@@ -2989,7 +2992,8 @@ function &FetchObject($isupper=true)
*/
function &FetchNextObj()
{
- return $this->FetchNextObject(false);
+ $o = $this->FetchNextObject(false);
+ return $o;
}
@@ -3415,6 +3419,7 @@ function ADOLoadCode($dbType)
if (!$dbType) return false;
$db = strtolower($dbType);
switch ($db) {
+ case 'ifx':
case 'maxsql': $db = 'mysqlt'; break;
case 'postgres':
case 'pgsql': $db = 'postgres7'; break;
@@ -3456,44 +3461,111 @@ function &ADONewConnection($db='')
if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2);
$errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
- if (!empty($ADODB_NEWCONNECTION)) {
- $obj = $ADODB_NEWCONNECTION($db);
- if ($obj) {
- if ($errorfn) $obj->raiseErrorFn = $errorfn;
- return $obj;
+ if (strpos($db,'://')) {
+ $origdsn = $db;
+ $dsna = @parse_url($db);
+ if (!$dsna) {
+ // special handling of oracle, which might not have host
+ $db = str_replace('@/','@adodb-fakehost/',$db);
+ $dsna = parse_url($db);
+ if (!$dsna) return false;
+ $dsna['host'] = '';
}
+ $db = @$dsna['scheme'];
+ if (!$db) return false;
+ $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
+ $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : '';
+ $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : '';
+ $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : '';
+
+ if (isset($dsna['query'])) {
+ $opt1 = explode('&',$dsna['query']);
+ foreach($opt1 as $k => $v) {
+ $arr = explode('=',$v);
+ $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1;
+ }
+ } else $opt = array();
}
- if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = '';
- if (empty($db)) $db = $ADODB_LASTDB;
-
- if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db);
+ /*
+ * phptype: Database backend used in PHP (mysql, odbc etc.)
+ * dbsyntax: Database used with regards to SQL syntax etc.
+ * protocol: Communication protocol to use (tcp, unix etc.)
+ * hostspec: Host specification (hostname[:port])
+ * database: Database to use on the DBMS server
+ * username: User name for login
+ * password: Password for login
+ */
+ if (!empty($ADODB_NEWCONNECTION)) {
+ $obj = $ADODB_NEWCONNECTION($db);
+
+ } else {
- if (!$db) {
- if ($errorfn) {
- // raise an error
- $ignore = false;
- $errorfn('ADONewConnection', 'ADONewConnection', -998,
- "could not load the database driver for '$db",
- $db,false,$ignore);
- } else
- ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false);
-
- return false;
+ if (!isset($ADODB_LASTDB)) $ADODB_LASTDB = '';
+ if (empty($db)) $db = $ADODB_LASTDB;
+
+ if ($db != $ADODB_LASTDB) $db = ADOLoadCode($db);
+
+ if (!$db) {
+ if (isset($origdsn)) $db = $origdsn;
+ if ($errorfn) {
+ // raise an error
+ $ignore = false;
+ $errorfn('ADONewConnection', 'ADONewConnection', -998,
+ "could not load the database driver for '$db'",
+ $db,false,$ignore);
+ } else
+ ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false);
+
+ return false;
+ }
+
+ $cls = 'ADODB_'.$db;
+ if (!class_exists($cls)) {
+ adodb_backtrace();
+ return false;
+ }
+
+ $obj =& new $cls();
}
- $cls = 'ADODB_'.$db;
- if (!class_exists($cls)) {
- adodb_backtrace();
- return false;
+ # constructor should not fail
+ if ($obj) {
+ if ($errorfn) $obj->raiseErrorFn = $errorfn;
+ if (isset($dsna)) {
+
+ foreach($opt as $k => $v) {
+ switch(strtolower($k)) {
+ case 'persist':
+ case 'persistent': $persist = $v; break;
+ case 'debug': $obj->debug = (integer) $v; break;
+ #ibase
+ case 'dialect': $obj->dialect = (integer) $v; break;
+ case 'charset': $obj->charset = $v; break;
+ case 'buffers': $obj->buffers = $v; break;
+ case 'fetchmode': $obj->SetFetchMode($v); break;
+ #ado
+ case 'charpage': $obj->charPage = $v; break;
+ #mysql, mysqli
+ case 'clientflags': $obj->clientFlags = $v; break;
+ #mysqli
+ case 'port': $obj->port = $v; break;
+ case 'socket': $obj->socket = $v; break;
+ }
+ }
+ if (empty($persist))
+ $ok = $obj->Connect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path