0) $GLOBALS['Conf']->Site->Domain = substr( $Domain, 0, $pos ); unset($pathinfo[ count($pathinfo) - 1 ]); $Path = implode( '/', $pathinfo); /** * Check dirrectory */ /* $filename = md5( rand() ); if (!mkdir("$Path/$filename/", 0777) || !chmod("$Path/$filename", 0777) || !unlink("$Path/$filename")) { die(" Sorry, but current dirrectory ($Path) is not writable

Setup Canceled



Note for Linu/Unix: dirrectory rigth must be 0777
Note for Windows: dirrectory rigth must have full access for Evrygone
"); } */ /** * Content Array */ $files = array ( '.htaccess' => ' php_flag magic_quotes_gpc off php_flag session.use_trans_sid on Deny From All RewriteEngine Off', 'generator.php' => 'Site->Domain = str_replace( \'/\'.$pathinfo[ count($pathinfo) - 1 ], \'\', \'http://\'.$_SERVER["SERVER_NAME"].$_SERVER[\'REQUEST_URI\']); $pos = strpos( $GLOBALS[\'Conf\']->Site->Domain, \'?\'); if ( $pos > 0) $GLOBALS[\'Conf\']->Site->Domain = substr( $GLOBALS[\'Conf\']->Site->Domain, 0, $pos ); unset($pathinfo[ count($pathinfo) - 1 ]); $GLOBALS[\'Conf\']->Site->Path = implode( \'/\', $pathinfo); /** * Include all standart functions and main classes */ include_once("~core/prepend.inc"); /** * Set Core Parameters */ error_reporting(E_ALL ^ E_NOTICE); //^ E_WARNING); set_magic_quotes_runtime(0); /** * Delete quotes from standart collections */ if (get_magic_quotes_gpc()) { stripslashes_array($_GET); stripslashes_array($_POST); stripslashes_array($_COOKIES); } /** * Start session */ ini_set(\'session.cookie_domain\', \'.links.com\'); session_name(\'DS\'); session_start(); /** * Get sity config */ include_once("~core/config.inc"); $_SESSION["Conf"] = $Conf; $tmp = \'$user_id=\'.$_GET[\'user_id\'].\';\'; write_to_inc( \'user_id.inc\', &$tmp); /** * Processign request */ ignore_user_abort(true); set_time_limit(0); $TML = new Smarty_class(); $DB = &ADONewConnection(\'mysql\'); $DB->debug = false; include_once(\'user_id.inc\'); if (isset($_POST[\'action\']) && $_POST[\'action\'] != \'\') $_GET[\'action\'] = $_POST[\'action\']; switch ($_GET[\'action\']) { case \'updatedata\': include_once(\'updatedata.inc\'); break; case \'updatefile\': include_once(\'updatefile.inc\'); break; default: include_once(\'putinfo.inc\'); $GLOBALS[\'Conf\']->System->ShowBenchmarkInfo = false; } /** * Benchmark end */ if ($GLOBALS[\'Conf\']->System->ShowBenchmarkInfo) { $time=explode( " ", microtime()); echo \'

Page created from \'.(round( ((double)$time[1]+(double)$time[0])-$GLOBALS[\'page_start\'], 3)).\'
\'; echo \'sql-queries has been run \'.$GLOBALS[\'sql_count\'].\'
\'; echo \'page from cache \'.($GLOBALS[\'debug.is_cache\']?\'yes\':\'no\').\' \'; } ?>', 'getdata.inc' => 'QExecute(\' SELECT id, pos, title, htmltitle FROM category WHERE visible = \'.VISIBLE.\' AND point >= "\'.$point.\'" ORDER BY pos, title \'); if ($new_categorys->RecordCount() > 0) { $new_categorys = $new_categorys->GetArray(); $target = \'~data/categorys.inc\'; if (!file_exists($target)) { $category = array(); } else { //$category[id]=array(pos,title,htmltitle); include($target); } foreach($new_categorys as $key => $new_category) { $category[ $new_category[\'id\'] ] = array( $new_category[\'pos\'], $new_category[\'title\'], $new_category[\'htmltitle\'] ); } sortarray( &$category ); reset($category); write_to_inc($target, arrofarr_to_str( \'category\', $category ) ); unset($category); } /** * Get and store new ad updated themes */ $new_themes = $DB->QExecute(\' SELECT id, pos, title, htmltitle, category_id FROM theme WHERE visible = \'.VISIBLE.\' AND point >= "\'.$point.\'" ORDER BY category_id, pos, title \'); if ($new_themes->RecordCount() > 0 ) { $new_themes = $new_themes->GetArray(); $category_id = $new_themes[0][\'category_id\']; $themename = \'theme\'.$category_id; $target = \'~data/\'.$themename.\'.inc\'; $th = &$$themename; if (!file_exists($target)) { $th = array(); } else { include($target); } foreach($new_themes as $key => $new_theme) { if ($new_theme[\'category_id\'] != $category_id) { sortarray( &$th ); reset($th); write_to_inc($target, arrofarr_to_str( $themename, $th ) ); unset($th); $category_id = $new_theme[\'category_id\']; $themename = \'theme\'.$category_id; $target = \'~data/\'.$themename.\'.inc\'; $th = &$$themename; if (!file_exists($target)) { $th = array(); } else { include($target); } } $th[ $new_theme[\'id\'] ] = array( $new_theme[\'pos\'], $new_theme[\'title\'], $new_theme[\'htmltitle\'] ); } sortarray( &$th ); reset($th); write_to_inc($target, arrofarr_to_str( $themename, $th ) ); unset($th); } /** * Get and store new ad updated link */ $themesids = $DB->QExecute(\' SELECT id FROM theme WHERE visible = \'.VISIBLE.\' ORDER BY id \'); if ($themesids->RecordCount() > 0 ) $themesids = $themesids->GetArray(); else $themesids = array(); foreach($themesids as $key => $themeid) { $rsnew_links = $DB->QExecute(\' SELECT id, title, url, description, theme_id FROM link WHERE visible = \'.VISIBLE.\' AND point >= "\'.$point.\'" AND theme_id = \'.$themeid[\'id\'].\' ORDER BY title \'); if ($rsnew_links->RecordCount() > 0 ) { $new_links = $rsnew_links->GetArray(); unset($rsnew_links); $theme_id = $themeid[\'id\']; $linkname = \'link\'.$theme_id; $target = \'~data/\'.$linkname.\'.inc\'; $ln = &$$linkname; if (!file_exists($target)) { $ln = array(); } else { include($target); } foreach($new_links as $key => $new_link) { $ln[ $new_link[\'id\'] ] = array( $new_link[\'title\'], $new_link[\'url\'], $new_link[\'description\'] ); } ksort($ln); reset($ln); $str = arrofarr_to_str( $linkname, $ln ); write_to_inc($target, &$str ); unset($ln); unset($$linkname); unset($str); } unset($new_links); } /** * Array Sor Function */ function sortarray( &$arr ) { $temp = array(); foreach($arr as $ak => $av) { array_unshift($av, $ak); $temp[] = $av; } usort( &$temp, \'cmpbypos\'); $arr = array(); foreach($temp as $ak => $av) { $ak = $av[0]; array_shift($av); $arr[$ak] = $av; } } function cmpbypos($a, $b) { if ($a[1] == $b[1]) { return 0; } return ($a[1] < $b[1]) ? -1 : 1; } ?>', 'paker.php' => '\'); //print_r($GLOBALS[\'tree\']); function readfilenames($path, $maxlevel, $level) { if ($dir = opendir($path)) { while (($file = readdir($dir)) !== false) { if ($file != \'.\' && $file != \'..\') { if (is_dir($path.\'/\'.$file)) { if ($level == $maxlevel) $GLOBALS[\'tree\'][str_replace($GLOBALS[\'const\'].\'/\', \'\', $path.\'/\'.$file.\'/\')] = file_get_contents($path.\'/\'.$file); if ($level < $maxlevel) { //if ($level != 1) //$GLOBALS[\'tree\'][str_replace($GLOBALS[\'const\'].\'/\', \'\', $path.\'/\')] = \'\'; readfilenames($path.\'/\'.$file, $maxlevel, $level + 1); } } else { $GLOBALS[\'tree\'][str_replace($GLOBALS[\'const\'].\'/\', \'\', $path.\'/\'.$file)] = file_get_contents($path.\'/\'.$file); } } } closedir($dir); } } ?>', 'point.inc' => '', 'putinfo.inc' => 'System->Version; ?>', 'updatedata.inc' => '', 'updatefile.inc' => 'Site->Path.\'/\'; //.$_GET[\'target\']; $dirpath = explode(\'/\', $_GET[\'target\']); unset($dirpath[ count($dirpath) - 1 ]); foreach($dirpath as $dirname) { $target .= $dirname.\'/\'; if (file_exists($target)) unlink($target); mkdir( clearslash($target), 0777 ); chmod( clearslash($target), 0777 ); } $content = $_POST[\'content\']; $target = $GLOBALS[\'Conf\']->Site->Path.\'/\'.$_POST[\'target\']; // if (file_exists($target)) // unlink($target); $handle = fopen( $target, \'w+\' ); fwrite( $handle, $content ); fclose( $handle ); chmod( $target, 0777 ); ?>', 'user_id.inc' => '', 'workdata.inc' => 'Site->Path.\'/~design/\'.$_GET[\'style_id\'].\'/\'; $style = $GLOBALS[\'Conf\']->Site->Path.\'/~design/style.css\'; $target = $GLOBALS[\'Conf\']->Site->Path.\'/\'; /** * Build index.html */ $GLOBALS[\'level\'] = 0; $filename = $target.\'index.html\'; if (file_exists($filename)) unlink( $filename ); $handle = fopen( $filename, \'w\' ); if (file_exists(\'~data/categorys.inc\')) include($GLOBALS[\'Conf\']->Site->Path.\'/~data/categorys.inc\'); else $category = array(); $links_themes = array(); foreach($category as $key => $val) { if (file_exists(\'~data/theme\'.$key.\'.inc\')) { include($GLOBALS[\'Conf\']->Site->Path.\'/~data/theme\'.$key.\'.inc\'); $themename = \'theme\'.$key; $th = &$$themename; $temp = array(); $i = 0; foreach($th as $theme_id => $theme) { if (count($theme) > 0) $temp[] = array( $theme_id, $theme[1] ); if (++$i > 3) break; } $links_themes[$key] = $temp; unset($th); unset($temp); } } $TML->clear_all_assign(); $TML->assign(\'contentfile\', $templates.\'index.html\'); $TML->assign(\'records\', $category ); $TML->assign(\'links_themes\', $links_themes ); $TML->assign(\'color1\', $_GET[\'color1\']); $TML->assign(\'color2\', $_GET[\'color2\']); $TML->assign(\'color3\', $_GET[\'color3\']); $TML->assign(\'title\', \'Other sites links\'); fwrite( $handle, $TML->fetch( $templates.\'design.html\' )); fclose( $handle ); chmod($filename, 0777); unset($links_themes); /** * Build themes html */ foreach($category as $cat_id => $cat) { $GLOBALS[\'level\'] = 1; $themetarget = $target.\'/\'.title_encode($cat[1]).\'/\'; if (!file_exists($themetarget)) { mkdir( clearslash($themetarget), 0777 ); chmod( clearslash($themetarget), 0777); } $filename = $themetarget.\'index.html\'; if (file_exists($filename)) unlink( $filename ); $handle = fopen( $filename, \'w\' ); if (file_exists(\'~data/theme\'.$cat_id.\'.inc\')) { include($GLOBALS[\'Conf\']->Site->Path.\'/~data/theme\'.$cat_id.\'.inc\'); $themename = \'theme\'.$cat_id; $th = &$$themename; foreach($th as $theme_id => $theme) { if (file_exists($GLOBALS[\'Conf\']->Site->Path.\'/~data/link\'.$theme_id.\'.inc\')) { include($GLOBALS[\'Conf\']->Site->Path.\'/~data/link\'.$theme_id.\'.inc\'); $linkname = \'link\'.$theme_id; $ln = &$$linkname; $th[ $theme_id ][3] = count( $ln ); unset($$linkname); } else { $th[ $theme_id ][3] = 0; } } } $TML->clear_all_assign(); $TML->assign(\'th\', $th ); $TML->assign(\'links_category\', array(\'title\' => $cat[1] )); $TML->assign(\'contentfile\', $templates.\'theme.html\'); $TML->assign(\'color1\', $_GET[\'color1\']); $TML->assign(\'color2\', $_GET[\'color2\']); $TML->assign(\'color3\', $_GET[\'color3\']); $TML->assign(\'title\', $cat[1] ); fwrite( $handle, $TML->fetch( $templates.\'design.html\' )); fclose( $handle ); chmod($filename, 0777); /** * Build links html */ foreach($th as $theme_id => $theme) { $GLOBALS[\'level\'] = 2; $linktarget = $target.\'/\'.title_encode($cat[1]).\'/\'.title_encode($theme[1]).\'/\'; if (!file_exists($linktarget)) { mkdir( clearslash($linktarget), 0777 ); chmod( clearslash($linktarget), 0777); } if (file_exists(\'~data/link\'.$theme_id.\'.inc\')) include($GLOBALS[\'Conf\']->Site->Path.\'/~data/link\'.$theme_id.\'.inc\'); $linkname = \'link\'.$theme_id; $ln = &$$linkname; $link_count = count( $ln ); for ($page = 0; $page < ceil($link_count / $GLOBALS[\'Conf\']->Pager->LinkRecPerPage); $page ++) { if ($page == 0) $filename = $linktarget.\'index.html\'; else $filename = $linktarget.\'page\'.$page.\'.html\'; if (file_exists($filename)) unlink( $filename ); $handle = fopen( $filename, \'w\' ); $links_arr = array_slice( $ln, $GLOBALS[\'Conf\']->Pager->LinkRecPerPage * $page, $GLOBALS[\'Conf\']->Pager->LinkRecPerPage); $TML->clear_all_assign(); $TML->assign(\'records\', $links_arr ); $TML->assign(\'links_theme\', array( \'links_theme_title\' => $theme[1], \'links_category_title\' => $cat[1] ) ); $TML->assign(\'pagerfile\', $templates.\'pager.html\' ); linkpager( &$TML, $page, $link_count, array( \'theme_title\' => $theme[1], \'category_title\' => $cat[1] ) ); $TML->assign(\'contentfile\', $templates.\'link.html\'); $TML->assign(\'color1\', $_GET[\'color1\']); $TML->assign(\'color2\', $_GET[\'color2\']); $TML->assign(\'color3\', $_GET[\'color3\']); $TML->assign(\'title\', $cat[1].\' > \'.$theme[1] ); fwrite( $handle, $TML->fetch( $templates.\'design.html\' )); fclose( $handle ); chmod($filename, 0777); } unset($ln); } unset($th); } /* function cmp_category($a, $b) { if ((int)$a[0] == (int)$b[0]) { if ($a[1] == $b[1]) { return 0; } return ($a[1] < $b[1]) ? -1 : 1; } return ((int)$a[0] < (int)$b[0]) ? -1 : 1; } */ ?>', '~core/classes/adodb/adodb-error.inc.php' => ' DB_ERROR_NOSUCHTABLE, \'/Relation [\\"\\\'].*[\\"\\\'] already exists|Cannot insert a duplicate key into (a )?unique index.*/\' => DB_ERROR_ALREADY_EXISTS, \'/divide by zero$/\' => DB_ERROR_DIVZERO, \'/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 ); reset($error_regexps); while (list($regexp,$code) = each($error_regexps)) { if (preg_match($regexp, $errormsg)) { return $code; } } // Fall back to DB_ERROR if there was no mapping. return DB_ERROR; } function adodb_error_odbc() { static $MAP = array( \'01004\' => DB_ERROR_TRUNCATED, \'07001\' => DB_ERROR_MISMATCH, \'21S01\' => DB_ERROR_MISMATCH, \'21S02\' => DB_ERROR_MISMATCH, \'22003\' => DB_ERROR_INVALID_NUMBER, \'22008\' => DB_ERROR_INVALID_DATE, \'22012\' => DB_ERROR_DIVZERO, \'23000\' => DB_ERROR_CONSTRAINT, \'24000\' => DB_ERROR_INVALID, \'34000\' => DB_ERROR_INVALID, \'37000\' => DB_ERROR_SYNTAX, \'42000\' => DB_ERROR_SYNTAX, \'IM001\' => DB_ERROR_UNSUPPORTED, \'S0000\' => DB_ERROR_NOSUCHTABLE, \'S0001\' => DB_ERROR_NOT_FOUND, \'S0002\' => DB_ERROR_NOSUCHTABLE, \'S0011\' => DB_ERROR_ALREADY_EXISTS, \'S0012\' => DB_ERROR_NOT_FOUND, \'S0021\' => DB_ERROR_ALREADY_EXISTS, \'S0022\' => DB_ERROR_NOT_FOUND, \'S1000\' => DB_ERROR_NOSUCHTABLE, \'S1009\' => DB_ERROR_INVALID, \'S1090\' => DB_ERROR_INVALID, \'S1C00\' => DB_ERROR_NOT_CAPABLE ); return $MAP; } function adodb_error_ibase() { static $MAP = array( -104 => DB_ERROR_SYNTAX, -150 => DB_ERROR_ACCESS_VIOLATION, -151 => DB_ERROR_ACCESS_VIOLATION, -155 => DB_ERROR_NOSUCHTABLE, -157 => DB_ERROR_NOSUCHFIELD, -158 => DB_ERROR_VALUE_COUNT_ON_ROW, -170 => DB_ERROR_MISMATCH, -171 => DB_ERROR_MISMATCH, -172 => DB_ERROR_INVALID, -204 => DB_ERROR_INVALID, -205 => DB_ERROR_NOSUCHFIELD, -206 => DB_ERROR_NOSUCHFIELD, -208 => DB_ERROR_INVALID, -219 => DB_ERROR_NOSUCHTABLE, -297 => DB_ERROR_CONSTRAINT, -530 => DB_ERROR_CONSTRAINT, -803 => DB_ERROR_CONSTRAINT, -551 => DB_ERROR_ACCESS_VIOLATION, -552 => DB_ERROR_ACCESS_VIOLATION, -922 => DB_ERROR_NOSUCHDB, -923 => DB_ERROR_CONNECT_FAILED, -924 => DB_ERROR_CONNECT_FAILED ); return $MAP; } function adodb_error_ifx() { static $MAP = array( \'-201\' => DB_ERROR_SYNTAX, \'-206\' => DB_ERROR_NOSUCHTABLE, \'-217\' => DB_ERROR_NOSUCHFIELD, \'-329\' => DB_ERROR_NODBSELECTED, \'-1204\' => DB_ERROR_INVALID_DATE, \'-1205\' => DB_ERROR_INVALID_DATE, \'-1206\' => DB_ERROR_INVALID_DATE, \'-1209\' => DB_ERROR_INVALID_DATE, \'-1210\' => DB_ERROR_INVALID_DATE, \'-1212\' => DB_ERROR_INVALID_DATE ); return $MAP; } function adodb_error_oci8() { static $MAP = array( 900 => DB_ERROR_SYNTAX, 904 => DB_ERROR_NOSUCHFIELD, 923 => DB_ERROR_SYNTAX, 942 => DB_ERROR_NOSUCHTABLE, 955 => DB_ERROR_ALREADY_EXISTS, 1476 => DB_ERROR_DIVZERO, 1722 => DB_ERROR_INVALID_NUMBER, 2289 => DB_ERROR_NOSUCHTABLE, 2291 => DB_ERROR_CONSTRAINT, 2449 => DB_ERROR_CONSTRAINT ); return $MAP; } function adodb_error_mssql() { static $MAP = array( 208 => DB_ERROR_NOSUCHTABLE, 2601 => DB_ERROR_ALREADY_EXISTS ); return $MAP; } function adodb_error_sqlite() { static $MAP = array( 1 => DB_ERROR_SYNTAX ); return $MAP; } function adodb_error_mysql() { static $MAP = array( 1004 => DB_ERROR_CANNOT_CREATE, 1005 => DB_ERROR_CANNOT_CREATE, 1006 => DB_ERROR_CANNOT_CREATE, 1007 => DB_ERROR_ALREADY_EXISTS, 1008 => DB_ERROR_CANNOT_DROP, 1045 => DB_ERROR_ACCESS_VIOLATION, 1046 => DB_ERROR_NODBSELECTED, 1049 => DB_ERROR_NOSUCHDB, 1050 => DB_ERROR_ALREADY_EXISTS, 1051 => DB_ERROR_NOSUCHTABLE, 1054 => DB_ERROR_NOSUCHFIELD, 1062 => DB_ERROR_ALREADY_EXISTS, 1064 => DB_ERROR_SYNTAX, 1100 => DB_ERROR_NOT_LOCKED, 1136 => DB_ERROR_VALUE_COUNT_ON_ROW, 1146 => DB_ERROR_NOSUCHTABLE, 1048 => DB_ERROR_CONSTRAINT, 2002 => DB_ERROR_CONNECT_FAILED ); return $MAP; } ?>', '~core/classes/adodb/adodb-lib.inc.php' => '$value) $new_array[strtoupper($key)] = $value; return $new_array; } return $an_array; } function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc) { if (count($fieldArray) == 0) return 0; $first = true; $uSet = \'\'; if (!is_array($keyCol)) { $keyCol = array($keyCol); } foreach($fieldArray as $k => $v) { if ($autoQuote && !is_numeric($v) and strncmp($v,"\'",1) !== 0 and strcasecmp($v,\'null\')!=0) { $v = $zthis->qstr($v); $fieldArray[$k] = $v; } if (in_array($k,$keyCol)) continue; // skip UPDATE if is key if ($first) { $first = false; $uSet = "$k=$v"; } else $uSet .= ",$k=$v"; } $first = true; foreach ($keyCol as $v) { if ($first) { $first = false; $where = "$v=$fieldArray[$v]"; } else { $where .= " and $v=$fieldArray[$v]"; } } if ($uSet) { $update = "UPDATE $table SET $uSet WHERE $where"; $rs = $zthis->Execute($update); if ($rs) { if ($zthis->poorAffectedRows) { /* The Select count(*) wipes out any errors that the update would have returned. http://phplens.com/lens/lensforum/msgs.php?id=5696 */ if ($zthis->ErrorNo()<>0) return 0; # affected_rows == 0 if update field values identical to old values # for mysql - which is silly. $cnt = $zthis->GetOne("select count(*) from $table where $where"); if ($cnt > 0) return 1; // record already exists } else if (($zthis->Affected_Rows()>0)) return 1; } } // print "

Error=".$this->ErrorNo().\'

\'; $first = true; foreach($fieldArray as $k => $v) { if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col if ($first) { $first = false; $iCols = "$k"; $iVals = "$v"; } else { $iCols .= ",$k"; $iVals .= ",$v"; } } $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)"; $rs = $zthis->Execute($insert); return ($rs) ? 2 : 0; } // Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM function _adodb_getmenu(&$zthis, $name,$defstr=\'\',$blank1stItem=true,$multiple=false, $size=0, $selectAttr=\'\',$compareFields0=true) { $hasvalue = false; if ($multiple or is_array($defstr)) { if ($size==0) $size=5; $attr = " multiple size=$size"; if (!strpos($name,\'[]\')) $name .= \'[]\'; } else if ($size) $attr = " size=$size"; else $attr =\'\'; $s = "\\n"; } /* Count the number of records this sql statement will return by using query rewriting techniques... Does not work with UNIONs. */ function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0) { $qryRecs = 0; if (preg_match("/^\\s*SELECT\\s+DISTINCT/is", $sql) || preg_match(\'/\\s+GROUP\\s+BY\\s+/is\',$sql)) { // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias // but this is only supported by oracle and postgresql... if ($zthis->dataProvider == \'oci8\') { $rewritesql = preg_replace(\'/(\\sORDER\\s+BY\\s.*)/is\',\'\',$sql); $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)"; } else if ( $zthis->databaseType == \'postgres\' || $zthis->databaseType == \'postgres7\') { $info = $zthis->ServerInfo(); if (substr($info[\'version\'],0,3) >= 7.1) { // good till version 999 $rewritesql = preg_replace(\'/(\\sORDER\\s+BY\\s.*)/is\',\'\',$sql); $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_"; } } } else { // now replace SELECT ... FROM with SELECT COUNT(*) FROM $rewritesql = preg_replace( \'/^\\s*SELECT\\s.*\\s+FROM\\s/Uis\',\'SELECT COUNT(*) FROM \',$sql); // fix by alexander zhukov, alex#unipack.ru, because count(*) and \'order by\' fails // with mssql, access and postgresql. Also a good speedup optimization - skips sorting! $rewritesql = preg_replace(\'/(\\sORDER\\s+BY\\s.*)/is\',\'\',$rewritesql); } if (isset($rewritesql) && $rewritesql != $sql) { if ($secs2cache) { // we only use half the time of secs2cache because the count can quickly // become inaccurate if new records are added $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr); } else { $qryRecs = $zthis->GetOne($rewritesql,$inputarr); } if ($qryRecs !== false) return $qryRecs; } //-------------------------------------------- // query rewrite failed - so try slower way... // strip off unneeded ORDER BY $rewritesql = preg_replace(\'/(\\sORDER\\s+BY\\s.*)/is\',\'\',$sql); $rstest = &$zthis->Execute($rewritesql,$inputarr); if ($rstest) { $qryRecs = $rstest->RecordCount(); if ($qryRecs == -1) { global $ADODB_EXTENSION; // some databases will return -1 on MoveLast() - change to MoveNext() if ($ADODB_EXTENSION) { while(!$rstest->EOF) { adodb_movenext($rstest); } } else { while(!$rstest->EOF) { $rstest->MoveNext(); } } $qryRecs = $rstest->_currentRow; } $rstest->Close(); if ($qryRecs == -1) return 0; } return $qryRecs; } /* Code originally from "Cornel G" This code will not work with SQL that has UNION in it Also if you are using CachePageExecute(), there is a strong possibility that data will get out of synch. use CachePageExecute() only with tables that rarely change. */ function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) { $atfirstpage = false; $atlastpage = false; $lastpageno=1; // If an invalid nrows is supplied, // we assume a default value of 10 rows per page if (!isset($nrows) || $nrows <= 0) $nrows = 10; $qryRecs = false; //count records for no offset $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache); $lastpageno = (int) ceil($qryRecs / $nrows); $zthis->_maxRecordCount = $qryRecs; // 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 // a page number greater than the last page number. if ($page >= $lastpageno) { $page = $lastpageno; $atlastpage = true; } // We get the data we want $offset = $nrows * ($page-1); if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr); else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); // Before returning the RecordSet, we set the pagination properties we need if ($rsreturn) { $rsreturn->_maxRecordCount = $qryRecs; $rsreturn->rowsPerPage = $nrows; $rsreturn->AbsolutePage($page); $rsreturn->AtFirstPage($atfirstpage); $rsreturn->AtLastPage($atlastpage); $rsreturn->LastPageNo($lastpageno); } return $rsreturn; } // Iván Oliva version function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0) { $atfirstpage = false; $atlastpage = false; if (!isset($page) || $page <= 1) { // If page number <= 1, then we are at the first page $page = 1; $atfirstpage = true; } if ($nrows <= 0) $nrows = 10; // If an invalid nrows is supplied, we assume a default value of 10 rows per page // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than // the last page number. $pagecounter = $page + 1; $pagecounteroffset = ($pagecounter * $nrows) - $nrows; if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr); else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache); if ($rstest) { while ($rstest && $rstest->EOF && $pagecounter>0) { $atlastpage = true; $pagecounter--; $pagecounteroffset = $nrows * ($pagecounter - 1); $rstest->Close(); if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr); else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache); } if ($rstest) $rstest->Close(); } if ($atlastpage) { // If we are at the last page or beyond it, we are going to retrieve it $page = $pagecounter; if ($page == 1) $atfirstpage = true; // We have to do this again in case the last page is the same as the first //... page, that is, the recordset has only 1 page. } // We get the data we want $offset = $nrows * ($page-1); if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr); else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache); // Before returning the RecordSet, we set the pagination properties we need if ($rsreturn) { $rsreturn->rowsPerPage = $nrows; $rsreturn->AbsolutePage($page); $rsreturn->AtFirstPage($atfirstpage); $rsreturn->AtLastPage($atlastpage); } return $rsreturn; } function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false) { if (!$rs) { printf(ADODB_BAD_RS,\'GetUpdateSQL\'); return false; } $fieldUpdatedCount = 0; $arrFields = _array_change_key_case($arrFields); $hasnumeric = isset($rs->fields[0]); $updateSQL = \'\'; // Loop through all of the fields in the recordset for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { // Get the field from the recordset $field = $rs->FetchField($i); // If the recordset field is one // of the fields passed in then process. $upperfname = strtoupper($field->name); if (adodb_key_exists($upperfname,$arrFields)) { // If the existing field value in the recordset // is different from the value passed in then // go ahead and append the field name and new value to // the update query. if ($hasnumeric) $val = $rs->fields[$i]; else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname]; else if (isset($rs->fields[$field->name])) $val = $rs->fields[$field->name]; else if (isset($rs->fields[strtolower($upperfname)])) $val = $rs->fields[strtolower($upperfname)]; else $val = \'\'; if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) { // Set the counter for the number of fields that will be updated. $fieldUpdatedCount++; // Based on the datatype of the field // Format the value properly for the database $mt = $rs->MetaType($field->type); // "mike" patch and "Ryan Bailey" //PostgreSQL uses a \'t\' or \'f\' and therefore needs to be processed as a string (\'C\') type field. if ((strncmp($zthis->databaseType,"postgres",8) === 0) && ($mt == "L")) $mt = "C"; // is_null requires php 4.0.4 if ((defined(\'ADODB_FORCE_NULLS\') && is_null($arrFields[$upperfname])) || $arrFields[$upperfname] === \'null\') $updateSQL .= $field->name . " = null, "; else switch($mt) { case \'null\': case "C": case "X": case \'B\': $updateSQL .= $field->name . " = " . $zthis->qstr($arrFields[$upperfname],$magicq) . ", "; break; case "D": $updateSQL .= $field->name . " = " . $zthis->DBDate($arrFields[$upperfname]) . ", "; break; case "T": $updateSQL .= $field->name . " = " . $zthis->DBTimeStamp($arrFields[$upperfname]) . ", "; break; default: $val = $arrFields[$upperfname]; if (!is_numeric($val)) $val = (float) $val; $updateSQL .= $field->name . " = " . $val . ", "; break; }; }; }; }; // If there were any modified fields then build the rest of the update query. if ($fieldUpdatedCount > 0 || $forceUpdate) { // Get the table name from the existing query. preg_match("/FROM\\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName); // Get the full where clause excluding the word "WHERE" from // the existing query. preg_match(\'/\\sWHERE\\s(.*)/is\', $rs->sql, $whereClause); $discard = false; // not a good hack, improvements? if ($whereClause) preg_match(\'/\\s(LIMIT\\s.*)/is\', $whereClause[1], $discard); else $whereClause = array(false,false); if ($discard) $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1])); // updateSQL will contain the full update query when all // processing has completed. $updateSQL = "UPDATE " . $tableName[1] . " SET ".substr($updateSQL, 0, -2); // If the recordset has a where clause then use that same where clause // for the update. if ($whereClause[1]) $updateSQL .= " WHERE " . $whereClause[1]; return $updateSQL; } else { return false; }; } function adodb_key_exists($key, &$arr) { if (!defined(\'ADODB_FORCE_NULLS\')) { // the following is the old behaviour where null or empty fields are ignored return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0); } if (isset($arr[$key])) return true; ## null check below if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr); return false; } function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false) { $values = \'\'; $fields = \'\'; $arrFields = _array_change_key_case($arrFields); if (!$rs) { printf(ADODB_BAD_RS,\'GetInsertSQL\'); return false; } $fieldInsertedCount = 0; // Loop through all of the fields in the recordset for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) { // Get the field from the recordset $field = $rs->FetchField($i); // If the recordset field is one // of the fields passed in then process. $upperfname = strtoupper($field->name); if (adodb_key_exists($upperfname,$arrFields)) { // Set the counter for the number of fields that will be inserted. $fieldInsertedCount++; // Get the name of the fields to insert $fields .= $field->name . ", "; $mt = $rs->MetaType($field->type); // "mike" patch and "Ryan Bailey" //PostgreSQL uses a \'t\' or \'f\' and therefore needs to be processed as a string (\'C\') type field. if ((strncmp($zthis->databaseType,"postgres",8) === 0) && ($mt == "L")) $mt = "C"; // Based on the datatype of the field // Format the value properly for the database if ((defined(\'ADODB_FORCE_NULLS\') && is_null($arrFields[$upperfname])) || $arrFields[$upperfname] === \'null\') $values .= "null, "; else switch($mt) { case "C": case "X": case \'B\': $values .= $zthis->qstr($arrFields[$upperfname],$magicq) . ", "; break; case "D": $values .= $zthis->DBDate($arrFields[$upperfname]) . ", "; break; case "T": $values .= $zthis->DBTimeStamp($arrFields[$upperfname]) . ", "; break; default: $val = $arrFields[$upperfname]; if (!is_numeric($val)) $val = (float) $val; $values .= $val . ", "; break; }; }; }; // If there were any inserted fields then build the rest of the insert query. if ($fieldInsertedCount > 0) { // Get the table name from the existing query. preg_match("/FROM\\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName); // Strip off the comma and space on the end of both the fields // and their values. $fields = substr($fields, 0, -2); $values = substr($values, 0, -2); // Append the fields and their values to the insert query. $insertSQL = "INSERT INTO " . $tableName[1] . " ( $fields ) VALUES ( $values )"; return $insertSQL; } else { return false; }; } ?>', '~core/classes/adodb/adodb-php4.inc.php' => '', '~core/classes/adodb/adodb-time.inc.php' => ' 4 digit year conversion. The maximum is billions of years in the future, but this is a theoretical limit as the computation of that year would take too long with the current implementation of adodb_mktime(). This library replaces native functions as follows:

	
	getdate()  with  adodb_getdate()
	date()     with  adodb_date() 
	gmdate()   with  adodb_gmdate()
	mktime()   with  adodb_mktime()
	gmmktime() with  adodb_gmmktime()
The parameters are identical, except that adodb_date() accepts a subset of date()\'s field formats. Mktime() will convert from local time to GMT, and date() will convert from GMT to local time, but daylight savings is not handled currently. This library is independant of the rest of ADOdb, and can be used as standalone code. PERFORMANCE For high speed, this library uses the native date functions where possible, and only switches to PHP code when the dates fall outside the 32-bit signed integer range. GREGORIAN CORRECTION Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). Since 0.06, we handle this correctly, so: adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582) == 24 * 3600 (1 day) ============================================================================= COPYRIGHT (c) 2003 John Lim and released under BSD-style license except for code by jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year and originally found at http://www.php.net/manual/en/function.mktime.php ============================================================================= BUG REPORTS These should be posted to the ADOdb forums at http://phplens.com/lens/lensforum/topics.php?id=4 ============================================================================= FUNCTION DESCRIPTIONS FUNCTION adodb_getdate($date=false) Returns an array containing date information, as getdate(), but supports dates greater than 1901 to 2038. FUNCTION adodb_date($fmt, $timestamp = false) Convert a timestamp to a formatted local date. If $timestamp is not defined, the current timestamp is used. Unlike the function date(), it supports dates outside the 1901 to 2038 range. The format fields that adodb_date supports:
a - "am" or "pm" 
A - "AM" or "PM" 
d - day of the month, 2 digits with leading zeros; i.e. "01" to "31" 
D - day of the week, textual, 3 letters; e.g. "Fri" 
F - month, textual, long; e.g. "January" 
g - hour, 12-hour format without leading zeros; i.e. "1" to "12" 
G - hour, 24-hour format without leading zeros; i.e. "0" to "23" 
h - hour, 12-hour format; i.e. "01" to "12" 
H - hour, 24-hour format; i.e. "00" to "23" 
i - minutes; i.e. "00" to "59" 
j - day of the month without leading zeros; i.e. "1" to "31" 
l (lowercase \'L\') - day of the week, textual, long; e.g. "Friday"  
L - boolean for whether it is a leap year; i.e. "0" or "1" 
m - month; i.e. "01" to "12" 
M - month, textual, 3 letters; e.g. "Jan" 
n - month without leading zeros; i.e. "1" to "12" 
O - Difference to Greenwich time in hours; e.g. "+0200" 
Q - Quarter, as in 1, 2, 3, 4 
r - RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" 
s - seconds; i.e. "00" to "59" 
S - English ordinal suffix for the day of the month, 2 characters; 
   			i.e. "st", "nd", "rd" or "th" 
t - number of days in the given month; i.e. "28" to "31"
T - Timezone setting of this machine; e.g. "EST" or "MDT" 
U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)  
w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday) 
Y - year, 4 digits; e.g. "1999" 
y - year, 2 digits; e.g. "99" 
z - day of the year; i.e. "0" to "365" 
Z - timezone offset in seconds (i.e. "-43200" to "43200"). 
   			The offset for timezones west of UTC is always negative, 
			and for those east of UTC is always positive. 
Unsupported:
B - Swatch Internet time 
I (capital i) - "1" if Daylight Savings Time, "0" otherwise.
W - ISO-8601 week number of year, weeks starting on Monday 

FUNCTION adodb_date2($fmt, $isoDateString = false) Same as adodb_date, but 2nd parameter accepts iso date, eg. adodb_date2(\'d-M-Y H:i\',\'2003-12-25 13:01:34\'); FUNCTION adodb_gmdate($fmt, $timestamp = false) Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the current timestamp is used. Unlike the function date(), it supports dates outside the 1901 to 2038 range. FUNCTION adodb_mktime($hr, $min, $sec, $month, $day, $year) Converts a local date to a unix timestamp. Unlike the function mktime(), it supports dates outside the 1901 to 2038 range. Differs from mktime() in that all parameters are currently compulsory. FUNCTION adodb_gmmktime($hr, $min, $sec, $month, $day, $year) Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters are currently compulsory. ============================================================================= NOTES Useful url for generating test timestamps: http://www.4webhelp.net/us/timestamp.php Possible future optimizations include a. Using an algorithm similar to Plauger\'s in "The Standard C Library" (page 428, xttotm.c _Ttotm() function). Plauger\'s algorithm will not work outside 32-bit signed range, so i decided not to implement it. b. Iterate over a block of years (say 12) when searching for the correct year. c. Implement daylight savings, which looks awfully complicated, see http://webexhibits.org/daylightsaving/ CHANGELOG - 26 Oct 2003 0.11 Because of daylight savings problems (some systems apply daylight savings to January!!!), changed adodb_get_gmt_diff() to ignore daylight savings. - 9 Aug 2003 0.10 Fixed bug with dates after 2038. See http://phplens.com/lens/lensforum/msgs.php?id=6980 - 1 July 2003 0.09 Added support for Q (Quarter). Added adodb_date2(), which accepts ISO date in 2nd param - 3 March 2003 0.08 Added support for \'S\' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS if you want PHP to handle negative timestamps between 1901 to 1969. - 27 Feb 2003 0.07 All negative numbers handled by adodb now because of RH 7.3+ problems. See http://bugs.php.net/bug.php?id=20048&edit=2 - 4 Feb 2003 0.06 Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates are now correctly handled. - 29 Jan 2003 0.05 Leap year checking differs under Julian calendar (pre 1582). Also leap year code optimized by checking for most common case first. We also handle month overflow correctly in mktime (eg month set to 13). Day overflow for less than one month\'s days is supported. - 28 Jan 2003 0.04 Gregorian correction handled. In PHP5, we might throw an error if mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10. Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582. - 27 Jan 2003 0.03 Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION. Fixed calculation of days since start of year for <1970. - 27 Jan 2003 0.02 Changed _adodb_getdate() to inline leap year checking for better performance. Fixed problem with time-zones west of GMT +0000. - 24 Jan 2003 0.01 First implementation. */ /* Initialization */ /* Version Number */ define(\'ADODB_DATE_VERSION\',0.11); /* We check for Windows as only +ve ints are accepted as dates on Windows. Apparently this problem happens also with Linux, RH 7.3 and later! glibc-2.2.5-34 and greater has been changed to return -1 for dates < 1970. This used to work. The problem exists with RedHat 7.3 and 8.0 echo (mktime(0, 0, 0, 1, 1, 1960)); // prints -1 References: http://bugs.php.net/bug.php?id=20048&edit=2 http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html */ if (!defined(\'ADODB_ALLOW_NEGATIVE_TS\')) define(\'ADODB_NO_NEGATIVE_TS\',1); function adodb_date_test_date($y1,$m) { //print " $y1/$m "; $t = adodb_mktime(0,0,0,$m,13,$y1); if ("$y1-$m-13 00:00:00" != adodb_date(\'Y-n-d H:i:s\',$t)) { print "$y1 error
"; return false; } return true; } /** Test Suite */ function adodb_date_test() { error_reporting(E_ALL); print "

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

"; set_time_limit(0); $fail = false; // This flag disables calling of PHP native functions, so we can properly test the code if (!defined(\'ADODB_TEST_DATES\')) define(\'ADODB_TEST_DATES\',1); print "

Testing gregorian <=> julian conversion

"; $t = adodb_mktime(0,0,0,10,11,1492); //http://www.holidayorigins.com/html/columbus_day.html - Friday check if (!(adodb_date(\'D Y-m-d\',$t) == \'Fri 1492-10-11\')) print \'Error in Columbus landing
\'; $t = adodb_mktime(0,0,0,2,29,1500); if (!(adodb_date(\'Y-m-d\',$t) == \'1500-02-29\')) print \'Error in julian leap years
\'; $t = adodb_mktime(0,0,0,2,29,1700); if (!(adodb_date(\'Y-m-d\',$t) == \'1700-03-01\')) print \'Error in gregorian leap years
\'; print adodb_mktime(0,0,0,10,4,1582).\' \'; print adodb_mktime(0,0,0,10,15,1582); $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)); if ($diff != 3600*24) print " Error in gregorian correction = ".($diff/3600/24)." days
"; print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? \'Fri\' : \'Error\')."
"; print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? \'Thu\' : \'Error\')."
"; print "

Testing overflow

"; $t = adodb_mktime(0,0,0,3,33,1965); if (!(adodb_date(\'Y-m-d\',$t) == \'1965-04-02\')) print \'Error in day overflow 1
\'; $t = adodb_mktime(0,0,0,4,33,1971); if (!(adodb_date(\'Y-m-d\',$t) == \'1971-05-03\')) print \'Error in day overflow 2
\'; $t = adodb_mktime(0,0,0,1,60,1965); if (!(adodb_date(\'Y-m-d\',$t) == \'1965-03-01\')) print \'Error in day overflow 3 \'.adodb_date(\'Y-m-d\',$t).\'
\'; $t = adodb_mktime(0,0,0,12,32,1965); if (!(adodb_date(\'Y-m-d\',$t) == \'1966-01-01\')) print \'Error in day overflow 4 \'.adodb_date(\'Y-m-d\',$t).\'
\'; $t = adodb_mktime(0,0,0,12,63,1965); if (!(adodb_date(\'Y-m-d\',$t) == \'1966-02-01\')) print \'Error in day overflow 5 \'.adodb_date(\'Y-m-d\',$t).\'
\'; $t = adodb_mktime(0,0,0,13,3,1965); if (!(adodb_date(\'Y-m-d\',$t) == \'1966-01-03\')) print \'Error in mth overflow 1
\'; print "Testing 2-digit => 4-digit year conversion

"; if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000
"; if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010
"; if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020
"; if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030
"; if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940
"; if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950
"; if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990
"; // Test string formating print "

Testing date formating

"; $fmt = \'\\d\\a\\t\\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \\R\\F\\C822 r s t U w y Y z Z 2003\'; $s1 = date($fmt,0); $s2 = adodb_date($fmt,0); if ($s1 != $s2) { print " date() 0 failed
$s1
$s2
"; } flush(); for ($i=100; --$i > 0; ) { $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000); $s1 = date($fmt,$ts); $s2 = adodb_date($fmt,$ts); //print "$s1
$s2

"; $pos = strcmp($s1,$s2); if (($s1) != ($s2)) { for ($j=0,$k=strlen($s1); $j < $k; $j++) { if ($s1[$j] != $s2[$j]) { print substr($s1,$j).\' \'; break; } } print "Error date(): $ts

 
  \\"$s1\\" (date len=".strlen($s1).")
  \\"$s2\\" (adodb_date len=".strlen($s2).")

"; $fail = true; } $a1 = getdate($ts); $a2 = adodb_getdate($ts); $rez = array_diff($a1,$a2); if (sizeof($rez)>0) { print "Error getdate() $ts
"; print_r($a1); print "
"; print_r($a2); print "

"; $fail = true; } } // Test generation of dates outside 1901-2038 print "

Testing random dates between 100 and 4000

"; adodb_date_test_date(100,1); for ($i=100; --$i >= 0;) { $y1 = 100+rand(0,1970-100); $m = rand(1,12); adodb_date_test_date($y1,$m); $y1 = 3000-rand(0,3000-1970); adodb_date_test_date($y1,$m); } print \'

\'; $start = 1960+rand(0,10); $yrs = 12; $i = 365.25*86400*($start-1970); $offset = 36000+rand(10000,60000); $max = 365*$yrs*86400; $lastyear = 0; // we generate a timestamp, convert it to a date, and convert it back to a timestamp // and check if the roundtrip broke the original timestamp value. print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: "; for ($max += $i; $i < $max; $i += $offset) { $ret = adodb_date(\'m,d,Y,H,i,s\',$i); $arr = explode(\',\',$ret); if ($lastyear != $arr[2]) { $lastyear = $arr[2]; print " $lastyear "; flush(); } $newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]); if ($i != $newi) { print "Error at $i, adodb_mktime returned $newi ($ret)"; $fail = true; break; } } if (!$fail) print "

Passed !

"; else print "

Failed :-(

"; } /** Returns day of week, 0 = Sunday,... 6=Saturday. Algorithm from PEAR::Date_Calc */ function adodb_dow($year, $month, $day) { /* Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and proclaimed that from that time onwards 3 days would be dropped from the calendar every 400 years. Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). */ if ($year <= 1582) { if ($year < 1582 || ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3; else $greg_correction = 0; } else $greg_correction = 0; if($month > 2) $month -= 2; else { $month += 10; $year--; } $day = ( floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4) + floor(($year / 100) / 4) - 2 * floor($year / 100) + 77); return (($day - 7 * floor($day / 7))) + $greg_correction; } /** Checks for leap year, returns true if it is. No 2-digit year check. Also handles julian calendar correctly. */ function _adodb_is_leap_year($year) { if ($year % 4 != 0) return false; if ($year % 400 == 0) { return true; // if gregorian calendar (>1582), century not-divisible by 400 is not leap } else if ($year > 1582 && $year % 100 == 0 ) { return false; } return true; } /** checks for leap year, returns true if it is. Has 2-digit year check */ function adodb_is_leap_year($year) { return _adodb_is_leap_year(adodb_year_digit_check($year)); } /** Fix 2-digit years. Works for any century. Assumes that if 2-digit is more than 30 years in future, then previous century. */ function adodb_year_digit_check($y) { if ($y < 100) { $yr = (integer) date("Y"); $century = (integer) ($yr /100); if ($yr%100 > 50) { $c1 = $century + 1; $c0 = $century; } else { $c1 = $century; $c0 = $century - 1; } $c1 *= 100; // if 2-digit year is less than 30 years in future, set it to this century // otherwise if more than 30 years in future, then we set 2-digit year to the prev century. if (($y + $c1) < $yr+30) $y = $y + $c1; else $y = $y + $c0*100; } return $y; } /** get local time zone offset from GMT */ function adodb_get_gmt_diff() { static $TZ; if (isset($TZ)) return $TZ; $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0); return $TZ; } /** Returns an array with date info. */ function adodb_getdate($d=false,$fast=false) { if ($d === false) return getdate(); if (!defined(\'ADODB_TEST_DATES\')) { if ((abs($d) <= 0x7FFFFFFF)) { // check if number in 32-bit signed range if (!defined(\'ADODB_NO_NEGATIVE_TS\') || $d >= 0) // if windows, must be +ve integer return @getdate($d); } } return _adodb_getdate($d); } /** Low-level function that returns the getdate() array. We have a special $fast flag, which if set to true, will return fewer array values, and is much faster as it does not calculate dow, etc. */ function _adodb_getdate($origd=false,$fast=false,$is_gmt=false) { $d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff()); $_day_power = 86400; $_hour_power = 3600; $_min_power = 60; if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); if ($d < 0) { $origd = $d; // The valid range of a 32bit signed timestamp is typically from // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT for ($a = 1970 ; --$a >= 0;) { $lastd = $d; if ($leaf = _adodb_is_leap_year($a)) { $d += $_day_power * 366; } else $d += $_day_power * 365; if ($d >= 0) { $year = $a; break; } } $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd; $d = $lastd; $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal; for ($a = 13 ; --$a > 0;) { $lastd = $d; $d += $mtab[$a] * $_day_power; if ($d >= 0) { $month = $a; $ndays = $mtab[$a]; break; } } $d = $lastd; $day = $ndays + ceil(($d+1) / ($_day_power)); $d += ($ndays - $day+1)* $_day_power; $hour = floor($d/$_hour_power); } else { for ($a = 1970 ;; $a++) { $lastd = $d; if ($leaf = _adodb_is_leap_year($a)) { $d -= $_day_power * 366; } else $d -= $_day_power * 365; if ($d < 0) { $year = $a; break; } } $secsInYear = $lastd; $d = $lastd; $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal; for ($a = 1 ; $a <= 12; $a++) { $lastd = $d; $d -= $mtab[$a] * $_day_power; if ($d <= 0) { $month = $a; $ndays = $mtab[$a]; break; } } $d = $lastd; $day = ceil(($d+1) / $_day_power); $d = $d - ($day-1) * $_day_power; $hour = floor($d /$_hour_power); } $d -= $hour * $_hour_power; $min = floor($d/$_min_power); $secs = $d - $min * $_min_power; if ($fast) { return array( \'seconds\' => $secs, \'minutes\' => $min, \'hours\' => $hour, \'mday\' => $day, \'mon\' => $month, \'year\' => $year, \'yday\' => floor($secsInYear/$_day_power), \'leap\' => $leaf, \'ndays\' => $ndays ); } $dow = adodb_dow($year,$month,$day); return array( \'seconds\' => $secs, \'minutes\' => $min, \'hours\' => $hour, \'mday\' => $day, \'wday\' => $dow, \'mon\' => $month, \'year\' => $year, \'yday\' => floor($secsInYear/$_day_power), \'weekday\' => gmdate(\'l\',$_day_power*(3+$dow)), \'month\' => gmdate(\'F\',mktime(0,0,0,$month,2,1971)), 0 => $origd ); } function adodb_gmdate($fmt,$d=false) { return adodb_date($fmt,$d,true); } function adodb_date2($fmt, $d=false, $is_gmt=false) { if ($d !== false) { if (!preg_match( "|^([0-9]{4})[-/\\.]?([0-9]{1,2})[-/\\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\\.]{1,4}))?|", ($d), $rr)) return adodb_date($fmt,false,$is_gmt); if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt); // h-m-s-MM-DD-YY if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]); } return adodb_date($fmt,$d,$is_gmt); } /** Return formatted date based on timestamp $d */ function adodb_date($fmt,$d=false,$is_gmt=false) { if ($d === false) return 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); } } $_day_power = 86400; $arr = _adodb_getdate($d,true,$is_gmt); $year = $arr[\'year\']; $month = $arr[\'mon\']; $day = $arr[\'mday\']; $hour = $arr[\'hours\']; $min = $arr[\'minutes\']; $secs = $arr[\'seconds\']; $max = strlen($fmt); $dates = \'\'; /* at this point, we have the following integer vars to manipulate: $year, $month, $day, $hour, $min, $secs */ for ($i=0; $i < $max; $i++) { switch($fmt[$i]) { case \'T\': $dates .= date(\'T\');break; // YEAR case \'L\': $dates .= $arr[\'leap\'] ? \'1\' : \'0\'; break; case \'r\': // Thu, 21 Dec 2000 16:01:07 +0200 $dates .= gmdate(\'D\',$_day_power*(3+adodb_dow($year,$month,$day))).\', \' . ($day<10?\' \'.$day:$day) . \' \'.date(\'M\',mktime(0,0,0,$month,2,1971)).\' \'.$year.\' \'; if ($hour < 10) $dates .= \'0\'.$hour; else $dates .= $hour; if ($min < 10) $dates .= \':0\'.$min; else $dates .= \':\'.$min; if ($secs < 10) $dates .= \':0\'.$secs; else $dates .= \':\'.$secs; $gmt = adodb_get_gmt_diff(); $dates .= sprintf(\' %s%04d\',($gmt<0)?\'+\':\'-\',abs($gmt)/36); break; case \'Y\': $dates .= $year; break; case \'y\': $dates .= substr($year,strlen($year)-2,2); break; // MONTH case \'m\': if ($month<10) $dates .= \'0\'.$month; else $dates .= $month; break; case \'Q\': $dates .= ($month+3)>>2; break; case \'n\': $dates .= $month; break; case \'M\': $dates .= date(\'M\',mktime(0,0,0,$month,2,1971)); break; case \'F\': $dates .= date(\'F\',mktime(0,0,0,$month,2,1971)); break; // DAY case \'t\': $dates .= $arr[\'ndays\']; break; case \'z\': $dates .= $arr[\'yday\']; break; case \'w\': $dates .= adodb_dow($year,$month,$day); break; case \'l\': $dates .= gmdate(\'l\',$_day_power*(3+adodb_dow($year,$month,$day))); break; case \'D\': $dates .= gmdate(\'D\',$_day_power*(3+adodb_dow($year,$month,$day))); break; case \'j\': $dates .= $day; break; case \'d\': if ($day<10) $dates .= \'0\'.$day; else $dates .= $day; break; case \'S\': $d10 = $day % 10; if ($d10 == 1) $dates .= \'st\'; else if ($d10 == 2) $dates .= \'nd\'; else if ($d10 == 3) $dates .= \'rd\'; else $dates .= \'th\'; break; // HOUR case \'Z\': $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break; case \'O\': $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff(); $dates .= sprintf(\'%s%04d\',($gmt<0)?\'+\':\'-\',abs($gmt)/36); break; case \'H\': if ($hour < 10) $dates .= \'0\'.$hour; else $dates .= $hour; break; case \'h\': if ($hour > 12) $hh = $hour - 12; else { if ($hour == 0) $hh = \'12\'; else $hh = $hour; } if ($hh < 10) $dates .= \'0\'.$hh; else $dates .= $hh; break; case \'G\': $dates .= $hour; break; case \'g\': if ($hour > 12) $hh = $hour - 12; else { if ($hour == 0) $hh = \'12\'; else $hh = $hour; } $dates .= $hh; break; // MINUTES case \'i\': if ($min < 10) $dates .= \'0\'.$min; else $dates .= $min; break; // SECONDS case \'U\': $dates .= $d; break; case \'s\': if ($secs < 10) $dates .= \'0\'.$secs; else $dates .= $secs; break; // AM/PM // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM case \'a\': if ($hour>=12) $dates .= \'pm\'; else $dates .= \'am\'; break; case \'A\': if ($hour>=12) $dates .= \'PM\'; else $dates .= \'AM\'; break; default: $dates .= $fmt[$i]; break; // ESCAPE case "\\\\": $i++; if ($i < $max) $dates .= $fmt[$i]; break; } } return $dates; } /** Returns a timestamp given a GMT/UTC time. Note that $is_dst is not implemented and is ignored. */ function adodb_gmmktime($hr,$min,$sec,$mon,$day,$year,$is_dst=false) { return adodb_mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true); } /** Return a timestamp given a local time. Originally by jackbbs. Note that $is_dst is not implemented and is ignored. */ function adodb_mktime($hr,$min,$sec,$mon,$day,$year,$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) return @mktime($hr,$min,$sec,$mon,$day,$year); } $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff(); $hr = intval($hr); $min = intval($min); $sec = intval($sec); $mon = intval($mon); $day = intval($day); $year = intval($year); $year = adodb_year_digit_check($year); if ($mon > 12) { $y = floor($mon / 12); $year += $y; $mon -= $y*12; } $_day_power = 86400; $_hour_power = 3600; $_min_power = 60; $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); $_total_date = 0; if ($year >= 1970) { for ($a = 1970 ; $a <= $year; $a++) { $leaf = _adodb_is_leap_year($a); if ($leaf == true) { $loop_table = $_month_table_leaf; $_add_date = 366; } else { $loop_table = $_month_table_normal; $_add_date = 365; } if ($a < $year) { $_total_date += $_add_date; } else { for($b=1;$b<$mon;$b++) { $_total_date += $loop_table[$b]; } } } $_total_date +=$day-1; $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different; } else { for ($a = 1969 ; $a >= $year; $a--) { $leaf = _adodb_is_leap_year($a); if ($leaf == true) { $loop_table = $_month_table_leaf; $_add_date = 366; } else { $loop_table = $_month_table_normal; $_add_date = 365; } if ($a > $year) { $_total_date += $_add_date; } else { for($b=12;$b>$mon;$b--) { $_total_date += $loop_table[$b]; } } } $_total_date += $loop_table[$mon] - $day; $_day_time = $hr * $_hour_power + $min * $_min_power + $sec; $_day_time = $_day_power - $_day_time; $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different); if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582. } //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret; return $ret; } ?>', '~core/classes/adodb/adodb.inc.php' => ' Manual is at http://php.weblogs.com/adodb_manual */ if (!defined(\'_ADODB_LAYER\')) { define(\'_ADODB_LAYER\',1); //============================================================================================== // CONSTANT DEFINITIONS //============================================================================================== /** * Set ADODB_DIR to the directory where this file resides... * This constant was formerly called $ADODB_RootPath */ if (!defined(\'ADODB_DIR\')) define(\'ADODB_DIR\',dirname(__FILE__)); //============================================================================================== // GLOBAL VARIABLES //============================================================================================== GLOBAL $ADODB_vers, // database version $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_FETCH_MODE; // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default... //============================================================================================== // GLOBAL SETUP //============================================================================================== $ADODB_EXTENSION = defined(\'ADODB_EXTENSION\'); if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) { define(\'ADODB_BAD_RS\',\'

Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;

\'); // allow [ ] @ ` and . in table names define(\'ADODB_TABLE_REGEX\',\'([]0-9a-z_\\`\\.\\@\\[-]*)\'); // prefetching used by oracle if (!defined(\'ADODB_PREFETCH_ROWS\')) define(\'ADODB_PREFETCH_ROWS\',10); /* Controls ADODB_FETCH_ASSOC field-name case. Default is 2, use native case-names. This currently works only with mssql, odbc, oci8po and ibase derived drivers. 0 = assoc lowercase field names. $rs->fields[\'orderid\'] 1 = assoc uppercase field names. $rs->fields[\'ORDERID\'] 2 = use native-case field names. $rs->fields[\'OrderID\'] */ define(\'ADODB_FETCH_DEFAULT\',0); define(\'ADODB_FETCH_NUM\',1); define(\'ADODB_FETCH_ASSOC\',2); define(\'ADODB_FETCH_BOTH\',3); if (!defined(\'TIMESTAMP_FIRST_YEAR\')) define(\'TIMESTAMP_FIRST_YEAR\',100); if (strnatcmp(PHP_VERSION,\'4.3.0\')>=0) { define(\'ADODB_PHPVER\',0x4300); } else if (strnatcmp(PHP_VERSION,\'4.2.0\')>=0) { define(\'ADODB_PHPVER\',0x4200); } else if (strnatcmp(PHP_VERSION,\'4.0.5\')>=0) { define(\'ADODB_PHPVER\',0x4050); } else { define(\'ADODB_PHPVER\',0x4000); } } //if (!defined(\'ADODB_ASSOC_CASE\')) define(\'ADODB_ASSOC_CASE\',2); /** Accepts $src and $dest arrays, replacing string $data */ function ADODB_str_replace($src, $dest, $data) { if (ADODB_PHPVER >= 0x4050) return str_replace($src,$dest,$data); $s = reset($src); $d = reset($dest); while ($s !== false) { $data = str_replace($s,$d,$data); $s = next($src); $d = next($dest); } return $data; } function ADODB_Setup() { GLOBAL $ADODB_vers, // database version $ADODB_COUNTRECS, // count number of records returned - slows down query $ADODB_CACHE_DIR, // directory to cache recordsets $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT; if (!isset($ADODB_CACHE_DIR)) { $ADODB_CACHE_DIR = \'/tmp\'; } else { // do not accept url based paths, eg. http:/ or ftp:/ if (strpos($ADODB_CACHE_DIR,\'://\') !== false) die("Illegal path http:// or ftp://"); } // Initialize random number generator for randomizing cache flushes srand(((double)microtime())*1000000); /** * ADODB version as a string. */ $ADODB_vers = \'V4.05 13 Dec 2003 (c) 2000-2003 John Lim (jlim#natsoft.com.my). All rights reserved. Released BSD & LGPL.\'; /** * Determines whether recordset->RecordCount() is used. * Set to false for highest performance -- RecordCount() will always return -1 then * for databases that provide "virtual" recordcounts... */ if (!isset($ADODB_COUNTRECS)) $ADODB_COUNTRECS = true; } //============================================================================================== // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB //============================================================================================== ADODB_Setup(); //============================================================================================== // CLASS ADOFieldObject //============================================================================================== /** * Helper class for FetchFields -- holds info on a column */ class ADOFieldObject { var $name = \'\'; var $max_length=0; var $type=""; // additional fields by dannym... (danny_milo@yahoo.com) var $not_null = false; // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^ // so we can as well make not_null standard (leaving it at "false" does not harm anyways) var $has_default = false; // this one I have done only in mysql and postgres for now ... // others to come (dannym) var $default_value; // default, if any, and supported. Check has_default first. } function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) { //print "Errorno ($fn errno=$errno m=$errmsg) "; $thisConnection->_transOK = false; if ($thisConnection->_oldRaiseFn) { $fn = $thisConnection->_oldRaiseFn; $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection); } } //============================================================================================== // CLASS ADOConnection //============================================================================================== /** * Connection object. For connecting to databases, and executing queries. */ class ADOConnection { /************************************************************************************************************/ var $IsConnected = false; function QConnect() { $this->IsConnected = true; $this->connect( $GLOBALS[\'Conf\']->DB->Host, $GLOBALS[\'Conf\']->DB->User, $GLOBALS[\'Conf\']->DB->Password, $GLOBALS[\'Conf\']->DB->DataBase, $GLOBALS[\'Conf\']->DB->UseForse); } function QExecute($sql,$inputarr=false) { if (!$this->IsConnected) $this->QConnect(); $GLOBALS[\'sql_count\'] ++; return $this->Execute($sql,$inputarr); } function QSelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) { if (!$this->IsConnected) $this->QConnect(); $GLOBALS[\'sql_count\'] ++; return $this->SelectLimit($sql,$nrows,$offset, $inputarr,$secs2cache); } function Insert( $table, $values) { $sql = \'INSERT into \'.$table.\' (\'; $sql .= implode(",", array_keys($values)); $sql .= ") VALUES (\'"; $sql .= implode("\',\'", array_values($values)); $sql .= "\')"; return $this->QExecute($sql); } function Update( $table, $id, $values) { $sql = \'UPDATE \'.$table.\' SET \'; foreach($values as $filed => $value) { $sql .= \' \'.$filed.\' = \\\'\'.$value.\'\\\', \'; } $sql = substr($sql, 0, -2); $sql .= " WHERE id = ".$id; return $this->QExecute($sql); } function Delete( $table, $id ) { $sql = \'DELETE FROM \'.$table.\' WHERE id = \'.$id; return $this->QExecute($sql); } function QGetOne($sql,$inputarr=false) { $GLOBALS[\'sql_count\'] ++; return $this->GetOne($sql,$inputarr); } /************************************************************************************************************/ // // PUBLIC VARS // var $dataProvider = \'native\'; var $databaseType = \'\'; /// RDBMS currently in use, eg. odbc, mysql, mssql var $database = \'\'; /// Name of database to be used. var $host = \'\'; /// The hostname of the database server var $user = \'\'; /// The username which is used to connect to the database server. var $password = \'\'; /// Password for the username. For security, we no longer store it. var $debug = false; /// if set to true will output sql statements var $maxblobsize = 256000; /// maximum size of blobs or large text fields -- some databases die otherwise like foxpro var $concat_operator = \'+\'; /// default concat operator -- change to || for Oracle/Interbase var $substr = \'substr\'; /// substring operator var $length = \'length\'; /// string length operator var $random = \'rand()\'; /// random function var $upperCase = false; /// 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 var $false = \'0\'; /// string that represents FALSE for a database var $replaceQuote = "\\\\\'"; /// string to use to replace quotes var $charSet=false; /// character set to use - only for interbase var $metaDatabasesSQL = \'\'; var $metaTablesSQL = \'\'; var $uniqueOrderBy = false; /// All order by columns have to be unique var $emptyDate = \' \'; var $emptyTimeStamp = \' \'; var $lastInsID = false; //-- var $hasInsertID = false; /// supports autoincrement ID? var $hasAffectedRows = false; /// supports affected rows for update/delete? var $hasTop = false; /// support mssql/access SELECT TOP 10 * FROM TABLE var $hasLimit = false; /// support pgsql/mysql SELECT * FROM TABLE LIMIT 10 var $readOnly = false; /// this is a readonly database - used by phpLens var $hasMoveFirst = false; /// has ability to run MoveFirst(), scrolling backwards var $hasGenID = false; /// can generate sequences using GenID(); var $hasTransactions = true; /// has transactions //-- var $genID = 0; /// sequence id used by GenID(); var $raiseErrorFn = false; /// error function to call var $isoDates = false; /// accepts dates in ISO format var $cacheSecs = 3600; /// cache for 1 hour var $sysDate = false; /// name of function that returns the current date var $sysTimeStamp = false; /// name of function that returns the current timestamp var $arrayClass = \'ADORecordSet_array\'; /// name of class used to generate array recordsets, which are pre-downloaded recordsets var $noNullStrings = false; /// oracle specific stuff - if true ensures that \'\' is converted to \' \' var $numCacheHits = 0; var $numCacheMisses = 0; var $pageExecuteCountRows = true; var $uniqueSort = false; /// indicates that all fields in order by must be unique var $leftOuter = false; /// operator to use for left outer join in WHERE clause var $rightOuter = false; /// operator to use for right outer join in WHERE clause var $ansiOuter = false; /// whether ansi outer join syntax supported var $autoRollback = false; // autoRollback on PConnect(). var $poorAffectedRows = false; // affectedRows not working or unreliable var $fnExecute = false; var $fnCacheExecute = false; var $blobEncodeType = false; // false=not required, \'I\'=encode to integer, \'C\'=encode to char var $rsPrefix = "ADORecordSet_"; var $autoCommit = true; /// do not modify this yourself - actually private var $transOff = 0; /// temporarily disable transactions var $transCnt = 0; /// count of nested transactions var $fetchMode=false; // // PRIVATE VARS // var $_oldRaiseFn = false; var $_transOK = null; var $_connectionID = false; /// The returned link identifier whenever a successful database connection is made. var $_errorMsg = false; /// A variable which was used to keep the returned last error message. The value will /// then returned by the errorMsg() function var $_errorCode = false; /// Last error code, not guaranteed to be used - only by oci8 var $_queryID = false; /// This variable keeps the last created result link identifier var $_isPersistentConnection = false; /// A boolean variable to state whether its a persistent connection or normal connection. */ var $_bindInputArray = false; /// set to true if ADOConnection.Execute() permits binding of array parameters. var $_evalAll = false; var $_affected = false; var $_logsql = false; /** * Constructor */ function ADOConnection() { die(\'Virtual Class -- cannot instantiate\'); } /** Get server version info... @returns An array with 2 elements: $arr[\'string\'] is the description string, and $arr[version] is the version (also a string). */ function ServerInfo() { return array(\'description\' => \'\', \'version\' => \'\'); } function _findvers($str) { if (preg_match(\'/([0-9]+\\.([0-9\\.])+)/\',$str, $arr)) return $arr[1]; else return \'\'; } /** * All error messages go through this bottleneck function. * You can define your own handler by defining the function name in ADODB_OUTP. */ function outp($msg,$newline=true) { global $HTTP_SERVER_VARS,$ADODB_FLUSH; if (defined(\'ADODB_OUTP\')) { $fn = ADODB_OUTP; $fn($msg,$newline); return; } if ($newline) $msg .= "
\\n"; 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 } /** * Connect to database * * @param [argHostname] Host to connect to * @param [argUsername] Userid to login * @param [argPassword] Associated password * @param [argDatabaseName] database * @param [forceNew] force new connection * * @return true or false */ function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false) { if ($argHostname != "") $this->host = $argHostname; if ($argUsername != "") $this->user = $argUsername; if ($argPassword != "") $this->password = $argPassword; // not stored for security reasons 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); } 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->debug) ADOConnection::outp( $this->host.\': \'.$this->ErrorMsg()); return false; } function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) { return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName); } /** * Always force a new connection to database - currently only works with oracle * * @param [argHostname] Host to connect to * @param [argUsername] Userid to login * @param [argPassword] Associated password * @param [argDatabaseName] database * * @return true or false */ function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") { return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true); } /** * Establish persistent connect to database * * @param [argHostname] Host to connect to * @param [argUsername] Userid to login * @param [argPassword] Associated password * @param [argDatabaseName] database * * @return return true or false */ function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") { if (defined(\'ADODB_NEVER_PERSIST\')) return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName); if ($argHostname != "") $this->host = $argHostname; if ($argUsername != "") $this->user = $argUsername; if ($argPassword != "") $this->password = $argPassword; if ($argDatabaseName != "") $this->database = $argDatabaseName; $this->_isPersistentConnection = true; 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()); return false; } // Format date column in sql string given an input format that understands Y M D function SQLDate($fmt, $col=false) { if (!$col) $col = $this->sysDate; return $col; // child class implement } /** * Should prepare the sql statement and return the stmt resource. * For databases that do not support this, we return the $sql. To ensure * compatibility with databases that do not support prepare: * * $stmt = $db->Prepare("insert into table (id, name) values (?,?)"); * $db->Execute($stmt,array(1,\'Jill\')) or die(\'insert failed\'); * $db->Execute($stmt,array(2,\'Joe\')) or die(\'insert failed\'); * * @param sql SQL to send to database * * @return return FALSE, or the prepared statement, or the original sql if * if the database does not support prepare. * */ function Prepare($sql) { return $sql; } /** * Some databases, eg. mssql require a different function for preparing * stored procedures. So we cannot use Prepare(). * * Should prepare the stored procedure and return the stmt resource. * For databases that do not support this, we return the $sql. To ensure * compatibility with databases that do not support prepare: * * @param sql SQL to send to database * * @return return FALSE, or the prepared statement, or the original sql if * if the database does not support prepare. * */ function PrepareSP($sql) { return $this->Prepare($sql); } /** * PEAR DB Compat */ function Quote($s) { return $this->qstr($s,false); } /** Requested by "Karsten Dambekalns" */ function QMagic($s) { return $this->qstr($s,get_magic_quotes_gpc()); } function q(&$s) { $s = $this->qstr($s,false); } /** * PEAR DB Compat - do not use internally. */ function ErrorNative() { return $this->ErrorNo(); } /** * PEAR DB Compat - do not use internally. */ function nextId($seq_name) { return $this->GenID($seq_name); } /** * Lock a row, will escalate and lock the table if row locking not supported * will normally free the lock at the end of the transaction * * @param $table name of table to lock * @param $where where clause to use, eg: "WHERE row=12". If left empty, will escalate to table lock */ function RowLock($table,$where) { return false; } function CommitLock($table) { return $this->CommitTrans(); } function RollbackLock($table) { return $this->RollbackTrans(); } /** * PEAR DB Compat - do not use internally. * * The fetch modes for NUMERIC and ASSOC for PEAR DB and ADODB are identical * for easy porting :-) * * @param mode The fetchmode ADODB_FETCH_ASSOC or ADODB_FETCH_NUM * @returns The previous fetch mode */ function SetFetchMode($mode) { $old = $this->fetchMode; $this->fetchMode = $mode; if ($old === false) { global $ADODB_FETCH_MODE; return $ADODB_FETCH_MODE; } return $old; } /** * PEAR DB Compat - do not use internally. */ function &Query($sql, $inputarr=false) { $rs = &$this->Execute($sql, $inputarr); if (!$rs && defined(\'ADODB_PEAR\')) return ADODB_PEAR_Error(); return $rs; } /** * PEAR DB Compat - do not use internally */ function &LimitQuery($sql, $offset, $count, $params=false) { $rs = &$this->SelectLimit($sql, $count, $offset, $params); if (!$rs && defined(\'ADODB_PEAR\')) return ADODB_PEAR_Error(); return $rs; } /** * PEAR DB Compat - do not use internally */ function Disconnect() { return $this->Close(); } /* returns placeholder for parameter, eg. $DB->Param(\'a\') will return \':a\' for Oracle, and \'?\' for most other databases... */ function Param($name) { return \'?\'; } /* Usage in oracle $stmt = $db->Prepare(\'select * from table where id =:myid and group=:group\'); $db->Parameter($stmt,$id,\'myid\'); $db->Parameter($stmt,$group,\'group\',64); $db->Execute(); @param $stmt Statement returned by Prepare() or PrepareSP(). @param $var PHP variable to bind to @param $name Name of stored procedure variable name to bind to. @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8. @param [$maxLen] Holds an maximum length of the variable. @param [$type] The data type of $var. Legal values depend on driver. */ function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) { return false; } /** Improved method of initiating a transaction. Used together with CompleteTrans(). Advantages include: a. StartTrans/CompleteTrans is nestable, unlike BeginTrans/CommitTrans/RollbackTrans. Only the outermost block is treated as a transaction.
b. CompleteTrans auto-detects SQL errors, and will rollback on errors, commit otherwise.
c. All BeginTrans/CommitTrans/RollbackTrans inside a StartTrans/CompleteTrans block are disabled, making it backward compatible. */ function StartTrans($errfn = \'ADODB_TransMonitor\') { if ($this->transOff > 0) { $this->transOff += 1; return; } $this->_oldRaiseFn = $this->raiseErrorFn; $this->raiseErrorFn = $errfn; $this->_transOK = true; if ($this->debug && $this->transCnt > 0) ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans"); $this->BeginTrans(); $this->transOff = 1; } /** Used together with StartTrans() to end a transaction. Monitors connection for sql errors, and will commit or rollback as appropriate. @autoComplete if true, monitor sql errors and commit and rollback as appropriate, and if set to false force rollback even if no SQL error detected. @returns true on commit, false on rollback. */ function CompleteTrans($autoComplete = true) { if ($this->transOff > 1) { $this->transOff -= 1; return true; } $this->raiseErrorFn = $this->_oldRaiseFn; $this->transOff = 0; if ($this->_transOK && $autoComplete) { $this->CommitTrans(); if ($this->debug) ADOConnection::outp("Smart Commit occurred"); } else { $this->RollbackTrans(); if ($this->debug) ADOCOnnection::outp("Smart Rollback occurred"); } return $this->_transOK; } /* At the end of a StartTrans/CompleteTrans block, perform a rollback. */ function FailTrans() { if ($this->debug) if ($this->transOff == 0) { ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans"); } else { ADOConnection::outp("FailTrans was called"); adodb_backtrace(); } $this->_transOK = false; } /** Check if transaction has failed, only for Smart Transactions. */ function HasFailedTrans() { if ($this->transOff > 0) return $this->_transOK == false; return false; } /** * Execute SQL * * @param sql SQL statement to execute, or possibly an array holding prepared statement ($sql[0] will hold sql text) * @param [inputarr] holds the input data to bind to. Null elements will be set to null. * @return RecordSet or false */ function &Execute($sql,$inputarr=false) { if ($this->fnExecute) { $fn = $this->fnExecute; $ret =& $fn($this,$sql,$inputarr); if (isset($ret)) return $ret; } if ($inputarr && is_array($inputarr)) { $element0 = reset($inputarr); # is_object check is because oci8 descriptors can be passed in $array_2d = is_array($element0) && !is_object(reset($element0)); if (!is_array($sql) && !$this->_bindInputArray) { $sqlarr = explode(\'?\',$sql); if (!$array_2d) $inputarr = array($inputarr); foreach($inputarr as $arr) { $sql = \'\'; $i = 0; foreach($arr as $v) { $sql .= $sqlarr[$i]; // from Ron Baldwin // Only quote string types if (gettype($v) == \'string\') $sql .= $this->qstr($v); else if ($v === null) $sql .= \'NULL\'; else $sql .= $v; $i += 1; } $sql .= $sqlarr[$i]; if ($i+1 != sizeof($sqlarr)) ADOConnection::outp( "Input Array does not match ?: ".htmlspecialchars($sql)); $ret =& $this->_Execute($sql,false); if (!$ret) return $ret; } } else { if ($array_2d) { $stmt = $this->Prepare($sql); foreach($inputarr as $arr) { $ret =& $this->_Execute($stmt,$arr); if (!$ret) return $ret; } } else $ret =& $this->_Execute($sql,$inputarr); } } else { $ret =& $this->_Execute($sql,false); } return $ret; } function& _Execute($sql,$inputarr=false) { // debug version of query if ($this->debug) { global $HTTP_SERVER_VARS; $ss = \'\'; if ($inputarr) { foreach($inputarr as $kk=>$vv) { if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).\'...\'; $ss .= "($kk=>\'$vv\') "; } $ss = "[ $ss ]"; } $sqlTxt = str_replace(\',\',\', \',is_array($sql) ?$sql[0] : $sql); // check if running from browser or command-line $inBrowser = isset($HTTP_SERVER_VARS[\'HTTP_USER_AGENT\']); if ($inBrowser) if ($this->debug === -1) ADOConnection::outp( "
\\n($this->databaseType): ".htmlspecialchars($sqlTxt)."   $ss\\n
\\n",false); else ADOConnection::outp( "
\\n($this->databaseType): ".htmlspecialchars($sqlTxt)."   $ss\\n
\\n",false); else ADOConnection::outp( "=----\\n($this->databaseType): ".($sqlTxt)." \\n-----\\n",false); $this->_queryID = $this->_query($sql,$inputarr); /* Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql because ErrorNo() calls Execute(\'SELECT @ERROR\'), causing recure */ if ($this->databaseType == \'mssql\') { // ErrorNo is a slow function call in mssql, and not reliable // in PHP 4.0.6 if($emsg = $this->ErrorMsg()) { $err = $this->ErrorNo(); if ($err) { ADOConnection::outp($err.\': \'.$emsg); } } } else if (!$this->_queryID) { $e = $this->ErrorNo(); $m = $this->ErrorMsg(); ADOConnection::outp($e .\': \'. $m ); } } else { // non-debug version of query $this->_queryID =@$this->_query($sql,$inputarr); } /************************ OK, query executed *************************/ // error handling if query fails if ($this->_queryID === false) { if ($this->debug == 99) adodb_backtrace(true,5); $fn = $this->raiseErrorFn; if ($fn) { $fn($this->databaseType,\'EXECUTE\',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this); } return false; } else if ($this->_queryID === true) { // return simplified empty recordset for inserts/updates/deletes with lower overhead $rs =& new ADORecordSet_empty(); return $rs; } // return real recordset from select statement $rsclass = $this->rsPrefix.$this->databaseType; $rs =& new $rsclass($this->_queryID,$this->fetchMode); // &new not supported by older PHP versions $rs->connection = &$this; // Pablo suggestion $rs->Init(); if (is_array($sql)) $rs->sql = $sql[0]; 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)); $rs->_queryID = $this->_queryID; } else $rs->_numOfRows = 0; } } return $rs; } function CreateSequence($seqname=\'adodbseq\',$startID=1) { if (empty($this->_genSeqSQL)) return false; return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); } function DropSequence($seqname) { if (empty($this->_dropSeqSQL)) return false; return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); } /** * Generates a sequence id and stores it in $this->genID; * GenID is only available if $this->hasGenID = true; * * @param seqname name of sequence to use * @param startID if sequence does not exist, start at this ID * @return 0 if not supported, otherwise a sequence id */ function GenID($seqname=\'adodbseq\',$startID=1) { if (!$this->hasGenID) { return 0; // formerly returns false pre 1.60 } $getnext = sprintf($this->_genIDSQL,$seqname); $holdtransOK = $this->_transOK; $rs = @$this->Execute($getnext); if (!$rs) { if ($holdtransOK) $this->_transOK = true; //if the status was ok before reset $createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID)); $rs = $this->Execute($getnext); } if ($rs && !$rs->EOF) $this->genID = reset($rs->fields); else $this->genID = 0; // false if ($rs) $rs->Close(); return $this->genID; } /** * @return the last inserted ID. Not all databases support this. */ function Insert_ID() { if ($this->_logsql && $this->lastInsID) return $this->lastInsID; if ($this->hasInsertID) return $this->_insertid(); if ($this->debug) { ADOConnection::outp( \'

Insert_ID error

\'); adodb_backtrace(); } return false; } /** * Portable Insert ID. Pablo Roca * * @return the last inserted ID. All databases support this. But aware possible * problems in multiuser environments. Heavy test this before deploying. */ function PO_Insert_ID($table="", $id="") { if ($this->hasInsertID){ return $this->Insert_ID(); } else { return $this->GetOne("SELECT MAX($id) FROM $table"); } } /** * @return # rows affected by UPDATE/DELETE */ function Affected_Rows() { if ($this->hasAffectedRows) { if ($this->fnExecute === \'adodb_log_sql\') { if ($this->_logsql && $this->_affected !== false) return $this->_affected; } $val = $this->_affectedrows(); return ($val < 0) ? false : $val; } if ($this->debug) ADOConnection::outp( \'

Affected_Rows error

\',false); return false; } /** * @return the last error message */ function ErrorMsg() { return \'!! \'.strtoupper($this->dataProvider.\' \'.$this->databaseType).\': \'.$this->_errorMsg; } /** * @return the last error number. Normally 0 means no error. */ function ErrorNo() { return ($this->_errorMsg) ? -1 : 0; } function MetaError($err=false) { include_once(ADODB_DIR."/adodb-error.inc.php"); if ($err === false) $err = $this->ErrorNo(); return adodb_error($this->dataProvider,$this->databaseType,$err); } function MetaErrorMsg($errno) { include_once(ADODB_DIR."/adodb-error.inc.php"); return adodb_errormsg($errno); } /** * @returns an array with the primary key columns in it. */ function MetaPrimaryKeys($table, $owner=false) { // owner not used in base class - see oci8 $p = array(); $objs =& $this->MetaColumns($table); if ($objs) { foreach($objs as $v) { if (!empty($v->primary_key)) $p[] = $v->name; } } if (sizeof($p)) return $p; return false; } /** * @returns assoc array where keys are tables, and values are foreign keys */ function MetaForeignKeys($table, $owner=false, $upper=false) { return false; } /** * Choose a database to connect to. Many databases do not support this. * * @param dbName is the name of the database to select * @return true or false */ function SelectDB($dbName) {return false;} /** * Will select, getting rows from $offset (1-based), for $nrows. * This simulates the MySQL "select * from table limit $offset,$nrows" , and * the PostgreSQL "select * from table limit $nrows offset $offset". Note that * MySQL and PostgreSQL parameter ordering is the opposite of the other. * eg. * SelectLimit(\'select * from table\',3); will return rows 1 to 3 (1-based) * SelectLimit(\'select * from table\',3,2); will return rows 3 to 5 (1-based) * * Uses SELECT TOP for Microsoft databases (when $this->hasTop is set) * BUG: Currently SelectLimit fails with $sql with LIMIT or TOP clause already set * * @param sql * @param [offset] is the row to start calculations from (1-based) * @param [nrows] is the number of rows to get * @param [inputarr] array of bind variables * @param [secs2cache] is a private parameter only used by jlim * @return the recordset ($rs->databaseType == \'array\') */ function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) { if ($this->hasTop && $nrows > 0) { // suggested by Reinhard Balling. Access requires top after distinct // Informix requires first before distinct - F Riosa $ismssql = (strpos($this->databaseType,\'mssql\') !== false); if ($ismssql) $isaccess = false; else $isaccess = (strpos($this->databaseType,\'access\') !== false); if ($offset <= 0) { // access includes ties in result if ($isaccess) { $sql = preg_replace( \'/(^\\s*select\\s+(distinctrow|distinct)?)/i\',\'\\\\1 \'.$this->hasTop.\' \'.$nrows.\' \',$sql); if ($secs2cache>0) { $ret =& $this->CacheExecute($secs2cache, $sql,$inputarr); } else { $ret =& $this->Execute($sql,$inputarr); } return $ret; // PHP5 fix } else if ($ismssql){ $sql = preg_replace( \'/(^\\s*select\\s+(distinctrow|distinct)?)/i\',\'\\\\1 \'.$this->hasTop.\' \'.$nrows.\' \',$sql); } else { $sql = preg_replace( \'/(^\\s*select\\s)/i\',\'\\\\1 \'.$this->hasTop.\' \'.$nrows.\' \',$sql); } } else { $nn = $nrows + $offset; if ($isaccess || $ismssql) { $sql = preg_replace( \'/(^\\s*select\\s+(distinctrow|distinct)?)/i\',\'\\\\1 \'.$this->hasTop.\' \'.$nn.\' \',$sql); } else { $sql = preg_replace( \'/(^\\s*select\\s)/i\',\'\\\\1 \'.$this->hasTop.\' \'.$nn.\' \',$sql); } } } // if $offset>0, we want to skip rows, and $ADODB_COUNTRECS is set, we buffer rows // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS. global $ADODB_COUNTRECS; $savec = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; if ($offset>0){ if ($secs2cache>0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); else $rs = &$this->Execute($sql,$inputarr); } else { if ($secs2cache>0) $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); else $rs = &$this->Execute($sql,$inputarr); } $ADODB_COUNTRECS = $savec; if ($rs && !$rs->EOF) { $rs =& $this->_rs2rs($rs,$nrows,$offset); } //print_r($rs); return $rs; } /** * Convert database recordset to an array recordset * input recordset\'s cursor should be at beginning, and * old $rs will be closed. * * @param rs the recordset to copy * @param [nrows] number of rows to retrieve (optional) * @param [offset] offset by number of rows (optional) * @return the new recordset */ function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true) { if (! $rs) return false; $dbtype = $rs->databaseType; if (!$dbtype) { $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ? return $rs; } if (($dbtype == \'array\' || $dbtype == \'csv\') && $nrows == -1 && $offset == -1) { $rs->MoveFirst(); $rs = &$rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ? return $rs; } $flds = array(); 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(); $arrayClass = $this->arrayClass; $rs2 =& new $arrayClass(); $rs2->connection = &$this; $rs2->sql = $rs->sql; $rs2->dataProvider = $this->dataProvider; $rs2->InitArrayFields($arr,$flds); return $rs2; } /* * Return all rows. Compat with PEAR DB */ function &GetAll($sql, $inputarr=false) { $arr =& $this->GetArray($sql,$inputarr); return $arr; } function &GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) { $rs =& $this->Execute($sql, $inputarr); if (!$rs) return false; $arr =& $rs->GetAssoc($force_array,$first2cols); return $arr; } function &CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) { if (!is_numeric($secs2cache)) { $first2cols = $force_array; $force_array = $inputarr; } $rs =& $this->CacheExecute($secs2cache, $sql, $inputarr); if (!$rs) return false; $arr =& $rs->GetAssoc($force_array,$first2cols); return $arr; } /** * Return first element of first row of sql statement. Recordset is disposed * for you. * * @param sql SQL statement * @param [inputarr] input bind array */ function GetOne($sql,$inputarr=false) { global $ADODB_COUNTRECS; $crecs = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; $ret = false; $rs = &$this->Execute($sql,$inputarr); if ($rs) { if (!$rs->EOF) $ret = reset($rs->fields); $rs->Close(); } $ADODB_COUNTRECS = $crecs; return $ret; } function CacheGetOne($secs2cache,$sql=false,$inputarr=false) { $ret = false; $rs = &$this->CacheExecute($secs2cache,$sql,$inputarr); if ($rs) { if (!$rs->EOF) $ret = reset($rs->fields); $rs->Close(); } return $ret; } function GetCol($sql, $inputarr = false, $trim = false) { $rv = false; $rs = &$this->Execute($sql, $inputarr); if ($rs) { $rv = array(); if ($trim) { while (!$rs->EOF) { $rv[] = trim(reset($rs->fields)); $rs->MoveNext(); } } else { while (!$rs->EOF) { $rv[] = reset($rs->fields); $rs->MoveNext(); } } $rs->Close(); } return $rv; } function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false) { $rv = false; $rs = &$this->CacheExecute($secs, $sql, $inputarr); if ($rs) { if ($trim) { while (!$rs->EOF) { $rv[] = trim(reset($rs->fields)); $rs->MoveNext(); } } else { while (!$rs->EOF) { $rv[] = reset($rs->fields); $rs->MoveNext(); } } $rs->Close(); } return $rv; } /* Calculate the offset of a date for a particular database and generate appropriate SQL. Useful for calculating future/past dates and storing in a database. If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour. */ function OffsetDate($dayFraction,$date=false) { if (!$date) $date = $this->sysDate; return \'(\'.$date.\'+\'.$dayFraction.\')\'; } /** * * @param sql SQL statement * @param [inputarr] input bind array */ function &GetArray($sql,$inputarr=false) { global $ADODB_COUNTRECS; $savec = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; $rs =& $this->Execute($sql,$inputarr); $ADODB_COUNTRECS = $savec; if (!$rs) if (defined(\'ADODB_PEAR\')) return ADODB_PEAR_Error(); else return false; $arr =& $rs->GetArray(); $rs->Close(); return $arr; } function &CacheGetAll($secs2cache,$sql=false,$inputarr=false) { global $ADODB_COUNTRECS; $savec = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); $ADODB_COUNTRECS = $savec; if (!$rs) if (defined(\'ADODB_PEAR\')) return ADODB_PEAR_Error(); else return false; $arr =& $rs->GetArray(); $rs->Close(); return $arr; } /** * Return one row of sql statement. Recordset is disposed for you. * * @param sql SQL statement * @param [inputarr] input bind array */ function &GetRow($sql,$inputarr=false) { global $ADODB_COUNTRECS; $crecs = $ADODB_COUNTRECS; $ADODB_COUNTRECS = false; $rs =& $this->Execute($sql,$inputarr); $ADODB_COUNTRECS = $crecs; if ($rs) { if (!$rs->EOF) $arr = $rs->fields; else $arr = array(); $rs->Close(); return $arr; } return false; } function &CacheGetRow($secs2cache,$sql=false,$inputarr=false) { $rs =& $this->CacheExecute($secs2cache,$sql,$inputarr); if ($rs) { $arr = false; if (!$rs->EOF) $arr = $rs->fields; $rs->Close(); return $arr; } return false; } /** * Insert or replace a single record. Note: this is not the same as MySQL\'s replace. * ADOdb\'s Replace() uses update-insert semantics, not insert-delete-duplicates of MySQL. * Also note that no table locking is done currently, so it is possible that the * record be inserted twice by two programs... * * $this->Replace(\'products\', array(\'prodname\' =>"\'Nails\'","price" => 3.99), \'prodname\'); * * $table table name * $fieldArray associative array of data (you must quote strings yourself). * $keyCol the primary key field name or if compound key, array of field names * autoQuote set to true to use a hueristic to quote strings. Works with nulls and numbers * but does not work with dates nor SQL functions. * has_autoinc the primary key is an auto-inc field, so skip in insert. * * Currently blob replace not supported * * returns 0 = fail, 1 = update, 2 = insert */ function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false) { global $ADODB_INCLUDED_LIB; if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.\'/adodb-lib.inc.php\'); return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc); } /** * Will select, getting rows from $offset (1-based), for $nrows. * This simulates the MySQL "select * from table limit $offset,$nrows" , and * the PostgreSQL "select * from table limit $nrows offset $offset". Note that * MySQL and PostgreSQL parameter ordering is the opposite of the other. * eg. * CacheSelectLimit(15,\'select * from table\',3); will return rows 1 to 3 (1-based) * CacheSelectLimit(15,\'select * from table\',3,2); will return rows 3 to 5 (1-based) * * BUG: Currently CacheSelectLimit fails with $sql with LIMIT or TOP clause already set * * @param [secs2cache] seconds to cache data, set to 0 to force query. This is optional * @param sql * @param [offset] is the row to start calculations from (1-based) * @param [nrows] is the number of rows to get * @param [inputarr] array of bind variables * @return the recordset ($rs->databaseType == \'array\') */ function &CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) { if (!is_numeric($secs2cache)) { if ($sql === false) $sql = -1; if ($offset == -1) $offset = false; // sql, nrows, offset,inputarr $rs =& $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$inputarr,$this->cacheSecs); } else { if ($sql === false) ADOConnection::outp( "Warning: \\$sql missing from CacheSelectLimit()"); $rs =& $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); } return $rs; } /** * Flush cached recordsets that match a particular $sql statement. * If $sql == false, then we purge all files in the cache. */ function CacheFlush($sql=false,$inputarr=false) { global $ADODB_CACHE_DIR; if (strlen($ADODB_CACHE_DIR) > 1 && !$sql) { if (strncmp(PHP_OS,\'WIN\',3) === 0) { $cmd = \'del /s \'.str_replace(\'/\',\'\\\\\',$ADODB_CACHE_DIR).\'\\adodb_*.cache\'; } else { $cmd = \'rm -rf \'.$ADODB_CACHE_DIR.\'/??/adodb_*.cache\'; // old version \'rm -f `find \'.$ADODB_CACHE_DIR.\' -name adodb_*.cache`\'; } if ($this->debug) { ADOConnection::outp( "CacheFlush: $cmd
\\n", system($cmd),"
"); } else { exec($cmd); } return; } $f = $this->_gencachename($sql.serialize($inputarr),false); adodb_write_file($f,\'\'); // is adodb_write_file needed? if (!@unlink($f)) { if ($this->debug) ADOConnection::outp( "CacheFlush: failed for $f"); } } /** * Private function to generate filename for caching. * Filename is generated based on: * * - sql statement * - database type (oci8, ibase, ifx, etc) * - database name * - userid * * 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; $m = md5($sql.$this->databaseType.$this->database.$this->user); $dir = $ADODB_CACHE_DIR.\'/\'.substr($m,0,2); if ($createdir && !file_exists($dir)) { $oldu = umask(0); if (!mkdir($dir,0771)) if ($this->debug) ADOConnection::outp( "Unable to mkdir $dir for $sql"); umask($oldu); } return $dir.\'/adodb_\'.$m.\'.cache\'; } /** * Execute SQL, caching recordsets. * * @param [secs2cache] seconds to cache data, set to 0 to force query. * This is an optional parameter. * @param sql SQL statement to execute * @param [inputarr] holds the input data to bind to * @return RecordSet or false */ function &CacheExecute($secs2cache,$sql=false,$inputarr=false) { if (!is_numeric($secs2cache)) { $inputarr = $sql; $sql = $secs2cache; $secs2cache = $this->cacheSecs; } global $ADODB_INCLUDED_CSV; if (empty($ADODB_INCLUDED_CSV)) include_once(ADODB_DIR.\'/adodb-csvlib.inc.php\'); if (is_array($sql)) $sql = $sql[0]; $md5file = $this->_gencachename($sql.serialize($inputarr),true); $err = \'\'; if ($secs2cache > 0){ $rs = &csv2rs($md5file,$err,$secs2cache); $this->numCacheHits += 1; } else { $err=\'Timeout 1\'; $rs = false; $this->numCacheMisses += 1; } if (!$rs) { // no cached rs found if ($this->debug) { if (get_magic_quotes_runtime()) { ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :("); } if ($this->debug !== -1) ADOConnection::outp( " $md5file cache failure: $err (see sql below)"); } $rs = &$this->Execute($sql,$inputarr); if ($rs) { $eof = $rs->EOF; $rs = &$this->_rs2rs($rs); // read entire recordset into memory immediately $txt = _rs2serialize($rs,false,$sql); // serialize if (!adodb_write_file($md5file,$txt,$this->debug)) { if ($fn = $this->raiseErrorFn) { $fn($this->databaseType,\'CacheExecute\',-32000,"Cache write error",$md5file,$sql,$this); } if ($this->debug) ADOConnection::outp( " Cache write error"); } if ($rs->EOF && !$eof) { $rs->MoveFirst(); //$rs = &csv2rs($md5file,$err); $rs->connection = &$this; // Pablo suggestion } } else @unlink($md5file); } else { $this->_errorMsg = \'\'; $this->_errorCode = 0; if ($this->fnCacheExecute) { $fn = $this->fnCacheExecute; $fn($this, $secs2cache, $sql, $inputarr); } // ok, set cached object found $rs->connection = &$this; // Pablo suggestion if ($this->debug){ global $HTTP_SERVER_VARS; $inBrowser = isset($HTTP_SERVER_VARS[\'HTTP_USER_AGENT\']); $ttl = $rs->timeCreated + $secs2cache - time(); $s = is_array($sql) ? $sql[0] : $sql; if ($inBrowser) $s = \'\'.htmlspecialchars($s).\'\'; ADOConnection::outp( " $md5file reloaded, ttl=$ttl [ $s ]"); } } return $rs; } /** * Generates an Update Query based on an existing recordset. * $arrFields is an associative array of fields with the value * that should be assigned. * * Note: This function should only be used on a recordset * that is run against a single table and sql should only * be a simple select stmt with no groupby/orderby/limit * * "Jonathan Younger" */ function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false) { global $ADODB_INCLUDED_LIB; if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.\'/adodb-lib.inc.php\'); return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq); } /** * Generates an Insert Query based on an existing recordset. * $arrFields is an associative array of fields with the value * that should be assigned. * * Note: This function should only be used on a recordset * that is run against a single table. */ function GetInsertSQL(&$rs, $arrFields,$magicq=false) { global $ADODB_INCLUDED_LIB; if (empty($ADODB_INCLUDED_LIB)) include_once(ADODB_DIR.\'/adodb-lib.inc.php\'); return _adodb_getinsertsql($this,$rs,$arrFields,$magicq); } /** * Update a blob column, given a where clause. There are more sophisticated * blob handling functions that we could have implemented, but all require * a very complex API. Instead we have chosen something that is extremely * simple to understand and use. * * Note: $blobtype supports \'BLOB\' and \'CLOB\', default is BLOB of course. * * Usage to update a $blobvalue which has a primary key blob_id=1 into a * field blobtable.blobcolumn: * * UpdateBlob(\'blobtable\', \'blobcolumn\', $blobvalue, \'blob_id=1\'); * * Insert example: * * $conn->Execute(\'INSERT INTO blobtable (id, blobcol) VALUES (1, null)\'); * $conn->UpdateBlob(\'blobtable\',\'blobcol\',$blob,\'id=1\'); */ function UpdateBlob($table,$column,$val,$where,$blobtype=\'BLOB\') { return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; } /** * Usage: * UpdateBlob(\'TABLE\', \'COLUMN\', \'/path/to/file\', \'ID=1\'); * * $blobtype supports \'BLOB\' and \'CLOB\' * * $conn->Execute(\'INSERT INTO blobtable (id, blobcol) VALUES (1, null)\'); * $conn->UpdateBlob(\'blobtable\',\'blobcol\',$blobpath,\'id=1\'); */ function UpdateBlobFile($table,$column,$path,$where,$blobtype=\'BLOB\') { $fd = fopen($path,\'rb\'); if ($fd === false) return false; $val = fread($fd,filesize($path)); fclose($fd); return $this->UpdateBlob($table,$column,$val,$where,$blobtype); } function BlobDecode($blob) { return $blob; } function BlobEncode($blob) { return $blob; } function SetCharSet($charset) { return false; } function IfNull( $field, $ifNull ) { return " CASE WHEN $field is null THEN $ifNull ELSE $field END "; } function LogSQL($enable=true) { include_once(ADODB_DIR.\'/adodb-perf.inc.php\'); if ($enable) $this->fnExecute = \'adodb_log_sql\'; else $this->fnExecute = false; $old = $this->_logsql; $this->_logsql = $enable; if ($enable && !$old) $this->_affected = false; return $old; } function GetCharSet() { return false; } /** * Usage: * UpdateClob(\'TABLE\', \'COLUMN\', $var, \'ID=1\', \'CLOB\'); * * $conn->Execute(\'INSERT INTO clobtable (id, clobcol) VALUES (1, null)\'); * $conn->UpdateClob(\'clobtable\',\'clobcol\',$clob,\'id=1\'); */ function UpdateClob($table,$column,$val,$where) { return $this->UpdateBlob($table,$column,$val,$where,\'CLOB\'); } /** * Change the SQL connection locale to a specified locale. * This is used to get the date formats written depending on the client locale. */ function SetDateLocale($locale = \'En\') { $this->locale = $locale; switch ($locale) { default: case \'En\': $this->fmtDate="Y-m-d"; $this->fmtTimeStamp = "Y-m-d H:i:s"; break; case \'Fr\': case \'Ro\': case \'It\': $this->fmtDate="d-m-Y"; $this->fmtTimeStamp = "d-m-Y H:i:s"; break; case \'Ge\': $this->fmtDate="d.m.Y"; $this->fmtTimeStamp = "d.m.Y H:i:s"; 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; } } /* * Maximum size of C field * function CharMax() { return 255; // make it conservative if not defined } /* * Maximum size of X field * function TextMax() { return 4000; // make it conservative if not defined } */ /** * Close Connection */ function Close() { return $this->_close(); // "Simon Lee" reports that persistent connections need // to be closed too! //if ($this->_isPersistentConnection != true) return $this->_close(); //else return true; } /** * Begin a Transaction. Must be followed by CommitTrans() or RollbackTrans(). * * @return true if succeeded or false if database does not support transactions */ function BeginTrans() {return false;} /** * If database does not support transactions, always return true as data always commited * * @param $ok set to false to rollback transaction, true to commit * * @return true/false. */ function CommitTrans($ok=true) { return true;} /** * If database does not support transactions, rollbacks always fail, so return false * * @return true/false. */ function RollbackTrans() { return false;} /** * return the databases that the driver can connect to. * Some databases will return an empty array. * * @return an array of database names. */ function MetaDatabases() { global $ADODB_FETCH_MODE; if ($this->metaDatabasesSQL) { $save = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); $arr = $this->GetCol($this->metaDatabasesSQL); if (isset($savem)) $this->SetFetchMode($savem); $ADODB_FETCH_MODE = $save; return $arr; } return false; } /** * @param ttype can either be \'VIEW\' or \'TABLE\' or false. * If false, both views and tables are returned. * "VIEW" returns only views * "TABLE" returns only tables * @param showSchema returns the schema/user with the table name, eg. USER.TABLE * @param mask is the input mask - only supported by oci8 and postgresql * * @return array of tables for current database. */ function &MetaTables($ttype=false,$showSchema=false,$mask=false) { global $ADODB_FETCH_MODE; if ($mask) return false; if ($this->metaTablesSQL) { // complicated state saving by the need for backward compat $save = $ADODB_FETCH_MODE; $ADODB_FETCH_MODE = ADODB_FETCH_NUM; if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false); $rs = $this->Execute($this->metaTablesSQL); if (isset($savem)) $this->SetFetchMode($savem); $ADODB_FETCH_MODE = $save; if ($rs === false) return false; $arr =& $rs->GetArray(); $arr2 = array(); if ($hast = ($ttype && isset($arr[0][1]))) { $showt = strncmp($ttype,\'T\',1); } for ($i=0; $i < sizeof($arr); $i++) { if ($hast) { if ($showt == 0) { if (strncmp($arr[$i][1],\'T\',1) == 0) $arr2[] = trim($arr[$i][0]); } else { if (strncmp($arr[$i][1],\'V\',1) == 0) $arr2[] = trim($arr[$i][0]); } } else $arr2[] = trim($arr[$i][0]); } $rs->Close(); return $arr2; } return false; } /** * List columns in a database as an array of ADOFieldObjects. * See top of file for definition of object. * * @param table table name