diff --git a/phpgwapi/inc/adodb/adodb-csvlib.inc.php b/phpgwapi/inc/adodb/adodb-csvlib.inc.php index 17a606a3f9..80d0d8cb62 100644 --- a/phpgwapi/inc/adodb/adodb-csvlib.inc.php +++ b/phpgwapi/inc/adodb/adodb-csvlib.inc.php @@ -1,15 +1,19 @@ timeCreated = $ttl; + else { + $err = "Unable to unserialize recordset"; + //echo htmlspecialchars($text),' !--END--!

'; + } return $rs; } diff --git a/phpgwapi/inc/adodb/adodb-datadict.inc.php b/phpgwapi/inc/adodb/adodb-datadict.inc.php index ea68b3fe6e..80e77767a3 100644 --- a/phpgwapi/inc/adodb/adodb-datadict.inc.php +++ b/phpgwapi/inc/adodb/adodb-datadict.inc.php @@ -1,7 +1,7 @@ DB_ERROR_NOSUCHTABLE, '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/' => DB_ERROR_ALREADY_EXISTS, @@ -96,7 +98,9 @@ function adodb_error_pg($errormsg) '/pg_atoi: error in .*: can\'t parse /' => DB_ERROR_INVALID_NUMBER, '/ttribute [\"\'].*[\"\'] not found|Relation [\"\'].*[\"\'] does not have attribute [\"\'].*[\"\']/' => DB_ERROR_NOSUCHFIELD, '/parser: parse error at or near \"/' => DB_ERROR_SYNTAX, - '/referential integrity violation/' => DB_ERROR_CONSTRAINT + '/referential integrity violation/' => DB_ERROR_CONSTRAINT, + '/Relation [\"\'].*[\"\'] already exists|Cannot insert a duplicate key into (a )?unique index.*|duplicate key violates unique constraint/' + => DB_ERROR_ALREADY_EXISTS ); reset($error_regexps); while (list($regexp,$code) = each($error_regexps)) { diff --git a/phpgwapi/inc/adodb/adodb-errorhandler.inc.php b/phpgwapi/inc/adodb/adodb-errorhandler.inc.php index c5ed4cc307..ff8c35059a 100644 --- a/phpgwapi/inc/adodb/adodb-errorhandler.inc.php +++ b/phpgwapi/inc/adodb/adodb-errorhandler.inc.php @@ -1,6 +1,6 @@ Execute("select * from adoxyz"); foreach($rs as $k => $v) { @@ -19,6 +20,7 @@ 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; @@ -59,9 +61,16 @@ function __toString() { - return 'ADODB Iterator'; + if (isset($rs->databaseType)) $s = ' for '.$rs->databaseType; + else $s = ''; + + return 'ADODB Iterator'.$s; + } + + function hasMore() + { + return !$this->rs->EOF; } - } diff --git a/phpgwapi/inc/adodb/adodb-lib.inc.php b/phpgwapi/inc/adodb/adodb-lib.inc.php index ede10e3917..f6046b5ca3 100644 --- a/phpgwapi/inc/adodb/adodb-lib.inc.php +++ b/phpgwapi/inc/adodb/adodb-lib.inc.php @@ -1,10 +1,13 @@ ".htmlspecialchars($zval).''; + $s .= "'; else $s .= "\n'.htmlspecialchars($zval).''; } else { if (strcasecmp($selected,$defstr)==0) - $s .= "'; + $s .= "'; else $s .= "\n'.htmlspecialchars($zval).''; } @@ -206,12 +209,13 @@ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) } if ($qryRecs !== false) return $qryRecs; } - //-------------------------------------------- // query rewrite failed - so try slower way... - // strip off unneeded ORDER BY - $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql); + // strip off unneeded ORDER BY if no UNION + if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql; + else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql); + $rstest = &$zthis->Execute($rewritesql,$inputarr); if ($rstest) { $qryRecs = $rstest->RecordCount(); @@ -347,7 +351,7 @@ function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputar return $rsreturn; } -function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false) +function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$forcenulls=false) { if (!$rs) { printf(ADODB_BAD_RS,'GetUpdateSQL'); @@ -391,18 +395,23 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq $type = $rs->MetaType($field->type); // is_null requires php 4.0.4 - if ((defined('ADODB_FORCE_NULLS') && is_null($arrFields[$upperfname])) || + 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, + $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq, $arrFields, $magicq); } } @@ -439,9 +448,9 @@ function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq } } -function adodb_key_exists($key, &$arr) +function adodb_key_exists($key, &$arr,$forcenulls=false) { - if (!defined('ADODB_FORCE_NULLS')) { + if (!$forcenulls) { // the following is the old behaviour where null or empty fields are ignored return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0); } @@ -459,7 +468,7 @@ function adodb_key_exists($key, &$arr) * * */ -function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false) +function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$forcenulls=false) { $tableName = ''; $values = ''; @@ -498,13 +507,19 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false) // Set the counter for the number of fields that will be inserted. $fieldInsertedCount++; + + if (strpos($upperfname,' ') !== false) + $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote; + else + $fnameq = $upperfname; + // Get the name of the fields to insert - $fields .= $field->name . ", "; + $fields .= $fnameq . ", "; $type = $recordSet->MetaType($field->type); - if ((defined('ADODB_FORCE_NULLS') && is_null($arrFields[$upperfname])) || + if (($forcenulls && is_null($arrFields[$upperfname])) || $arrFields[$upperfname] === 'null') { $values .= "null, "; } else { @@ -512,7 +527,7 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false) //DB specific column types. //Oracle needs BLOB types to be handled with a returning clause //postgres has special needs as well - $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, + $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq, $arrFields, $magicq); } } @@ -553,7 +568,7 @@ function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false) * @return string * */ -function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $arrFields, $magicq) +function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq) { $sql = ''; @@ -570,16 +585,22 @@ function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $arrFields, $mag if ($action == 'I') { $sql = 'empty_blob(), '; } else { - $sql = $fname. '=empty_blob(), '; + $sql = $fnameq. '=empty_blob(), '; } //add the variable to the returning clause array //so the user can build this later in //case they want to add more to it $zthis->_returningArray[$fname] = ':xx'.$fname.'xx'; + } else if (empty($arrFields[$fname])){ + if ($action == 'I') { + $sql = 'empty_blob(), '; + } else { + $sql = $fnameq. '=empty_blob(), '; + } } else { //this is to maintain compatibility //with older adodb versions. - $sql = _adodb_column_sql($zthis, $action, $type, $fname, $arrFields, $magicq,false); + $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); } break; @@ -593,7 +614,7 @@ function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $arrFields, $mag if ($action == 'I') { $sql = ':xx'.$fname.'xx, '; } else { - $sql = $fname.'=:xx'.$fname.'xx, '; + $sql = $fnameq.'=:xx'.$fname.'xx, '; } //add the variable to the returning clause array //so the user can build this later in @@ -602,19 +623,19 @@ function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $arrFields, $mag } else { //this is to maintain compatibility //with older adodb versions. - $sql = _adodb_column_sql($zthis, $action, $type, $fname, $arrFields, $magicq,false); + $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); } break; default: - $sql = _adodb_column_sql($zthis, $action, $type, $fname, $arrFields, $magicq,false); + $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false); break; } return $sql; } -function _adodb_column_sql(&$zthis, $action, $type, $fname, $arrFields, $magicq, $recurse=true) +function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true) { if ($recurse) { @@ -623,13 +644,13 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $arrFields, $magicq, if ($type == 'L') $type = 'C'; break; case 'oci8': - return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $arrFields, $magicq); + return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq); } } $sql = ''; - + switch($type) { case "C": case "X": @@ -637,7 +658,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $arrFields, $magicq, if ($action == 'I') { $sql = $zthis->qstr($arrFields[$fname],$magicq) . ", "; } else { - $sql .= $fname . "=" . $zthis->qstr($arrFields[$fname],$magicq) . ", "; + $sql .= $fnameq . "=" . $zthis->qstr($arrFields[$fname],$magicq) . ", "; } break; @@ -645,7 +666,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $arrFields, $magicq, if ($action == 'I') { $sql = $zthis->DBDate($arrFields[$fname]) . ", "; } else { - $sql .= $fname . "=" . $zthis->DBDate($arrFields[$fname]) . ", "; + $sql .= $fnameq . "=" . $zthis->DBDate($arrFields[$fname]) . ", "; } break; @@ -653,7 +674,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $arrFields, $magicq, if ($action == 'I') { $sql = $zthis->DBTimeStamp($arrFields[$fname]) . ", "; } else { - $sql .= $fname . "=" . $zthis->DBTimeStamp($arrFields[$fname]) . ", "; + $sql .= $fnameq . "=" . $zthis->DBTimeStamp($arrFields[$fname]) . ", "; } break; @@ -665,7 +686,7 @@ function _adodb_column_sql(&$zthis, $action, $type, $fname, $arrFields, $magicq, if ($action == 'I') { $sql .= $val . ", "; } else { - $sql .= $fname . "=" . $val . ", "; + $sql .= $fnameq . "=" . $val . ", "; } break; } diff --git a/phpgwapi/inc/adodb/adodb-pager.inc.php b/phpgwapi/inc/adodb/adodb-pager.inc.php index 355806dac8..f4d2525eb4 100644 --- a/phpgwapi/inc/adodb/adodb-pager.inc.php +++ b/phpgwapi/inc/adodb/adodb-pager.inc.php @@ -1,6 +1,7 @@ trim(substr($sql,0,230)), - 'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>round($time,6)); + 'c'=>substr($sql,0,3900), 'd'=>$params,'e'=>$tracer,'f'=>adodb_round($time,6)); //var_dump($arr); $saved = $conn->debug; $conn->debug = 0; @@ -402,7 +408,7 @@ Committed_AS: 348732 kB $suffix = ' ... String too long for GET parameter: '.strlen($prefix).''; $prefix = ''; } - $s .= "".round($rs->fields[0],6)."".$rs->fields[2]."".$prefix.htmlspecialchars($sql).$suffix."". + $s .= "".adodb_round($rs->fields[0],6)."".$rs->fields[2]."".$prefix.htmlspecialchars($sql).$suffix."". "".$rs->fields[3]."".$rs->fields[4].""; $rs->MoveNext(); } @@ -478,7 +484,7 @@ Committed_AS: 348732 kB $prefix = ''; $suffix = ''; } - $s .= "".round($rs->fields[0],6)."".$rs->fields[2]."".$prefix.htmlspecialchars($sql).$suffix."". + $s .= "".adodb_round($rs->fields[0],6)."".$rs->fields[2]."".$prefix.htmlspecialchars($sql).$suffix."". "".$rs->fields[3]."".$rs->fields[4].""; $rs->MoveNext(); } @@ -628,7 +634,7 @@ Committed_AS: 348732 kB default: case 'stats': echo $this->HealthCheck(); - $this->conn->debug=1; + //$this->conn->debug=1; echo $this->CheckMemory(); break; case 'poll': diff --git a/phpgwapi/inc/adodb/adodb-php4.inc.php b/phpgwapi/inc/adodb/adodb-php4.inc.php index 90ac18b977..efc8f85e58 100644 --- a/phpgwapi/inc/adodb/adodb-php4.inc.php +++ b/phpgwapi/inc/adodb/adodb-php4.inc.php @@ -1,7 +1,7 @@ 0 + [minutes] => 0 + [hours] => 0 + [mday] => 1 # day of month, eg 1st day of the month + [mon] => 2 # month (eg. Feb) + [year] => 2102 + [yday] => 31 # days in current year + [leap] => # true if leap year + [ndays] => 28 # no of days in current month + ) + + +- 28 Apr 2004 0.13 +Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov. + - 20 Mar 2004 0.12 Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32. @@ -237,7 +271,7 @@ First implementation. /* Version Number */ -define('ADODB_DATE_VERSION',0.12); +define('ADODB_DATE_VERSION',0.14); /* We check for Windows as only +ve ints are accepted as dates on Windows. @@ -273,7 +307,7 @@ function adodb_date_test() error_reporting(E_ALL); print "

Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION. "

"; - set_time_limit(0); + @set_time_limit(0); $fail = false; // This flag disables calling of PHP native functions, so we can properly test the code @@ -551,6 +585,9 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false) $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); + $d366 = $_day_power * 366; + $d365 = $_day_power * 365; + if ($d < 0) { $origd = $d; // The valid range of a 32bit signed timestamp is typically from @@ -558,10 +595,9 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false) for ($a = 1970 ; --$a >= 0;) { $lastd = $d; - if ($leaf = _adodb_is_leap_year($a)) { - $d += $_day_power * 366; - } else - $d += $_day_power * 365; + if ($leaf = _adodb_is_leap_year($a)) $d += $d366; + else $d += $d365; + if ($d >= 0) { $year = $a; break; @@ -589,14 +625,11 @@ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false) $hour = floor($d/$_hour_power); } else { - for ($a = 1970 ;; $a++) { $lastd = $d; - if ($leaf = _adodb_is_leap_year($a)) { - $d -= $_day_power * 366; - } else - $d -= $_day_power * 365; + if ($leaf = _adodb_is_leap_year($a)) $d -= $d366; + else $d -= $d365; if ($d < 0) { $year = $a; break; @@ -660,6 +693,7 @@ function adodb_gmdate($fmt,$d=false) return adodb_date($fmt,$d,true); } +// accepts unix timestamp and iso date format in $d function adodb_date2($fmt, $d=false, $is_gmt=false) { if ($d !== false) { @@ -677,21 +711,25 @@ function adodb_date2($fmt, $d=false, $is_gmt=false) return adodb_date($fmt,$d,$is_gmt); } + /** Return formatted date based on timestamp $d */ function adodb_date($fmt,$d=false,$is_gmt=false) { - if ($d === false) return date($fmt); + if ($d === false) return ($is_gmt)? @gmdate($fmt): @date($fmt); if (!defined('ADODB_TEST_DATES')) { if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range if (!defined('ADODB_NO_NEGATIVE_TS') || $d >= 0) // if windows, must be +ve integer - return @date($fmt,$d); + return ($is_gmt)? @gmdate($fmt,$d): @date($fmt,$d); + } } $_day_power = 86400; $arr = _adodb_getdate($d,true,$is_gmt); + if (function_exists('adodb_daylight_sv')) adodb_daylight_sv($arr, $is_gmt); + $year = $arr['year']; $month = $arr['mon']; $day = $arr['mday']; @@ -822,6 +860,8 @@ function adodb_gmmktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false) /** Return a timestamp given a local time. Originally by jackbbs. Note that $is_dst is not implemented and is ignored. + + Not a very fast algorithm - O(n) operation. Could be optimized to O(1). */ function adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false,$is_gmt=false) { @@ -830,7 +870,9 @@ function adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false,$is_gmt=false) // 1 Jan 1970 could generate negative timestamp, which is illegal if (!defined('ADODB_NO_NEGATIVE_TS') || ($year >= 1971)) if (1901 < $year && $year < 2038) - return @mktime($hr,$min,$sec,$mon,$day,$year); + return $is_gmt? + @gmmktime($hr,$min,$sec,$mon,$day,$year): + @mktime($hr,$min,$sec,$mon,$day,$year); } $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff(); diff --git a/phpgwapi/inc/adodb/adodb.inc.php b/phpgwapi/inc/adodb/adodb.inc.php index b9aa9a53af..8f76063074 100644 --- a/phpgwapi/inc/adodb/adodb.inc.php +++ b/phpgwapi/inc/adodb/adodb.inc.php @@ -2,7 +2,7 @@ /* * Set tabs to 4 for best viewing. * - * Latest version is available at http://php.weblogs.com/adodb + * 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 @@ -14,7 +14,7 @@ /** \mainpage - @version V4.22 15 Apr 2004 (c) 2000-2004 John Lim (jlim\@natsoft.com.my). All rights reserved. + @version V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim\@natsoft.com.my). All rights reserved. Released under both BSD license and Lesser GPL library license. You can choose which license you prefer. @@ -56,7 +56,7 @@ $ADODB_COUNTRECS, // count number of records returned - slows down query $ADODB_CACHE_DIR, // directory to cache recordsets $ADODB_EXTENSION, // ADODB extension installed - $ADODB_COMPAT_PATCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF + $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF $ADODB_FETCH_MODE; // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... //============================================================================================== @@ -91,9 +91,13 @@ if (!defined('TIMESTAMP_FIRST_YEAR')) define('TIMESTAMP_FIRST_YEAR',100); - if (strnatcmp(PHP_VERSION,'4.3.0')>=0) { + // PHP's version scheme makes converting to numbers difficult - workaround + $_adodb_ver = (float) PHP_VERSION; + if ($_adodb_ver >= 5.0) { + define('ADODB_PHPVER',0x5000); + } else if ($_adodb_ver > 4.299999) { # 4.3 define('ADODB_PHPVER',0x4300); - } else if (strnatcmp(PHP_VERSION,'4.2.0')>=0) { + } 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); @@ -103,7 +107,7 @@ } //if (!defined('ADODB_ASSOC_CASE')) define('ADODB_ASSOC_CASE',2); - + /** Accepts $src and $dest arrays, replacing string $data @@ -147,7 +151,7 @@ /** * ADODB version as a string. */ - $ADODB_vers = 'V4.22 15 Apr 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.'; + $ADODB_vers = 'V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.'; /** * Determines whether recordset->RecordCount() is used. @@ -300,6 +304,13 @@ die('Virtual Class -- cannot instantiate'); } + function Version() + { + global $ADODB_vers; + + return (float) substr($ADODB_vers,1); + } + /** Get server version info... @@ -339,7 +350,7 @@ if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) echo $msg; else echo strip_tags($msg); - if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // dp not flush if output buffering enabled - useless - thx to Jesse Mullan + if (!empty($ADODB_FLUSH) && ob_get_length() !== false) flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan } @@ -370,30 +381,24 @@ if ($argDatabaseName != "") $this->database = $argDatabaseName; $this->_isPersistentConnection = false; - if ($fn = $this->raiseErrorFn) { - if ($forceNew) { - if ($this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; - } else { - if ($this->_connect($this->host, $this->user, $this->password, $this->database)) return true; - } - $err = $this->ErrorMsg(); - if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; - $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); + if ($forceNew) { + if ($this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; } else { - if ($forceNew) { - if ($this->_nconnect($this->host, $this->user, $this->password, $this->database)) return true; - } else { - if ($this->_connect($this->host, $this->user, $this->password, $this->database)) return true; - } + if ($this->_connect($this->host, $this->user, $this->password, $this->database)) return true; } - if ($this->debug) ADOConnection::outp( $this->host.': '.$this->ErrorMsg()); + $err = $this->ErrorMsg(); + if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; + if ($fn = $this->raiseErrorFn) + $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); + + if ($this->debug) ADOConnection::outp( $this->host.': '.$err); return false; } - function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) - { - return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName); - } + function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) + { + return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName); + } /** @@ -432,16 +437,16 @@ if ($argDatabaseName != "") $this->database = $argDatabaseName; $this->_isPersistentConnection = true; - + if ($this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; + $err = $this->ErrorMsg(); + if (empty($err)) { + $err = "Connection error to server '$argHostname' with user '$argUsername'"; + } if ($fn = $this->raiseErrorFn) { - if ($this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; - $err = $this->ErrorMsg(); - if (empty($err)) $err = "Connection error to server '$argHostname' with user '$argUsername'"; $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this); - } else - if ($this->_pconnect($this->host, $this->user, $this->password, $this->database)) return true; - - if ($this->debug) ADOConnection::outp( $this->host.': '.$this->ErrorMsg()); + } + + if ($this->debug) ADOConnection::outp( $this->host.': '.$err); return false; } @@ -679,6 +684,7 @@ $this->transOff = 1; } + /** Used together with StartTrans() to end a transaction. Monitors connection for sql errors, and will commit or rollback as appropriate. @@ -750,7 +756,7 @@ } if ($inputarr && is_array($inputarr)) { $element0 = reset($inputarr); - # is_object check is because oci8 descriptors can be passed in + # is_object check because oci8 descriptors can be passed in $array_2d = is_array($element0) && !is_object(reset($element0)); if (!is_array($sql) && !$this->_bindInputArray) { @@ -786,8 +792,9 @@ $ret =& $this->_Execute($stmt,$arr); if (!$ret) return $ret; } - } else + } else { $ret =& $this->_Execute($sql,$inputarr); + } } } else { $ret =& $this->_Execute($sql,false); @@ -863,6 +870,8 @@ if ($this->_queryID === true) { // return simplified empty 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; } @@ -875,7 +884,6 @@ else $rs->sql = $sql; if ($rs->_numOfRows <= 0) { global $ADODB_COUNTRECS; - if ($ADODB_COUNTRECS) { if (!$rs->EOF){ $rs = &$this->_rs2rs($rs,-1,-1,!is_array($sql)); @@ -1169,6 +1177,7 @@ for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { $flds[] = $rs->FetchField($i); } + $arr =& $rs->GetArrayLimit($nrows,$offset); //print_r($arr); if ($close) $rs->Close(); @@ -1328,6 +1337,11 @@ } function &CacheGetAll($secs2cache,$sql=false,$inputarr=false) + { + return $this->CacheGetArray($secs2cache,$sql,$inputarr); + } + + function &CacheGetArray($secs2cache,$sql=false,$inputarr=false) { global $ADODB_COUNTRECS; @@ -1482,18 +1496,29 @@ * - database type (oci8, ibase, ifx, etc) * - database name * - userid + * - setFetchMode (adodb 4.23) * - * We create 256 sub-directories in the cache directory ($ADODB_CACHE_DIR). + * When not in safe mode, we create 256 sub-directories in the cache directory ($ADODB_CACHE_DIR). * Assuming that we can have 50,000 files per directory with good performance, * then we can scale to 12.8 million unique cached recordsets. Wow! */ function _gencachename($sql,$createdir) { global $ADODB_CACHE_DIR; + static $notSafeMode; - $m = md5($sql.$this->databaseType.$this->database.$this->user); - $dir = $ADODB_CACHE_DIR.'/'.substr($m,0,2); - if ($createdir && !file_exists($dir)) { + if ($this->fetchMode === false) { + global $ADODB_FETCH_MODE; + $mode = $ADODB_FETCH_MODE; + } else { + $mode = $this->fetchMode; + } + $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode); + + if (!isset($notSafeMode)) $notSafeMode = !ini_get('safe_mode'); + $dir = ($notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($m,0,2) : $ADODB_CACHE_DIR; + + if ($createdir && $notSafeMode && !file_exists($dir)) { $oldu = umask(0); if (!mkdir($dir,0771)) if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql"); @@ -1599,9 +1624,12 @@ * * "Jonathan Younger" */ - function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false) + function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$forcenulls=null) { global $ADODB_INCLUDED_LIB; + if (!isset($forcenulls)) { + $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); } @@ -1615,9 +1643,12 @@ * Note: This function should only be used on a recordset * that is run against a single table. */ - function GetInsertSQL(&$rs, $arrFields,$magicq=false) + function GetInsertSQL(&$rs, $arrFields,$magicq=false,$forcenulls=null) { global $ADODB_INCLUDED_LIB; + if (!isset($forcenulls)) { + $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); } @@ -1744,44 +1775,6 @@ break; } } - - - /** - * $meta contains the desired type, which could be... - * C for character. You will have to define the precision yourself. - * X for teXt. For unlimited character lengths. - * B for Binary - * F for floating point, with no need to define scale and precision - * N for decimal numbers, you will have to define the (scale, precision) yourself - * D for date - * T for timestamp - * L for logical/Boolean - * I for integer - * R for autoincrement counter/integer - * and if you want to use double-byte, add a 2 to the end, like C2 or X2. - * - * - * @return the actual type of the data or false if no such type available - */ - function ActualType($meta) - { - switch($meta) { - case 'C': - case 'X': - return 'VARCHAR'; - case 'B': - - case 'D': - case 'T': - case 'L': - - case 'R': - - case 'I': - case 'N': - return false; - } - } /** @@ -1978,15 +1971,18 @@ * * @return array of column names for current table. */ - function &MetaColumnNames($table) + function &MetaColumnNames($table, $numIndexes=false) { $objarr =& $this->MetaColumns($table); if (!is_array($objarr)) return false; $arr = array(); - foreach($objarr as $v) { - $arr[strtoupper($v->name)] = $v->name; - } + if ($numIndexes) { + $i = 0; + foreach($objarr as $v) $arr[$i++] = $v->name; + } else + foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name; + return $arr; } @@ -2058,6 +2054,7 @@ */ function UnixDate($v) { + if (is_numeric($v) && strlen($v) !== 8) return $v; if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", ($v), $rr)) return false; @@ -2097,16 +2094,17 @@ * @return a date formated as user desires */ - function UserDate($v,$fmt='Y-m-d') + function UserDate($v,$fmt='Y-m-d',$gmt=false) { $tt = $this->UnixDate($v); + // $tt == -1 if pre TIMESTAMP_FIRST_YEAR if (($tt === false || $tt == -1) && $v != false) return $v; else if ($tt == 0) return $this->emptyDate; else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR } - return adodb_date($fmt,$tt); + return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); } @@ -2117,21 +2115,21 @@ * * @return a timestamp formated as user desires */ - function UserTimeStamp($v,$fmt='Y-m-d H:i:s') + function UserTimeStamp($v,$fmt='Y-m-d H:i:s',$gmt=false) { # strlen(14) allows YYYYMMDDHHMMSS format - if (is_numeric($v) && strlen($v)<14) return adodb_date($fmt,$v); + if (is_numeric($v) && strlen($v)<14) return ($gmt) ? adodb_gmdate($fmt,$v) : adodb_date($fmt,$v); $tt = $this->UnixTimeStamp($v); // $tt == -1 if pre TIMESTAMP_FIRST_YEAR if (($tt === false || $tt == -1) && $v != false) return $v; if ($tt == 0) return $this->emptyTimeStamp; - return adodb_date($fmt,$tt); + return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt); } /** * Quotes a string, without prefixing nor appending quotes. */ - function addq($s,$magicq=false) + function addq($s,$magic_quotes=false) { if (!$magic_quotes) { @@ -2210,9 +2208,9 @@ { global $ADODB_INCLUDED_LIB; if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.'/adodb-lib.inc.php'); - if ($this->pageExecuteCountRows) return _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache); - return _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; } @@ -2275,6 +2273,7 @@ function Close(){return true;} function FetchRow() {return false;} function FieldCount(){ return 0;} + function Init() {} } //============================================================================================== @@ -2581,7 +2580,6 @@ else if ($tt == -1) { // pre-TIMESTAMP_FIRST_YEAR } return adodb_date($fmt,$tt); - } @@ -2592,11 +2590,12 @@ */ function UnixDate($v) { - + if (is_numeric($v) && strlen($v) !== 8) return $v; if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", ($v), $rr)) return false; - if ($rr[1] <= TIMESTAMP_FIRST_YEAR) return 0; + if ($rr[1] <= TIMESTAMP_FIRST_YEAR || $rr[1] > 10000) return 0; + // h-m-s-MM-DD-YY return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); } @@ -2806,7 +2805,7 @@ /** * Use associative array to get fields array for databases that do not support - * associative arrays. Submitted by Paolo S. Asioli paolo.asioli@libero.it + * associative arrays. Submitted by Paolo S. Asioli paolo.asioli#libero.it * * If you don't want uppercase cols, set $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC * before you execute your SQL statement, and access $rs->fields['col'] directly. @@ -2929,7 +2928,7 @@ * Get the ADOFieldObjects of all columns in an array. * */ - function FieldTypesArray() + function& FieldTypesArray() { $arr = array(); for ($i=0, $max=$this->_numOfFields; $i < $max; $i++) @@ -3029,10 +3028,10 @@ * additional info (eg. primary_key for mysql). * * @return the general type of the data: - * C for character < 200 chars - * X for teXt (>= 200 chars) + * C for character < 250 chars + * X for teXt (>= 250 chars) * B for Binary - * N for numeric floating point + * N for numeric or floating point * D for date * T for timestamp * L for logical/Boolean @@ -3314,8 +3313,10 @@ /* Use associative array to get fields array */ function Fields($colname) { - if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname]; - + if ($this->fetchMode & ADODB_FETCH_ASSOC) { + if (!isset($this->fields[$colname])) $colname = strtolower($colname); + return $this->fields[$colname]; + } if (!$this->bind) { $this->bind = array(); for ($i=0; $i < $this->_numOfFields; $i++) { @@ -3424,6 +3425,7 @@ $ok = class_exists("ADODB_" . $db); if ($ok) return $db; + print_r(get_declared_classes()); $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php"; if (!file_exists($file)) ADOConnection::outp("Missing file: $file"); else ADOConnection::outp("Syntax error in file: $file"); @@ -3550,7 +3552,7 @@ $dict->connection = &$conn; $dict->upperName = strtoupper($drivername); $dict->quote = $conn->nameQuote; - if (is_resource($conn->_connectionID)) + if (!empty($conn->_connectionID)) $dict->serverInfo = $conn->ServerInfo(); return $dict; diff --git a/phpgwapi/inc/adodb/datadict/datadict-access.inc.php b/phpgwapi/inc/adodb/datadict/datadict-access.inc.php index daef9425eb..b1908b1b1d 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-access.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-access.inc.php @@ -1,7 +1,7 @@ connection) ) { + return $name; + } + + $quote = $this->connection->nameQuote; + + // if name is of the form `name`, quote it + if ( preg_match('/^`(.+)`$/', $name, $matches) ) { + return $quote . $matches[1] . $quote; + } + + // if name contains special characters, quote it + if ( !preg_match('/^[' . $this->nameRegex . ']+$/', $name) ) { + return $quote . $name . $quote; + } + + return $quote . $name . $quote; + } + + function CreateDatabase($dbname, $options=false) + { + $options = $this->_Options($options); + $sql = array(); + + $sql[] = "DECLARE EXTERNAL FUNCTION LOWER CSTRING(80) RETURNS CSTRING(80) FREE_IT ENTRY_POINT 'IB_UDF_lower' MODULE_NAME 'ib_udf'"; + + return $sql; + } + + function _DropAutoIncrement($t) + { + if (strpos($t,'.') !== false) { + $tarr = explode('.',$t); + return 'DROP GENERATOR '.$tarr[0].'."gen_'.$tarr[1].'"'; + } + return 'DROP GENERATOR "GEN_'.$t; + } + + + function _CreateSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned) + { + $suffix = ''; + + if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault"; + if ($fnotnull) $suffix .= ' NOT NULL'; + if ($fautoinc) $this->seqField = $fname; + if ($fconstraint) $suffix .= ' '.$fconstraint; + + return $suffix; + } + +/* +CREATE or replace TRIGGER jaddress_insert +before insert on jaddress +for each row +begin +IF ( NEW."seqField" IS NULL OR NEW."seqField" = 0 ) THEN + NEW."seqField" = GEN_ID("GEN_tabname", 1); +end; +*/ + function _Triggers($tabname,$tableoptions) + { + if (!$this->seqField) return array(); + + $tab1 = preg_replace( '/"/', '', $tabname ); + if ($this->schema) { + $t = strpos($tab1,'.'); + if ($t !== false) $tab = substr($tab1,$t+1); + else $tab = $tab1; + $seqField = $this->seqField; + $seqname = $this->schema.'.'.$this->seqPrefix.$tab; + $trigname = $this->schema.'.trig_'.$this->seqPrefix.$tab; + } else { + $seqField = $this->seqField; + $seqname = $this->seqPrefix.$tab1; + $trigname = 'trig_'.$seqname; + } + if (isset($tableoptions['REPLACE'])) + { $sql[] = "DROP GENERATOR \"$seqname\""; + $sql[] = "CREATE GENERATOR \"$seqname\""; + $sql[] = "ALTER TRIGGER \"$trigname\" BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END"; + } + else + { $sql[] = "CREATE GENERATOR \"$seqname\""; + $sql[] = "CREATE TRIGGER \"$trigname\" FOR $tabname BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END"; + } + + $this->seqField = false; + return $sql; + } + +} + + +?> \ No newline at end of file diff --git a/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php b/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php index d2e5f4a0dd..30c4e66c1b 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-generic.inc.php @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php b/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php index 3af2a178a8..fa8b47b62e 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-mysql.inc.php @@ -1,7 +1,7 @@ debug) ADOConnection::outp("DropColumnSQL not supported for Oracle"); - return array(); + if (!is_array($flds)) $flds = explode(',',$flds); + $sql = array(); + $s = "ALTER TABLE $tabname DROP("; + $s .= implode(',',$flds).') CASCADE COSTRAINTS'; + $sql[] = $s; + return $sql; } function _DropAutoIncrement($t) @@ -178,14 +186,20 @@ end; if ($t !== false) $tab = substr($tabname,$t+1); else $tab = $tabname; $seqname = $this->schema.'.'.$this->seqPrefix.$tab; - $trigname = $this->schema.'.TRIG_'.$this->seqPrefix.$tab; + $trigname = $this->schema.'.'.$this->trigPrefix.$this->seqPrefix.$tab; } else { $seqname = $this->seqPrefix.$tabname; - $trigname = "TRIG_$seqname"; + $trigname = $this->trigPrefix.$seqname; } if (isset($tableoptions['REPLACE'])) $sql[] = "DROP SEQUENCE $seqname"; - $sql[] = "CREATE SEQUENCE $seqname"; - $sql[] = "CREATE OR REPLACE TRIGGER $trigname BEFORE insert ON $tabname FOR EACH ROW BEGIN select $seqname.nextval into :new.$this->seqField from dual; END;"; + $seqCache = ''; + if (isset($tableoptions['SEQUENCE_CACHE'])){$seqCache = $tableoptions['SEQUENCE_CACHE'];} + $seqIncr = ''; + if (isset($tableoptions['SEQUENCE_INCREMENT'])){$seqIncr = ' INCREMENT BY '.$tableoptions['SEQUENCE_INCREMENT'];} + $seqStart = ''; + if (isset($tableoptions['SEQUENCE_START'])){$seqIncr = ' START WITH '.$tableoptions['SEQUENCE_START'];} + $sql[] = "CREATE SEQUENCE $seqname $seqStart $seqIncr $seqCache"; + $sql[] = "CREATE OR REPLACE TRIGGER $trigname BEFORE insert ON $tabname FOR EACH ROW WHEN (NEW.$this->seqField IS NULL OR NEW.$this->seqField = 0) BEGIN select $seqname.nextval into :new.$this->seqField from dual; END;"; $this->seqField = false; return $sql; diff --git a/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php b/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php index fba038b3e2..a809472e7a 100644 --- a/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php +++ b/phpgwapi/inc/adodb/datadict/datadict-postgres.inc.php @@ -1,7 +1,7 @@

ADOdb Library for PHP

-

V4.22 15 Apr 2004 (c) 2000-2004 John Lim (jlim#natsoft.com)

+

V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com)

This software is dual licensed using BSD-Style and LGPL. This means you can use it in compiled proprietary and commercial products.

-

Useful ADOdb links: Download   Other Docs + + +
Kindly note that the ADOdb home page has moved to http://adodb.sourceforge.net/ because of the persistent + unreliability of http://php.weblogs.com. Please change your links!
+

Useful ADOdb links: Download   Other Docs

Introduction
Unique Features
@@ -181,7 +185,7 @@ visit http://php.weblog

Feature requests and bug reports can be emailed to jlim#natsoft.com.my or posted to the ADOdb Help forums at http://phplens.com/lens/lensforum/topics.php?id=4.

Installation Guide

-

Make sure you are running PHP 4.0.4 or later. +

Make sure you are running PHP 4.0.5 or later. Unpack all the files into a directory accessible by your webserver.

To test, try modifying some of the tutorial examples. Make sure you customize the connection settings correctly. You can debug using $db->debug = true as shown below:

@@ -244,6 +248,7 @@ PHP will share the same connection. This can cause problems if the connections a different databases. The solution is to always use different userid's for different databases, or use NConnect(). +

Examples of Connecting to Databases

MySQL and Most Other Database Drivers

MySQL connections are very straightforward, and the parameters are identical @@ -262,7 +267,7 @@ different databases. The solution is to always use different userid's for differ

b. the classical 4 parameters:

 	$conn->PConnect('localhost','userid','password','database');
- 
+

LDAP

Here is an example of querying a LDAP server. Thanks to Josh Eldridge for the driver and this example:

@@ -295,10 +300,8 @@ if ($rs)
 		$rs->MoveNext();
 	} 
 	
-$rs = $ldap->Execute( $filter );
 print_r( $ldap->GetArray( $filter ) );
 
-$rs = $ldap->Execute( $filter );
 print_r( $ldap->GetRow( $filter ) );
 
 $ldap->Close();
@@ -311,30 +314,35 @@ You define the database in the $host parameter:
 	$conn->PConnect('localhost:c:\ibase\employee.gdb','sysdba','masterkey');
 

SQLite

-Sqlite will create database if it does not exist. +Sqlite will create the database file if it does not exist.
 	$conn = &ADONewConnection('sqlite'); 
 	$conn->PConnect('c:\path\to\sqlite.db'); # sqlite will create if does not exist
 
-

Oracle

-

With Oracle, you can connect in multiple ways.

+

Oracle (oci8)

+

With oci8, you can connect in multiple ways. Note that oci8 works fine with +newer versions of the Oracle, eg. 9i and 10g.

a. PHP and Oracle reside on the same machine, use default SID.

	$conn->Connect(false, 'scott', 'tiger');
-

b. TNS Name defined, eg. 'myTNS'

-
	$conn->PConnect(false, 'scott', 'tiger', 'myTNS');
-
+

b. TNS Name defined in tnsnames.ora (or ONAMES or HOSTNAMES), eg. 'myTNS'

+
	$conn->PConnect(false, 'scott', 'tiger', 'myTNS');

or

 	$conn->PConnect('myTNS', 'scott', 'tiger');

c. Host Address and SID

	$conn->Connect('192.168.0.1', 'scott', 'tiger', 'SID');

d. Host Address and Service Name

	$conn->Connect('192.168.0.1', 'scott', 'tiger', 'servicename');
+

e. Oracle connection string: +

	$cstr = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=$host)(PORT=$port))
+			(CONNECT_DATA=(SID=$sid)))";
+	$conn->Connect($cstr, 'scott', 'tiger');
+

DSN-less ODBC (access and mssql examples)

ODBC DSN's can be created in the ODBC control panel, or you can use a DSN-less connection.To use DSN-less connections with ODBC you need PHP 4.3 or later.

-

For Microsoft Access:

+

For Microsoft Access:

 	$db =& ADONewConnection('access');
 	$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=d:\\northwind.mdb;Uid=Admin;Pwd=;";
@@ -346,6 +354,11 @@ For Microsoft SQL Server:
 	$dsn = "Driver={SQL Server};Server=localhost;Database=northwind;";
 	$db->Connect($dsn,'userid','password');
 
+or if you prefer to use the mssql extension (which is limited to mssql 6.5 functionality): +
+	$db =& ADONewConnection('mssql');
+	$db->Execute("localhost', 'userid', 'password', 'northwind');
+
DSN-less Connections with ADO
If you are using versions of PHP earlier than PHP 4.3.0, DSN-less connections only work with Microsoft's ADO, which is Microsoft's COM based API. An example @@ -385,7 +398,7 @@ using the ADOdb library and Microsoft's ADO:

The fastest way to access the fields is by accessing the array $recordset->fields directly. Also set the global variables $ADODB_FETCH_MODE = ADODB_FETCH_NUM, and (for oci8, ibase/firebird and odbc) $ADODB_COUNTRECS = false - before you connect to your database. At the time of writing (Dec 2003).

+ before you connect to your database.

Consider using bind parameters if your database supports it, as it improves query plan reuse. Use ADOdb's performance tuning system to identify bottlenecks quickly. At the time of writing (Dec 2003), this means oci8 and odbc drivers.

@@ -470,6 +483,8 @@ catch exceptions on errors as they occur.

Note that reaching EOF is not considered an error nor an exception.

Databases Supported

+The name below is the value you pass to NewADOConnection($name) to create a connection object for that database. +

@@ -572,19 +587,11 @@ catch exceptions on errors as they occur. - - - - - - - - + - + @@ -637,7 +644,7 @@ catch exceptions on errors as they occur. - + @@ -799,11 +806,26 @@ catch exceptions on errors as they occur. - + + + + + + + + + + + @@ -1096,6 +1118,10 @@ $conn->Execute($updateSQL); # Update the record in the database $conn->Close(); ?> +GetInsertSQL/GetUpdateSQL ignore all empty fields (they are not added to the SQL generated). +To explicitly force a field to be set to "null", set the constant define('ADODB_FORCE_NULLS',1) before +you call the functions. +

Example 8: Implementing Scrolling with Next and Previous

The following code creates a very simple recordset pager, where you can scroll from page to page of a recordset.

@@ -1373,12 +1399,38 @@ PEAR::setErrorHandling('PEAR_ERROR_DIE'); $databasename = 'xphplens'; $driver = 'mysql'; $dsn = "$driver://$username:$password@$hostname/$databasename"; -
   $db = DB::Connect($dsn);
$rs = $db->Execute('select firstname,lastname from adoxyz'); +
   $db = DB::Connect($dsn);
$rs = $db->query('select firstname,lastname from adoxyz'); $cnt = 0; - while ($arr = $rs->FetchRow()) { + while ($arr = $rs->fetchRow()) { print_r($arr); print "<br>"; }

This requires PEAR to be installed and in the default include path in php.ini.

+

PEAR Compatibility

+ We support DSN's (see above), and the following functions: +
+ DB_Common
+ 	query - returns PEAR_Error on error
+	limitQuery - return PEAR_Error on error
+	prepare - does not return PEAR_Error on error
+	execute - does not return PEAR_Error on error
+	setFetchMode - supports ASSOC and ORDERED
+	errorNative
+	quote
+	nextID
+	disconnect
+	
+	getOne
+	getAssoc
+	getRow
+	getCol
+	
+ DB_Result
+ 	numRows - returns -1 if not supported
+	numCols
+	fetchInto - does not support passing of fetchmode
+	fetchRows - does not support passing of fetchmode
+	free
+

Caching of Recordsets

ADOdb now supports caching of recordsets using the CacheExecute( ), CachePageExecute( ) and CacheSelectLimit( ) functions. There are similar to the non-cache functions, @@ -1407,7 +1459,8 @@ $rs = $conn->CacheExec $rs = $conn->CacheExecute('select * from table');

Please note that magic_quotes_runtime should be turned off. More - info. + info, and do not change $ADODB_FETCH_MODE (or SetFetchMode) + as the cached recordset will use the $ADODB_FETCH_MODE set when the query was executed.

Pivot Tables

Since ADOdb 2.30, we support the generation of SQL to create pivot tables, also known as cross-tabulations. For further explanation @@ -1700,7 +1753,7 @@ in adodb/lang/adodb-$lang.inc.php, where $lang is the supported langauge.

Non-persistent connect to data source or server $host, using userid $user and password $password. If the server supports multiple databases, connect to database $database.

-

Returns true/false depending on connection.

+

Returns true/false depending on connection success. Since 4.23, null is returned if the extension is not loaded.

ADO Note: If you are using a Microsoft ADO and not OLEDB, you can set the $database parameter to the OLEDB data provider you are using.

PostgreSQL: An alternative way of connecting to the database is to pass the @@ -1715,8 +1768,10 @@ in adodb/lang/adodb-$lang.inc.php, where $lang is the supported langauge.

 # $oraname in tnsnames.ora/ONAMES/HOSTNAMES
  $conn->Connect(false, 'scott', 'tiger', $oraname); 
  $conn->Connect('server:1521', 'scott', 'tiger', 'ServiceName'); # bypass tnsnames.ora
-

There are many examples of connecting to a database at php.weblogs.com/ADOdb, +

There are many examples of connecting to a database. +See Connection Examples, php.weblogs.com/ADOdb, and in the testdatabases.inc.php file included in the release.

+

PConnect($host,[$user],[$password],[$database])

Persistent connect to data source or server $host, using userid $user and password $password. If the server supports multiple databases, @@ -1724,7 +1779,8 @@ in adodb/lang/adodb-$lang.inc.php, where $lang is the supported langauge.

We now perform a rollback on persistent connection for selected databases since 2.21, as advised in the PHP manual. See change log or source code for which databases are affected. -

Returns true/false depending on connection. See Connect( ) above for more info.

+

Returns true/false depending on connection. Since 4.23, null is returned if the extension is not loaded. +See Connect( ) above for more info.

Since ADOdb 2.21, we also support autoRollback. If you set:

 $conn = &NewADOConnection('mysql');
@@ -1738,6 +1794,8 @@ in adodb/lang/adodb-$lang.inc.php, where $lang is the supported langauge.
 

Since ADOdb 3.11, you can force non-persistent connections even if PConnect is called by defining the constant ADODB_NEVER_PERSIST before you call PConnect. +

+Since 4.23, null is returned if the extension is not loaded.

NConnect($host,[$user],[$password],[$database])

Always force a new connection. In contrast, PHP sometimes reuses connections when you use Connect() or PConnect(). Currently works only on mysql (PHP 4.3.0 @@ -2042,7 +2100,7 @@ $ret = $db->Replace('atable2', array('firstname'=>"'Harun'",'lastname'=>"'Al-Rashid'", 'age' => 'null'), array('lastname','firstname'));

-

GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false)

+

GetUpdateSQL(&$rs, $arrFields, $forceUpdate=false,$magicq=false, $forcenulls=false)

Generate SQL to update a table given a recordset $rs, and the modified fields of the array $arrFields (which must be an associative array holding the column names and the new values) are compared with the current recordset. If $forceUpdate @@ -2051,15 +2109,19 @@ $ret = $db->Replace('atable2', to indicate whether magic quotes are enabled (see qstr()). The field names in the array are case-insensitive.

Since 3.61, define('ADODB_FORCE_NULLS',1) and all PHP nulls will be auto-converted to SQL nulls. -

GetInsertSQL(&$rs, $arrFields,$magicq=false)

+ Since 4.24, we allow you to pass in $forcenulls as a parameter. This overrides the ADODB_FORCE_NULLS + constant. +

GetInsertSQL(&$rs, $arrFields,$magicq=false,$forcenulls=false)

Generate SQL to insert into a table given a recordset $rs. Requires the query to be associative. $magicq is used to indicate whether magic quotes are enabled (for qstr()). The field names in the array are case-insensitive.

- +

+ Since 2.42, you can pass a table name instead of a recordset into +GetInsertSQL (in $rs), and it will generate an insert statement for that table.

Since 3.61, define('ADODB_FORCE_NULLS',1) and all PHP nulls will be auto-converted to SQL nulls. - Since ADOdb 2.42, you can pass a table name instead of a recordset into -GetInsertSQL (in $rs), and it will generate an insert statement for that table. +Since 4.24, we allow you to pass in $forcenulls as a parameter. This overrides the ADODB_FORCE_NULLS + constant.

PageExecute($sql, $nrows, $page, $inputarr=false)

Used for pagination of recordset. $page is 1-based. See Example 8.

@@ -2608,9 +2670,9 @@ printf("<p>Total queries=%d; total cached=%d</p>",$EXECS+$ (required for some databases).

For schema support, pass in the $table parameter, "$schema.$tablename". This is only supported for selected databases. -

MetaColumnNames($table)

+

MetaColumnNames($table,$numericIndex=false)

Returns an array of column names for $table. Since ADOdb 4.22, this is an associative array, with the -keys in uppercase. +keys in uppercase. Set $numericIndex=true if you want the old behaviour of numeric indexes (since 4.23).

e.g. array('FIELD1' => 'Field1', 'FIELD2'=>'Field2')

@@ -3082,7 +3144,97 @@ $rs = $conn->Execute PHP.

Change Log

-

4.?? 2004 +

4.50 6 July 2004 +

Bumped it to 4.50 to avoid confusion with PHP 4.3.x series. +

Added alpha PDO driver. Very buggy, only works with odbc. +

Tested mysqli. Set poorAffectedRows = true. Cleaned up movenext() and _fetch(). +

PageExecute does not work properly with php5 (return val not a variable). Reported Dmytro Sychevsky sych#php.com.ua. Fixed. +

MetaTables() for mysql, $showschema parameter was not backward compatible with older versions of adodb. Fixed. +

Changed mysql GetOne() to work with mysql 3.23 when using with non-select stmts (e.g. SHOW TABLES). +

Changed TRIG_ prefix to a variable in datadict-oci8.inc.php. Thx to Luca.Gioppo#csi.it. +

New to adodb-time code. We allow you to define your own daylights savings function, +adodb_daylight_sv for pre-1970 dates. If the function is defined +(somewhere in an include), then you can correct +for daylights savings. See http://phplens.com/phpeverywhere/node/view/16#daylightsavings +for more info. +

New sqlitepo driver. This is because assoc mode does not work like other drivers in sqlite. + Namely, when selecting (joining) multiple tables, in assoc mode the table + names are included in the assoc keys in the "sqlite" driver. + In "sqlitepo" driver, the table names are stripped from the returned column names. + When this results in a conflict, the first field get preference. + Contributed by Herman Kuiper herman#ozuzo.net +

Added $forcenull parameter to GetInsertSQL/GetUpdateSQL. Idea by Marco Aurelio Silva. +

More XHTML changes for GetMenu. By Jeremy Evans. +

Fixes some ibase date issues. Thx to stefan bogdan. +

Improvements to mysqli driver to support $ADODB_COUNTRECS. +

Fixed adodb-csvlib.inc.php problem when reading stream from socket. We need to poll stream continiously. +

4.23 16 June 2004 +

+New interbase/firebird fixes thx to Lester Caine. +Driver fixes a problem with getting field names in the result array, and +corrects a couple of data conversions. Also we default to dialect3 for firebird. +Also ibase sysDate property was wrong. Changed to cast as timestamp. +

+The datadict driver is set up to give quoted tables and fields as this +was the only way round reserved words being used as field names in +TikiWiki. TikiPro is tidying that up, and I hope to be able to produce a +build of THAT which uses what I consider proper UPPERCASE field and +table names. The conversion of TikiWiki to ADOdb helped in that, but +until the database is completely tidied up in TikiPro ... +

Modified _gencachename() to include fetchmode in name hash. +This means you should clear your cache directory after installing this release as the +cache name algorithm has changed. +

Now Cache* functions work in safe mode, because we do not create sub-directories in the $ADODB_CACHE_DIR in safe mode. In non-safe mode we still create sub-directories. Done by modifying _gencachename(). +

Added $gmt parameter (true/false) to UserDate and UserTimeStamp in connection class, to force conversion of input (in local time) to be converted to UTC/GMT. +

Mssql datadict did not support INT types properly (no size param allowed). +Added _GetSize() to datadict-mssql.inc.php. +

For borland_ibase, BeginTrans(), changed:
+

   $this->_transactionID = $this->_connectionID;
+to
+
   $this->_transactionID = ibase_trans($this->ibasetrans, $this->_connectionID);
+ +

Fixed typo in mysqi_field_seek(). Thx to Sh4dow (sh4dow#php.pl). +

LogSQL did not work with Firebird/Interbase. Fixed. +

Postgres: made errorno() handling more consistent. Thx to Michael Jahn, Michael.Jahn#mailbox.tu-dresden.de. +

Added informix patch to better support metatables, metacolumns by "Cecilio Albero" c-albero#eos-i.com +

Cyril Malevanov contributed patch to oci8 to support passing of LOB parameters: +

+	$text = 'test test test';
+	$sql = "declare rs clob; begin :rs := lobinout(:sa0); end;";
+	$stmt = $conn -> PrepareSP($sql);
+	$conn -> InParameter($stmt,$text,'sa0', -1, OCI_B_CLOB);
+	$rs = '';
+	$conn -> OutParameter($stmt,$rs,'rs', -1, OCI_B_CLOB);
+	$conn -> Execute($stmt);
+	echo "return = ".$rs."<br>";
+
+As he says, the LOBs limitations are: +
+ - use OCINewDescriptor before binding
+ - if Param is IN, uses save() before each execute. This is done automatically for you.
+ - if Param is OUT, uses load() after each execute. This is done automatically for you.
+ - when we bind $var as LOB, we create new descriptor and return it as a
+   Bind Result, so if we want to use OUT parameters, we have to store
+   somewhere &$var to load() data from LOB to it.
+ - IN OUT params are not working now (should not be a big problem to fix it)
+ - now mass binding not working too (I've wrote about it before)
+
+

Simplified Connect() and PConnect() error handling. +

When extension not loaded, Connect() and PConnect() will return null. On connect error, the fns will return false. +

CacheGetArray() added to code. +

Added Init() to adorecordset_empty(). +

Changed postgres64 driver, MetaColumns() to not strip off quotes in default value if :: detected (type-casting of default). +

Added test: if (!defined('ADODB_DIR')) die(). Useful to prevent hackers from detecting file paths. +

Changed metaTablesSQL to ignore Postgres 7.4 information schemas (sql_*). +

New polish language file by Grzegorz Pacan +

Added support for UNION in _adodb_getcount(). +

Added security check for ADODB_DIR to limit path disclosure issues. Requested by postnuke team. +

Added better error message support to oracle driver. Thx to Gaetano Giunta. +

Added showSchema support to mysql. +

Bind in oci8 did not handle $name=false properly. Fixed. +

If extension not loaded, Connect(), PConnect(), NConnect() will return null. +

4.22 15 Apr 2004 +

Moved docs to own adodb/docs folder.

Fixed session bug when quoting compressed/encrypted data in Replace().

Netezza Driver and LDAP drivers contributed by Josh Eldridge.

GetMenu now uses rtrim() on values instead of trim(). diff --git a/phpgwapi/inc/adodb/docs/docs-datadict.htm b/phpgwapi/inc/adodb/docs/docs-datadict.htm index f2702e44d3..a815749dbb 100644 --- a/phpgwapi/inc/adodb/docs/docs-datadict.htm +++ b/phpgwapi/inc/adodb/docs/docs-datadict.htm @@ -18,9 +18,11 @@

ADOdb Data Dictionary Library for PHP

-

V4.22 15 Apr 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my).
AXMLS (c) 2004 ars Cognita, Inc

+

V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim#natsoft.com.my).
AXMLS (c) 2004 ars Cognita, Inc

This software is dual licensed using BSD-Style and LGPL. This means you can use it in compiled proprietary and commercial products.

-

Useful ADOdb links: Download   Other Docs

+
NameInterbase client Unix and Windows
informix72C Informix databases before Informix 7.3 that do no support - SELECT FIRST.Y/NInformix clientUnix and Windows
informix CGeneric informix driver.Generic informix driver. Use this if you are using Informix 7.3 or later. Y/N Informix client Unix and WindowsA MySQL without transaction support. You can also set $db->clientFlags before connecting.Y/NY MySQL client Unix and Windows
sqlite BSQLite. Only tested on PHP5.SQLite. Y -

Unix and Windows.

sqlitepoBPortable SQLite driver. This is because assoc mode does not work like other drivers in sqlite. + Namely, when selecting (joining) multiple tables, the table + names are included in the assoc keys in the "sqlite" driver.

+ In "sqlitepo" driver, the table names are stripped from the returned column names. + When this results in a conflict, the first field get preference. +

Y-

Unix and Windows.

sybase C
Kindly note that the ADOdb home page has moved to http://adodb.sourceforge.net/ because of the persistent + unreliability of http://php.weblogs.com. Please change your links!
+

Useful ADOdb links: Download   Other Docs

This documentation describes a PHP class library to automate the creation of tables, indexes and foreign key constraints portably for multiple databases. Richard Tango-Lowy and Dan Cech @@ -138,7 +140,7 @@ field size. Then optional keywords in $otheroptions:

NAME C(32) CONSTRAINTS 'FOREIGN KEY REFERENCES reftable' "; -

Note that if you have special characters in the field name (e.g. My Date), you should enclose it in back-quotes. Normally field names are not case-sensitive, but if you enclose it in back-quotes, some databases treat the names as case-sensitive, and some don't. So be careful.

+

Note that if you have special characters in the field name (e.g. My Date), you should enclose it in back-quotes. Normally field names are not case-sensitive, but if you enclose it in back-quotes, some databases will treat the names as case-sensitive (eg. Oracle) , and others won't. So be careful.

The $taboptarray is the 3rd parameter of the CreateTableSQL function. This contains table specific settings. Legal keywords include: