TYPO3 CMS  TYPO3_7-6
adodb.inc.php
Go to the documentation of this file.
1 <?php
2 /*
3  * Set tabs to 4 for best viewing.
4  *
5  * Latest version is available at http://adodb.sourceforge.net
6  *
7  * This is the main include file for ADOdb.
8  * Database specific drivers are stored in the adodb/drivers/adodb-*.inc.php
9  *
10  * The ADOdb files are formatted so that doxygen can be used to generate documentation.
11  * Doxygen is a documentation generation tool and can be downloaded from http://doxygen.org/
12  */
13 
37 if (!defined('_ADODB_LAYER')) {
38  define('_ADODB_LAYER',1);
39 
40  //==============================================================================================
41  // CONSTANT DEFINITIONS
42  //==============================================================================================
43 
44 
49  if (!defined('ADODB_DIR')) {
50  define('ADODB_DIR',dirname(__FILE__));
51  }
52 
53  //==============================================================================================
54  // GLOBAL VARIABLES
55  //==============================================================================================
56 
57  GLOBAL
58  $ADODB_vers, // database version
59  $ADODB_COUNTRECS, // count number of records returned - slows down query
60  $ADODB_CACHE_DIR, // directory to cache recordsets
61  $ADODB_CACHE,
62  $ADODB_CACHE_CLASS,
63  $ADODB_EXTENSION, // ADODB extension installed
64  $ADODB_COMPAT_FETCH, // If $ADODB_COUNTRECS and this is true, $rs->fields is available on EOF
65  $ADODB_FETCH_MODE, // DEFAULT, NUM, ASSOC or BOTH. Default follows native driver default...
66  $ADODB_GETONE_EOF,
67  $ADODB_QUOTE_FIELDNAMES; // Allows you to force quotes (backticks) around field names in queries generated by getinsertsql and getupdatesql.
68 
69  //==============================================================================================
70  // GLOBAL SETUP
71  //==============================================================================================
72 
73  $ADODB_EXTENSION = defined('ADODB_EXTENSION');
74 
75  // ********************************************************
76  // Controls $ADODB_FORCE_TYPE mode. Default is ADODB_FORCE_VALUE (3).
77  // Used in GetUpdateSql and GetInsertSql functions. Thx to Niko, nuko#mbnet.fi
78  //
79  // 0 = ignore empty fields. All empty fields in array are ignored.
80  // 1 = force null. All empty, php null and string 'null' fields are changed to sql NULL values.
81  // 2 = force empty. All empty, php null and string 'null' fields are changed to sql empty '' or 0 values.
82  // 3 = force value. Value is left as it is. Php null and string 'null' are set to sql NULL values and empty fields '' are set to empty '' sql values.
83 
84  define('ADODB_FORCE_IGNORE',0);
85  define('ADODB_FORCE_NULL',1);
86  define('ADODB_FORCE_EMPTY',2);
87  define('ADODB_FORCE_VALUE',3);
88  // ********************************************************
89 
90 
91  if (!$ADODB_EXTENSION || ADODB_EXTENSION < 4.0) {
92 
93  define('ADODB_BAD_RS','<p>Bad $rs in %s. Connection or SQL invalid. Try using $connection->debug=true;</p>');
94 
95  // allow [ ] @ ` " and . in table names
96  define('ADODB_TABLE_REGEX','([]0-9a-z_\:\"\`\.\@\[-]*)');
97 
98  // prefetching used by oracle
99  if (!defined('ADODB_PREFETCH_ROWS')) {
100  define('ADODB_PREFETCH_ROWS',10);
101  }
102 
103 
116  define('ADODB_FETCH_DEFAULT', 0);
117  define('ADODB_FETCH_NUM', 1);
118  define('ADODB_FETCH_ASSOC', 2);
119  define('ADODB_FETCH_BOTH', 3);
120 
136  define('ADODB_ASSOC_CASE_LOWER', 0);
137  define('ADODB_ASSOC_CASE_UPPER', 1);
138  define('ADODB_ASSOC_CASE_NATIVE', 2);
139 
140 
141  if (!defined('TIMESTAMP_FIRST_YEAR')) {
142  define('TIMESTAMP_FIRST_YEAR',100);
143  }
144 
149  define('DB_AUTOQUERY_INSERT', 1);
150  define('DB_AUTOQUERY_UPDATE', 2);
151 
152 
153  // PHP's version scheme makes converting to numbers difficult - workaround
154  $_adodb_ver = (float) PHP_VERSION;
155  if ($_adodb_ver >= 5.2) {
156  define('ADODB_PHPVER',0x5200);
157  } else if ($_adodb_ver >= 5.0) {
158  define('ADODB_PHPVER',0x5000);
159  } else {
160  die("PHP5 or later required. You are running ".PHP_VERSION);
161  }
162  unset($_adodb_ver);
163  }
164 
165 
169  function ADODB_str_replace($src, $dest, $data) {
170  if (ADODB_PHPVER >= 0x4050) {
171  return str_replace($src,$dest,$data);
172  }
173 
174  $s = reset($src);
175  $d = reset($dest);
176  while ($s !== false) {
177  $data = str_replace($s,$d,$data);
178  $s = next($src);
179  $d = next($dest);
180  }
181  return $data;
182  }
183 
184  function ADODB_Setup() {
185  GLOBAL
186  $ADODB_vers, // database version
187  $ADODB_COUNTRECS, // count number of records returned - slows down query
188  $ADODB_CACHE_DIR, // directory to cache recordsets
189  $ADODB_FETCH_MODE,
190  $ADODB_CACHE,
191  $ADODB_CACHE_CLASS,
192  $ADODB_FORCE_TYPE,
193  $ADODB_GETONE_EOF,
194  $ADODB_QUOTE_FIELDNAMES;
195 
196  if (empty($ADODB_CACHE_CLASS)) {
197  $ADODB_CACHE_CLASS = 'ADODB_Cache_File' ;
198  }
199  $ADODB_FETCH_MODE = ADODB_FETCH_DEFAULT;
200  $ADODB_FORCE_TYPE = ADODB_FORCE_VALUE;
201  $ADODB_GETONE_EOF = null;
202 
203  if (!isset($ADODB_CACHE_DIR)) {
204  $ADODB_CACHE_DIR = '/tmp'; //(isset($_ENV['TMP'])) ? $_ENV['TMP'] : '/tmp';
205  } else {
206  // do not accept url based paths, eg. http:/ or ftp:/
207  if (strpos($ADODB_CACHE_DIR,'://') !== false) {
208  die("Illegal path http:// or ftp://");
209  }
210  }
211 
212 
213  // Initialize random number generator for randomizing cache flushes
214  // -- note Since PHP 4.2.0, the seed becomes optional and defaults to a random value if omitted.
215  srand(((double)microtime())*1000000);
216 
220  $ADODB_vers = 'v5.20.3 01-Jan-2016';
221 
227  if (!isset($ADODB_COUNTRECS)) {
228  $ADODB_COUNTRECS = true;
229  }
230  }
231 
232 
233  //==============================================================================================
234  // CHANGE NOTHING BELOW UNLESS YOU ARE DESIGNING ADODB
235  //==============================================================================================
236 
237  ADODB_Setup();
238 
239  //==============================================================================================
240  // CLASS ADOFieldObject
241  //==============================================================================================
245  class ADOFieldObject {
246  var $name = '';
247  var $max_length=0;
248  var $type="";
249 /*
250  // additional fields by dannym... (danny_milo@yahoo.com)
251  var $not_null = false;
252  // actually, this has already been built-in in the postgres, fbsql AND mysql module? ^-^
253  // so we can as well make not_null standard (leaving it at "false" does not harm anyways)
254 
255  var $has_default = false; // this one I have done only in mysql and postgres for now ...
256  // others to come (dannym)
257  var $default_value; // default, if any, and supported. Check has_default first.
258 */
259  }
260 
261 
262  function _adodb_safedate($s) {
263  return str_replace(array("'", '\\'), '', $s);
264  }
265 
266  // parse date string to prevent injection attack
267  // date string will have one quote at beginning e.g. '3434343'
268  function _adodb_safedateq($s) {
269  $len = strlen($s);
270  if ($s[0] !== "'") {
271  $s2 = "'".$s[0];
272  } else {
273  $s2 = "'";
274  }
275  for($i=1; $i<$len; $i++) {
276  $ch = $s[$i];
277  if ($ch === '\\') {
278  $s2 .= "'";
279  break;
280  } elseif ($ch === "'") {
281  $s2 .= $ch;
282  break;
283  }
284 
285  $s2 .= $ch;
286  }
287 
288  return strlen($s2) == 0 ? 'null' : $s2;
289  }
290 
291 
292  // for transaction handling
293 
294  function ADODB_TransMonitor($dbms, $fn, $errno, $errmsg, $p1, $p2, &$thisConnection) {
295  //print "Errorno ($fn errno=$errno m=$errmsg) ";
296  $thisConnection->_transOK = false;
297  if ($thisConnection->_oldRaiseFn) {
298  $fn = $thisConnection->_oldRaiseFn;
299  $fn($dbms, $fn, $errno, $errmsg, $p1, $p2,$thisConnection);
300  }
301  }
302 
303  //------------------
304  // class for caching
305  class ADODB_Cache_File {
306 
307  var $createdir = true; // requires creation of temp dirs
308 
309  function __construct() {
310  global $ADODB_INCLUDED_CSV;
311  if (empty($ADODB_INCLUDED_CSV)) {
312  include_once(ADODB_DIR.'/adodb-csvlib.inc.php');
313  }
314  }
315 
316  // write serialised recordset to cache item/file
317  function writecache($filename, $contents, $debug, $secs2cache) {
318  return adodb_write_file($filename, $contents,$debug);
319  }
320 
321  // load serialised recordset and unserialise it
322  function &readcache($filename, &$err, $secs2cache, $rsClass) {
323  $rs = csv2rs($filename,$err,$secs2cache,$rsClass);
324  return $rs;
325  }
326 
327  // flush all items in cache
328  function flushall($debug=false) {
329  global $ADODB_CACHE_DIR;
330 
331  $rez = false;
332 
333  if (strlen($ADODB_CACHE_DIR) > 1) {
334  $rez = $this->_dirFlush($ADODB_CACHE_DIR);
335  if ($debug) {
336  ADOConnection::outp( "flushall: $ADODB_CACHE_DIR<br><pre>\n". $rez."</pre>");
337  }
338  }
339  return $rez;
340  }
341 
342  // flush one file in cache
343  function flushcache($f, $debug=false) {
344  if (!@unlink($f)) {
345  if ($debug) {
346  ADOConnection::outp( "flushcache: failed for $f");
347  }
348  }
349  }
350 
351  function getdirname($hash) {
352  global $ADODB_CACHE_DIR;
353  if (!isset($this->notSafeMode)) {
354  $this->notSafeMode = !ini_get('safe_mode');
355  }
356  return ($this->notSafeMode) ? $ADODB_CACHE_DIR.'/'.substr($hash,0,2) : $ADODB_CACHE_DIR;
357  }
358 
359  // create temp directories
360  function createdir($hash, $debug) {
361  global $ADODB_CACHE_PERMS;
362 
363  $dir = $this->getdirname($hash);
364  if ($this->notSafeMode && !file_exists($dir)) {
365  $oldu = umask(0);
366  if (!@mkdir($dir, empty($ADODB_CACHE_PERMS) ? 0771 : $ADODB_CACHE_PERMS)) {
367  if(!is_dir($dir) && $debug) {
368  ADOConnection::outp("Cannot create $dir");
369  }
370  }
371  umask($oldu);
372  }
373 
374  return $dir;
375  }
376 
383  function _dirFlush($dir, $kill_top_level = false) {
384  if(!$dh = @opendir($dir)) return;
385 
386  while (($obj = readdir($dh))) {
387  if($obj=='.' || $obj=='..') continue;
388  $f = $dir.'/'.$obj;
389 
390  if (strpos($obj,'.cache')) {
391  @unlink($f);
392  }
393  if (is_dir($f)) {
394  $this->_dirFlush($f, true);
395  }
396  }
397  if ($kill_top_level === true) {
398  @rmdir($dir);
399  }
400  return true;
401  }
402  }
403 
404  //==============================================================================================
405  // CLASS ADOConnection
406  //==============================================================================================
407 
411  abstract class ADOConnection {
412  //
413  // PUBLIC VARS
414  //
415  var $dataProvider = 'native';
416  var $databaseType = '';
417  var $database = '';
418  var $host = '';
419  var $user = '';
420  var $password = '';
421  var $debug = false;
422  var $maxblobsize = 262144;
423  var $concat_operator = '+';
424  var $substr = 'substr';
425  var $length = 'length';
426  var $random = 'rand()';
427  var $upperCase = 'upper';
428  var $fmtDate = "'Y-m-d'";
429  var $fmtTimeStamp = "'Y-m-d, h:i:s A'";
430  var $true = '1';
431  var $false = '0';
432  var $replaceQuote = "\\'";
433  var $nameQuote = '"';
434  var $charSet=false;
435  var $metaDatabasesSQL = '';
436  var $metaTablesSQL = '';
437  var $uniqueOrderBy = false;
438  var $emptyDate = '&nbsp;';
439  var $emptyTimeStamp = '&nbsp;';
440  var $lastInsID = false;
441  //--
442  var $hasInsertID = false;
443  var $hasAffectedRows = false;
444  var $hasTop = false;
445  var $hasLimit = false;
446  var $readOnly = false;
447  var $hasMoveFirst = false;
448  var $hasGenID = false;
449  var $hasTransactions = true;
450  //--
451  var $genID = 0;
452  var $raiseErrorFn = false;
453  var $isoDates = false;
454  var $cacheSecs = 3600;
455 
456  // memcache
457  var $memCache = false;
458  var $memCacheHost;
459  var $memCachePort = 11211;
460  var $memCacheCompress = false;
461 
462  var $sysDate = false;
463  var $sysTimeStamp = false;
464  var $sysUTimeStamp = false; // name of function that returns the current timestamp accurate to the microsecond or nearest fraction
465  var $arrayClass = 'ADORecordSet_array';
466 
467  var $noNullStrings = false;
468  var $numCacheHits = 0;
469  var $numCacheMisses = 0;
470  var $pageExecuteCountRows = true;
471  var $uniqueSort = false;
472  var $leftOuter = false;
473  var $rightOuter = false;
474  var $ansiOuter = false;
475  var $autoRollback = false; // autoRollback on PConnect().
476  var $poorAffectedRows = false; // affectedRows not working or unreliable
477 
478  var $fnExecute = false;
479  var $fnCacheExecute = false;
480  var $blobEncodeType = false; // false=not required, 'I'=encode to integer, 'C'=encode to char
481  var $rsPrefix = "ADORecordSet_";
482 
483  var $autoCommit = true;
484  var $transOff = 0;
485  var $transCnt = 0;
486 
487  var $fetchMode=false;
488 
489  var $null2null = 'null'; // in autoexecute/getinsertsql/getupdatesql, this value will be converted to a null
490  var $bulkBind = false; // enable 2D Execute array
491  //
492  // PRIVATE VARS
493  //
494  var $_oldRaiseFn = false;
495  var $_transOK = null;
496  var $_connectionID = false;
497  var $_errorMsg = false;
498  var $_errorCode = false;
500  var $_queryID = false;
501 
502  var $_isPersistentConnection = false;
503  var $_bindInputArray = false;
504  var $_evalAll = false;
505  var $_affected = false;
506  var $_logsql = false;
507  var $_transmode = ''; // transaction mode
508 
509  /*
510  * Additional parameters that may be passed to drivers in the connect string
511  * Driver must be coded to accept the parameters
512  */
513  protected $connectionParameters = array();
514 
528  final public function setConnectionParameter($parameter,$value)
529  {
530 
531  $this->connectionParameters[$parameter] = $value;
532 
533  }
534 
535  static function Version() {
536  global $ADODB_vers;
537 
538  // Semantic Version number matching regex
539  $regex = '^[vV]?(\d+\.\d+\.\d+' // Version number (X.Y.Z) with optional 'V'
540  . '(?:-(?:' // Optional preprod version: a '-'
541  . 'dev|' // followed by 'dev'
542  . '(?:(?:alpha|beta|rc)(?:\.\d+))' // or a preprod suffix and version number
543  . '))?)(?:\s|$)'; // Whitespace or end of string
544 
545  if (!preg_match("/$regex/", $ADODB_vers, $matches)) {
546  // This should normally not happen... Return whatever is between the start
547  // of the string and the first whitespace (or the end of the string).
548  self::outp("Invalid version number: '$ADODB_vers'", 'Version');
549  $regex = '^[vV]?(.*?)(?:\s|$)';
550  preg_match("/$regex/", $ADODB_vers, $matches);
551  }
552  return $matches[1];
553  }
554 
561  function ServerInfo() {
562  return array('description' => '', 'version' => '');
563  }
564 
565  function IsConnected() {
566  return !empty($this->_connectionID);
567  }
568 
569  function _findvers($str) {
570  if (preg_match('/([0-9]+\.([0-9\.])+)/',$str, $arr)) {
571  return $arr[1];
572  } else {
573  return '';
574  }
575  }
576 
581  static function outp($msg,$newline=true) {
582  global $ADODB_FLUSH,$ADODB_OUTP;
583 
584  if (defined('ADODB_OUTP')) {
585  $fn = ADODB_OUTP;
586  $fn($msg,$newline);
587  return;
588  } else if (isset($ADODB_OUTP)) {
589  $fn = $ADODB_OUTP;
590  $fn($msg,$newline);
591  return;
592  }
593 
594  if ($newline) {
595  $msg .= "<br>\n";
596  }
597 
598  if (isset($_SERVER['HTTP_USER_AGENT']) || !$newline) {
599  echo $msg;
600  } else {
601  echo strip_tags($msg);
602  }
603 
604 
605  if (!empty($ADODB_FLUSH) && ob_get_length() !== false) {
606  flush(); // do not flush if output buffering enabled - useless - thx to Jesse Mullan
607  }
608 
609  }
610 
611  function Time() {
612  $rs = $this->_Execute("select $this->sysTimeStamp");
613  if ($rs && !$rs->EOF) {
614  return $this->UnixTimeStamp(reset($rs->fields));
615  }
616 
617  return false;
618  }
619 
631  function Connect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "", $forceNew = false) {
632  if ($argHostname != "") {
633  $this->host = $argHostname;
634  }
635  if ( strpos($this->host, ':') > 0 && isset($this->port) ) {
636  list($this->host, $this->port) = explode(":", $this->host, 2);
637  }
638  if ($argUsername != "") {
639  $this->user = $argUsername;
640  }
641  if ($argPassword != "") {
642  $this->password = 'not stored'; // not stored for security reasons
643  }
644  if ($argDatabaseName != "") {
645  $this->database = $argDatabaseName;
646  }
647 
648  $this->_isPersistentConnection = false;
649 
650  if ($forceNew) {
651  if ($rez=$this->_nconnect($this->host, $this->user, $argPassword, $this->database)) {
652  return true;
653  }
654  } else {
655  if ($rez=$this->_connect($this->host, $this->user, $argPassword, $this->database)) {
656  return true;
657  }
658  }
659  if (isset($rez)) {
660  $err = $this->ErrorMsg();
661  if (empty($err)) {
662  $err = "Connection error to server '$argHostname' with user '$argUsername'";
663  }
664  $ret = false;
665  } else {
666  $err = "Missing extension for ".$this->dataProvider;
667  $ret = 0;
668  }
669  if ($fn = $this->raiseErrorFn) {
670  $fn($this->databaseType,'CONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this);
671  }
672 
673  $this->_connectionID = false;
674  if ($this->debug) {
675  ADOConnection::outp( $this->host.': '.$err);
676  }
677  return $ret;
678  }
679 
680  function _nconnect($argHostname, $argUsername, $argPassword, $argDatabaseName) {
681  return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabaseName);
682  }
683 
684 
695  function NConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") {
696  return $this->Connect($argHostname, $argUsername, $argPassword, $argDatabaseName, true);
697  }
698 
709  function PConnect($argHostname = "", $argUsername = "", $argPassword = "", $argDatabaseName = "") {
710 
711  if (defined('ADODB_NEVER_PERSIST')) {
712  return $this->Connect($argHostname,$argUsername,$argPassword,$argDatabaseName);
713  }
714 
715  if ($argHostname != "") {
716  $this->host = $argHostname;
717  }
718  if ( strpos($this->host, ':') > 0 && isset($this->port) ) {
719  list($this->host, $this->port) = explode(":", $this->host, 2);
720  }
721  if ($argUsername != "") {
722  $this->user = $argUsername;
723  }
724  if ($argPassword != "") {
725  $this->password = 'not stored';
726  }
727  if ($argDatabaseName != "") {
728  $this->database = $argDatabaseName;
729  }
730 
731  $this->_isPersistentConnection = true;
732 
733  if ($rez = $this->_pconnect($this->host, $this->user, $argPassword, $this->database)) {
734  return true;
735  }
736  if (isset($rez)) {
737  $err = $this->ErrorMsg();
738  if (empty($err)) {
739  $err = "Connection error to server '$argHostname' with user '$argUsername'";
740  }
741  $ret = false;
742  } else {
743  $err = "Missing extension for ".$this->dataProvider;
744  $ret = 0;
745  }
746  if ($fn = $this->raiseErrorFn) {
747  $fn($this->databaseType,'PCONNECT',$this->ErrorNo(),$err,$this->host,$this->database,$this);
748  }
749 
750  $this->_connectionID = false;
751  if ($this->debug) {
752  ADOConnection::outp( $this->host.': '.$err);
753  }
754  return $ret;
755  }
756 
757  function outp_throw($msg,$src='WARN',$sql='') {
758  if (defined('ADODB_ERROR_HANDLER') && ADODB_ERROR_HANDLER == 'adodb_throw') {
759  adodb_throw($this->databaseType,$src,-9999,$msg,$sql,false,$this);
760  return;
761  }
762  ADOConnection::outp($msg);
763  }
764 
765  // create cache class. Code is backward compat with old memcache implementation
766  function _CreateCache() {
767  global $ADODB_CACHE, $ADODB_CACHE_CLASS;
768 
769  if ($this->memCache) {
771 
772  if (empty($ADODB_INCLUDED_MEMCACHE)) {
773  include_once(ADODB_DIR.'/adodb-memcache.lib.inc.php');
774  }
775  $ADODB_CACHE = new ADODB_Cache_MemCache($this);
776  } else {
777  $ADODB_CACHE = new $ADODB_CACHE_CLASS($this);
778  }
779  }
780 
781  // Format date column in sql string given an input format that understands Y M D
782  function SQLDate($fmt, $col=false) {
783  if (!$col) {
784  $col = $this->sysDate;
785  }
786  return $col; // child class implement
787  }
788 
804  function Prepare($sql) {
805  return $sql;
806  }
807 
822  function PrepareSP($sql,$param=true) {
823  return $this->Prepare($sql,$param);
824  }
825 
829  function Quote($s) {
830  return $this->qstr($s,false);
831  }
832 
836  function QMagic($s) {
837  return $this->qstr($s,get_magic_quotes_gpc());
838  }
839 
840  function q(&$s) {
841  //if (!empty($this->qNull && $s == 'null') {
842  // return $s;
843  //}
844  $s = $this->qstr($s,false);
845  }
846 
850  function ErrorNative() {
851  return $this->ErrorNo();
852  }
853 
854 
858  function nextId($seq_name) {
859  return $this->GenID($seq_name);
860  }
861 
869  function RowLock($table,$where,$col='1 as adodbignore') {
870  return false;
871  }
872 
873  function CommitLock($table) {
874  return $this->CommitTrans();
875  }
876 
877  function RollbackLock($table) {
878  return $this->RollbackTrans();
879  }
880 
890  function SetFetchMode($mode) {
891  $old = $this->fetchMode;
892  $this->fetchMode = $mode;
893 
894  if ($old === false) {
895  global $ADODB_FETCH_MODE;
896  return $ADODB_FETCH_MODE;
897  }
898  return $old;
899  }
900 
901 
905  function Query($sql, $inputarr=false) {
906  $rs = $this->Execute($sql, $inputarr);
907  if (!$rs && defined('ADODB_PEAR')) {
908  return ADODB_PEAR_Error();
909  }
910  return $rs;
911  }
912 
913 
917  function LimitQuery($sql, $offset, $count, $params=false) {
918  $rs = $this->SelectLimit($sql, $count, $offset, $params);
919  if (!$rs && defined('ADODB_PEAR')) {
920  return ADODB_PEAR_Error();
921  }
922  return $rs;
923  }
924 
925 
929  function Disconnect() {
930  return $this->Close();
931  }
932 
946  function Param($name,$type='C') {
947  return '?';
948  }
949 
950  /*
951  InParameter and OutParameter are self-documenting versions of Parameter().
952  */
953  function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) {
954  return $this->Parameter($stmt,$var,$name,false,$maxLen,$type);
955  }
956 
957  /*
958  */
959  function OutParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false) {
960  return $this->Parameter($stmt,$var,$name,true,$maxLen,$type);
961 
962  }
963 
964 
965  /*
966  Usage in oracle
967  $stmt = $db->Prepare('select * from table where id =:myid and group=:group');
968  $db->Parameter($stmt,$id,'myid');
969  $db->Parameter($stmt,$group,'group',64);
970  $db->Execute();
971 
972  @param $stmt Statement returned by Prepare() or PrepareSP().
973  @param $var PHP variable to bind to
974  @param $name Name of stored procedure variable name to bind to.
975  @param [$isOutput] Indicates direction of parameter 0/false=IN 1=OUT 2= IN/OUT. This is ignored in oci8.
976  @param [$maxLen] Holds an maximum length of the variable.
977  @param [$type] The data type of $var. Legal values depend on driver.
978 
979  */
980  function Parameter(&$stmt,&$var,$name,$isOutput=false,$maxLen=4000,$type=false) {
981  return false;
982  }
983 
984 
985  function IgnoreErrors($saveErrs=false) {
986  if (!$saveErrs) {
987  $saveErrs = array($this->raiseErrorFn,$this->_transOK);
988  $this->raiseErrorFn = false;
989  return $saveErrs;
990  } else {
991  $this->raiseErrorFn = $saveErrs[0];
992  $this->_transOK = $saveErrs[1];
993  }
994  }
995 
1006  function StartTrans($errfn = 'ADODB_TransMonitor') {
1007  if ($this->transOff > 0) {
1008  $this->transOff += 1;
1009  return true;
1010  }
1011 
1012  $this->_oldRaiseFn = $this->raiseErrorFn;
1013  $this->raiseErrorFn = $errfn;
1014  $this->_transOK = true;
1015 
1016  if ($this->debug && $this->transCnt > 0) {
1017  ADOConnection::outp("Bad Transaction: StartTrans called within BeginTrans");
1018  }
1019  $ok = $this->BeginTrans();
1020  $this->transOff = 1;
1021  return $ok;
1022  }
1023 
1024 
1033  function CompleteTrans($autoComplete = true) {
1034  if ($this->transOff > 1) {
1035  $this->transOff -= 1;
1036  return true;
1037  }
1038  $this->raiseErrorFn = $this->_oldRaiseFn;
1039 
1040  $this->transOff = 0;
1041  if ($this->_transOK && $autoComplete) {
1042  if (!$this->CommitTrans()) {
1043  $this->_transOK = false;
1044  if ($this->debug) {
1045  ADOConnection::outp("Smart Commit failed");
1046  }
1047  } else {
1048  if ($this->debug) {
1049  ADOConnection::outp("Smart Commit occurred");
1050  }
1051  }
1052  } else {
1053  $this->_transOK = false;
1054  $this->RollbackTrans();
1055  if ($this->debug) {
1056  ADOCOnnection::outp("Smart Rollback occurred");
1057  }
1058  }
1059 
1060  return $this->_transOK;
1061  }
1062 
1063  /*
1064  At the end of a StartTrans/CompleteTrans block, perform a rollback.
1065  */
1066  function FailTrans() {
1067  if ($this->debug)
1068  if ($this->transOff == 0) {
1069  ADOConnection::outp("FailTrans outside StartTrans/CompleteTrans");
1070  } else {
1071  ADOConnection::outp("FailTrans was called");
1072  adodb_backtrace();
1073  }
1074  $this->_transOK = false;
1075  }
1076 
1080  function HasFailedTrans() {
1081  if ($this->transOff > 0) {
1082  return $this->_transOK == false;
1083  }
1084  return false;
1085  }
1086 
1094  function Execute($sql,$inputarr=false) {
1095  if ($this->fnExecute) {
1096  $fn = $this->fnExecute;
1097  $ret = $fn($this,$sql,$inputarr);
1098  if (isset($ret)) {
1099  return $ret;
1100  }
1101  }
1102  if ($inputarr !== false) {
1103  if (!is_array($inputarr)) {
1104  $inputarr = array($inputarr);
1105  }
1106 
1107  $element0 = reset($inputarr);
1108  # is_object check because oci8 descriptors can be passed in
1109  $array_2d = $this->bulkBind && is_array($element0) && !is_object(reset($element0));
1110 
1111  //remove extra memory copy of input -mikefedyk
1112  unset($element0);
1113 
1114  if (!is_array($sql) && !$this->_bindInputArray) {
1115  // @TODO this would consider a '?' within a string as a parameter...
1116  $sqlarr = explode('?',$sql);
1117  $nparams = sizeof($sqlarr)-1;
1118 
1119  // Make sure the number of parameters provided in the input
1120  // array matches what the query expects
1121  if ($nparams != count($inputarr)) {
1122  $this->outp_throw(
1123  "Input array has " . count($inputarr) .
1124  " params, does not match query: '" . htmlspecialchars($sql) . "'",
1125  'Execute'
1126  );
1127  return false;
1128  }
1129 
1130  if (!$array_2d) {
1131  $inputarr = array($inputarr);
1132  }
1133 
1134  foreach($inputarr as $arr) {
1135  $sql = ''; $i = 0;
1136  //Use each() instead of foreach to reduce memory usage -mikefedyk
1137  while(list(, $v) = each($arr)) {
1138  $sql .= $sqlarr[$i];
1139  // from Ron Baldwin <ron.baldwin#sourceprose.com>
1140  // Only quote string types
1141  $typ = gettype($v);
1142  if ($typ == 'string') {
1143  //New memory copy of input created here -mikefedyk
1144  $sql .= $this->qstr($v);
1145  } else if ($typ == 'double') {
1146  $sql .= str_replace(',','.',$v); // locales fix so 1.1 does not get converted to 1,1
1147  } else if ($typ == 'boolean') {
1148  $sql .= $v ? $this->true : $this->false;
1149  } else if ($typ == 'object') {
1150  if (method_exists($v, '__toString')) {
1151  $sql .= $this->qstr($v->__toString());
1152  } else {
1153  $sql .= $this->qstr((string) $v);
1154  }
1155  } else if ($v === null) {
1156  $sql .= 'NULL';
1157  } else {
1158  $sql .= $v;
1159  }
1160  $i += 1;
1161 
1162  if ($i == $nparams) {
1163  break;
1164  }
1165  } // while
1166  if (isset($sqlarr[$i])) {
1167  $sql .= $sqlarr[$i];
1168  if ($i+1 != sizeof($sqlarr)) {
1169  $this->outp_throw( "Input Array does not match ?: ".htmlspecialchars($sql),'Execute');
1170  }
1171  } else if ($i != sizeof($sqlarr)) {
1172  $this->outp_throw( "Input array does not match ?: ".htmlspecialchars($sql),'Execute');
1173  }
1174 
1175  $ret = $this->_Execute($sql);
1176  if (!$ret) {
1177  return $ret;
1178  }
1179  }
1180  } else {
1181  if ($array_2d) {
1182  if (is_string($sql)) {
1183  $stmt = $this->Prepare($sql);
1184  } else {
1185  $stmt = $sql;
1186  }
1187 
1188  foreach($inputarr as $arr) {
1189  $ret = $this->_Execute($stmt,$arr);
1190  if (!$ret) {
1191  return $ret;
1192  }
1193  }
1194  } else {
1195  $ret = $this->_Execute($sql,$inputarr);
1196  }
1197  }
1198  } else {
1199  $ret = $this->_Execute($sql,false);
1200  }
1201 
1202  return $ret;
1203  }
1204 
1205  function _Execute($sql,$inputarr=false) {
1206  // ExecuteCursor() may send non-string queries (such as arrays),
1207  // so we need to ignore those.
1208  if( is_string($sql) ) {
1209  // Strips keyword used to help generate SELECT COUNT(*) queries
1210  // from SQL if it exists.
1211  $sql = ADODB_str_replace( '_ADODB_COUNT', '', $sql );
1212  }
1213 
1214  if ($this->debug) {
1215  global $ADODB_INCLUDED_LIB;
1216  if (empty($ADODB_INCLUDED_LIB)) {
1217  include(ADODB_DIR.'/adodb-lib.inc.php');
1218  }
1219  $this->_queryID = _adodb_debug_execute($this, $sql,$inputarr);
1220  } else {
1221  $this->_queryID = @$this->_query($sql,$inputarr);
1222  }
1223 
1224  // ************************
1225  // OK, query executed
1226  // ************************
1227 
1228  // error handling if query fails
1229  if ($this->_queryID === false) {
1230  if ($this->debug == 99) {
1231  adodb_backtrace(true,5);
1232  }
1233  $fn = $this->raiseErrorFn;
1234  if ($fn) {
1235  $fn($this->databaseType,'EXECUTE',$this->ErrorNo(),$this->ErrorMsg(),$sql,$inputarr,$this);
1236  }
1237  return false;
1238  }
1239 
1240  // return simplified recordset for inserts/updates/deletes with lower overhead
1241  if ($this->_queryID === true) {
1242  $rsclass = $this->rsPrefix.'empty';
1243  $rs = (class_exists($rsclass)) ? new $rsclass(): new ADORecordSet_empty();
1244 
1245  return $rs;
1246  }
1247 
1248  // return real recordset from select statement
1249  $rsclass = $this->rsPrefix.$this->databaseType;
1250  $rs = new $rsclass($this->_queryID,$this->fetchMode);
1251  $rs->connection = $this; // Pablo suggestion
1252  $rs->Init();
1253  if (is_array($sql)) {
1254  $rs->sql = $sql[0];
1255  } else {
1256  $rs->sql = $sql;
1257  }
1258  if ($rs->_numOfRows <= 0) {
1259  global $ADODB_COUNTRECS;
1260  if ($ADODB_COUNTRECS) {
1261  if (!$rs->EOF) {
1262  $rs = $this->_rs2rs($rs,-1,-1,!is_array($sql));
1263  $rs->_queryID = $this->_queryID;
1264  } else
1265  $rs->_numOfRows = 0;
1266  }
1267  }
1268  return $rs;
1269  }
1270 
1271  function CreateSequence($seqname='adodbseq',$startID=1) {
1272  if (empty($this->_genSeqSQL)) {
1273  return false;
1274  }
1275  return $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
1276  }
1277 
1278  function DropSequence($seqname='adodbseq') {
1279  if (empty($this->_dropSeqSQL)) {
1280  return false;
1281  }
1282  return $this->Execute(sprintf($this->_dropSeqSQL,$seqname));
1283  }
1284 
1293  function GenID($seqname='adodbseq',$startID=1) {
1294  if (!$this->hasGenID) {
1295  return 0; // formerly returns false pre 1.60
1296  }
1297 
1298  $getnext = sprintf($this->_genIDSQL,$seqname);
1299 
1300  $holdtransOK = $this->_transOK;
1301 
1302  $save_handler = $this->raiseErrorFn;
1303  $this->raiseErrorFn = '';
1304  @($rs = $this->Execute($getnext));
1305  $this->raiseErrorFn = $save_handler;
1306 
1307  if (!$rs) {
1308  $this->_transOK = $holdtransOK; //if the status was ok before reset
1309  $createseq = $this->Execute(sprintf($this->_genSeqSQL,$seqname,$startID));
1310  $rs = $this->Execute($getnext);
1311  }
1312  if ($rs && !$rs->EOF) {
1313  $this->genID = reset($rs->fields);
1314  } else {
1315  $this->genID = 0; // false
1316  }
1317 
1318  if ($rs) {
1319  $rs->Close();
1320  }
1321 
1322  return $this->genID;
1323  }
1324 
1330  function Insert_ID($table='',$column='') {
1331  if ($this->_logsql && $this->lastInsID) {
1332  return $this->lastInsID;
1333  }
1334  if ($this->hasInsertID) {
1335  return $this->_insertid($table,$column);
1336  }
1337  if ($this->debug) {
1338  ADOConnection::outp( '<p>Insert_ID error</p>');
1339  adodb_backtrace();
1340  }
1341  return false;
1342  }
1343 
1344 
1351  function PO_Insert_ID($table="", $id="") {
1352  if ($this->hasInsertID){
1353  return $this->Insert_ID($table,$id);
1354  } else {
1355  return $this->GetOne("SELECT MAX($id) FROM $table");
1356  }
1357  }
1358 
1362  function Affected_Rows() {
1363  if ($this->hasAffectedRows) {
1364  if ($this->fnExecute === 'adodb_log_sql') {
1365  if ($this->_logsql && $this->_affected !== false) {
1366  return $this->_affected;
1367  }
1368  }
1369  $val = $this->_affectedrows();
1370  return ($val < 0) ? false : $val;
1371  }
1372 
1373  if ($this->debug) {
1374  ADOConnection::outp( '<p>Affected_Rows error</p>',false);
1375  }
1376  return false;
1377  }
1378 
1379 
1383  function ErrorMsg() {
1384  if ($this->_errorMsg) {
1385  return '!! '.strtoupper($this->dataProvider.' '.$this->databaseType).': '.$this->_errorMsg;
1386  } else {
1387  return '';
1388  }
1389  }
1390 
1391 
1395  function ErrorNo() {
1396  return ($this->_errorMsg) ? -1 : 0;
1397  }
1398 
1399  function MetaError($err=false) {
1400  include_once(ADODB_DIR."/adodb-error.inc.php");
1401  if ($err === false) {
1402  $err = $this->ErrorNo();
1403  }
1404  return adodb_error($this->dataProvider,$this->databaseType,$err);
1405  }
1406 
1407  function MetaErrorMsg($errno) {
1408  include_once(ADODB_DIR."/adodb-error.inc.php");
1409  return adodb_errormsg($errno);
1410  }
1411 
1415  function MetaPrimaryKeys($table, $owner=false) {
1416  // owner not used in base class - see oci8
1417  $p = array();
1418  $objs = $this->MetaColumns($table);
1419  if ($objs) {
1420  foreach($objs as $v) {
1421  if (!empty($v->primary_key)) {
1422  $p[] = $v->name;
1423  }
1424  }
1425  }
1426  if (sizeof($p)) {
1427  return $p;
1428  }
1429  if (function_exists('ADODB_VIEW_PRIMARYKEYS')) {
1430  return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner);
1431  }
1432  return false;
1433  }
1434 
1438  function MetaForeignKeys($table, $owner=false, $upper=false) {
1439  return false;
1440  }
1447  function SelectDB($dbName) {return false;}
1448 
1449 
1469  function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0) {
1470  if ($this->hasTop && $nrows > 0) {
1471  // suggested by Reinhard Balling. Access requires top after distinct
1472  // Informix requires first before distinct - F Riosa
1473  $ismssql = (strpos($this->databaseType,'mssql') !== false);
1474  if ($ismssql) {
1475  $isaccess = false;
1476  } else {
1477  $isaccess = (strpos($this->databaseType,'access') !== false);
1478  }
1479 
1480  if ($offset <= 0) {
1481  // access includes ties in result
1482  if ($isaccess) {
1483  $sql = preg_replace(
1484  '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
1485 
1486  if ($secs2cache != 0) {
1487  $ret = $this->CacheExecute($secs2cache, $sql,$inputarr);
1488  } else {
1489  $ret = $this->Execute($sql,$inputarr);
1490  }
1491  return $ret; // PHP5 fix
1492  } else if ($ismssql){
1493  $sql = preg_replace(
1494  '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
1495  } else {
1496  $sql = preg_replace(
1497  '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.((integer)$nrows).' ',$sql);
1498  }
1499  } else {
1500  $nn = $nrows + $offset;
1501  if ($isaccess || $ismssql) {
1502  $sql = preg_replace(
1503  '/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql);
1504  } else {
1505  $sql = preg_replace(
1506  '/(^\s*select\s)/i','\\1 '.$this->hasTop.' '.$nn.' ',$sql);
1507  }
1508  }
1509  }
1510 
1511  // if $offset>0, we want to skip rows, and $ADODB_COUNTRECS is set, we buffer rows
1512  // 0 to offset-1 which will be discarded anyway. So we disable $ADODB_COUNTRECS.
1513  global $ADODB_COUNTRECS;
1514 
1515  $savec = $ADODB_COUNTRECS;
1516  $ADODB_COUNTRECS = false;
1517 
1518 
1519  if ($secs2cache != 0) {
1520  $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
1521  } else {
1522  $rs = $this->Execute($sql,$inputarr);
1523  }
1524 
1525  $ADODB_COUNTRECS = $savec;
1526  if ($rs && !$rs->EOF) {
1527  $rs = $this->_rs2rs($rs,$nrows,$offset);
1528  }
1529  //print_r($rs);
1530  return $rs;
1531  }
1532 
1538  function SerializableRS(&$rs) {
1539  $rs2 = $this->_rs2rs($rs);
1540  $ignore = false;
1541  $rs2->connection = $ignore;
1542 
1543  return $rs2;
1544  }
1545 
1556  function &_rs2rs(&$rs,$nrows=-1,$offset=-1,$close=true) {
1557  if (! $rs) {
1558  return false;
1559  }
1560  $dbtype = $rs->databaseType;
1561  if (!$dbtype) {
1562  $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1 -- why ?
1563  return $rs;
1564  }
1565  if (($dbtype == 'array' || $dbtype == 'csv') && $nrows == -1 && $offset == -1) {
1566  $rs->MoveFirst();
1567  $rs = $rs; // required to prevent crashing in 4.2.1, but does not happen in 4.3.1-- why ?
1568  return $rs;
1569  }
1570  $flds = array();
1571  for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
1572  $flds[] = $rs->FetchField($i);
1573  }
1574 
1575  $arr = $rs->GetArrayLimit($nrows,$offset);
1576  //print_r($arr);
1577  if ($close) {
1578  $rs->Close();
1579  }
1580 
1581  $arrayClass = $this->arrayClass;
1582 
1583  $rs2 = new $arrayClass();
1584  $rs2->connection = $this;
1585  $rs2->sql = $rs->sql;
1586  $rs2->dataProvider = $this->dataProvider;
1587  $rs2->InitArrayFields($arr,$flds);
1588  $rs2->fetchMode = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode;
1589  return $rs2;
1590  }
1591 
1592  /*
1593  * Return all rows. Compat with PEAR DB
1594  */
1595  function GetAll($sql, $inputarr=false) {
1596  $arr = $this->GetArray($sql,$inputarr);
1597  return $arr;
1598  }
1599 
1600  function GetAssoc($sql, $inputarr=false,$force_array = false, $first2cols = false) {
1601  $rs = $this->Execute($sql, $inputarr);
1602  if (!$rs) {
1603  return false;
1604  }
1605  $arr = $rs->GetAssoc($force_array,$first2cols);
1606  return $arr;
1607  }
1608 
1609  function CacheGetAssoc($secs2cache, $sql=false, $inputarr=false,$force_array = false, $first2cols = false) {
1610  if (!is_numeric($secs2cache)) {
1611  $first2cols = $force_array;
1612  $force_array = $inputarr;
1613  }
1614  $rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
1615  if (!$rs) {
1616  return false;
1617  }
1618  $arr = $rs->GetAssoc($force_array,$first2cols);
1619  return $arr;
1620  }
1621 
1629  function GetOne($sql,$inputarr=false) {
1630  global $ADODB_COUNTRECS,$ADODB_GETONE_EOF;
1631 
1632  $crecs = $ADODB_COUNTRECS;
1633  $ADODB_COUNTRECS = false;
1634 
1635  $ret = false;
1636  $rs = $this->Execute($sql,$inputarr);
1637  if ($rs) {
1638  if ($rs->EOF) {
1639  $ret = $ADODB_GETONE_EOF;
1640  } else {
1641  $ret = reset($rs->fields);
1642  }
1643 
1644  $rs->Close();
1645  }
1646  $ADODB_COUNTRECS = $crecs;
1647  return $ret;
1648  }
1649 
1650  // $where should include 'WHERE fld=value'
1651  function GetMedian($table, $field,$where = '') {
1652  $total = $this->GetOne("select count(*) from $table $where");
1653  if (!$total) {
1654  return false;
1655  }
1656 
1657  $midrow = (integer) ($total/2);
1658  $rs = $this->SelectLimit("select $field from $table $where order by 1",1,$midrow);
1659  if ($rs && !$rs->EOF) {
1660  return reset($rs->fields);
1661  }
1662  return false;
1663  }
1664 
1665 
1666  function CacheGetOne($secs2cache,$sql=false,$inputarr=false) {
1667  global $ADODB_GETONE_EOF;
1668 
1669  $ret = false;
1670  $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
1671  if ($rs) {
1672  if ($rs->EOF) {
1673  $ret = $ADODB_GETONE_EOF;
1674  } else {
1675  $ret = reset($rs->fields);
1676  }
1677  $rs->Close();
1678  }
1679 
1680  return $ret;
1681  }
1682 
1683  function GetCol($sql, $inputarr = false, $trim = false) {
1684 
1685  $rs = $this->Execute($sql, $inputarr);
1686  if ($rs) {
1687  $rv = array();
1688  if ($trim) {
1689  while (!$rs->EOF) {
1690  $rv[] = trim(reset($rs->fields));
1691  $rs->MoveNext();
1692  }
1693  } else {
1694  while (!$rs->EOF) {
1695  $rv[] = reset($rs->fields);
1696  $rs->MoveNext();
1697  }
1698  }
1699  $rs->Close();
1700  } else {
1701  $rv = false;
1702  }
1703  return $rv;
1704  }
1705 
1706  function CacheGetCol($secs, $sql = false, $inputarr = false,$trim=false) {
1707  $rs = $this->CacheExecute($secs, $sql, $inputarr);
1708  if ($rs) {
1709  $rv = array();
1710  if ($trim) {
1711  while (!$rs->EOF) {
1712  $rv[] = trim(reset($rs->fields));
1713  $rs->MoveNext();
1714  }
1715  } else {
1716  while (!$rs->EOF) {
1717  $rv[] = reset($rs->fields);
1718  $rs->MoveNext();
1719  }
1720  }
1721  $rs->Close();
1722  } else
1723  $rv = false;
1724 
1725  return $rv;
1726  }
1727 
1728  function Transpose(&$rs,$addfieldnames=true) {
1729  $rs2 = $this->_rs2rs($rs);
1730  if (!$rs2) {
1731  return false;
1732  }
1733 
1734  $rs2->_transpose($addfieldnames);
1735  return $rs2;
1736  }
1737 
1738  /*
1739  Calculate the offset of a date for a particular database and generate
1740  appropriate SQL. Useful for calculating future/past dates and storing
1741  in a database.
1742 
1743  If dayFraction=1.5 means 1.5 days from now, 1.0/24 for 1 hour.
1744  */
1745  function OffsetDate($dayFraction,$date=false) {
1746  if (!$date) {
1747  $date = $this->sysDate;
1748  }
1749  return '('.$date.'+'.$dayFraction.')';
1750  }
1751 
1752 
1758  function GetArray($sql,$inputarr=false) {
1759  global $ADODB_COUNTRECS;
1760 
1761  $savec = $ADODB_COUNTRECS;
1762  $ADODB_COUNTRECS = false;
1763  $rs = $this->Execute($sql,$inputarr);
1764  $ADODB_COUNTRECS = $savec;
1765  if (!$rs)
1766  if (defined('ADODB_PEAR')) {
1767  $cls = ADODB_PEAR_Error();
1768  return $cls;
1769  } else {
1770  return false;
1771  }
1772  $arr = $rs->GetArray();
1773  $rs->Close();
1774  return $arr;
1775  }
1776 
1777  function CacheGetAll($secs2cache,$sql=false,$inputarr=false) {
1778  $arr = $this->CacheGetArray($secs2cache,$sql,$inputarr);
1779  return $arr;
1780  }
1781 
1782  function CacheGetArray($secs2cache,$sql=false,$inputarr=false) {
1783  global $ADODB_COUNTRECS;
1784 
1785  $savec = $ADODB_COUNTRECS;
1786  $ADODB_COUNTRECS = false;
1787  $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
1788  $ADODB_COUNTRECS = $savec;
1789 
1790  if (!$rs)
1791  if (defined('ADODB_PEAR')) {
1792  $cls = ADODB_PEAR_Error();
1793  return $cls;
1794  } else {
1795  return false;
1796  }
1797  $arr = $rs->GetArray();
1798  $rs->Close();
1799  return $arr;
1800  }
1801 
1802  function GetRandRow($sql, $arr= false) {
1803  $rezarr = $this->GetAll($sql, $arr);
1804  $sz = sizeof($rezarr);
1805  return $rezarr[abs(rand()) % $sz];
1806  }
1807 
1815  function GetRow($sql,$inputarr=false) {
1816  global $ADODB_COUNTRECS;
1817 
1818  $crecs = $ADODB_COUNTRECS;
1819  $ADODB_COUNTRECS = false;
1820 
1821  $rs = $this->Execute($sql,$inputarr);
1822 
1823  $ADODB_COUNTRECS = $crecs;
1824  if ($rs) {
1825  if (!$rs->EOF) {
1826  $arr = $rs->fields;
1827  } else {
1828  $arr = array();
1829  }
1830  $rs->Close();
1831  return $arr;
1832  }
1833 
1834  return false;
1835  }
1836 
1837  function CacheGetRow($secs2cache,$sql=false,$inputarr=false) {
1838  $rs = $this->CacheExecute($secs2cache,$sql,$inputarr);
1839  if ($rs) {
1840  if (!$rs->EOF) {
1841  $arr = $rs->fields;
1842  } else {
1843  $arr = array();
1844  }
1845 
1846  $rs->Close();
1847  return $arr;
1848  }
1849  return false;
1850  }
1851 
1872  function Replace($table, $fieldArray, $keyCol, $autoQuote=false, $has_autoinc=false) {
1873  global $ADODB_INCLUDED_LIB;
1874  if (empty($ADODB_INCLUDED_LIB)) {
1875  include(ADODB_DIR.'/adodb-lib.inc.php');
1876  }
1877 
1878  return _adodb_replace($this, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc);
1879  }
1880 
1881 
1900  function CacheSelectLimit($secs2cache,$sql,$nrows=-1,$offset=-1,$inputarr=false) {
1901  if (!is_numeric($secs2cache)) {
1902  if ($sql === false) {
1903  $sql = -1;
1904  }
1905  if ($offset == -1) {
1906  $offset = false;
1907  }
1908  // sql, nrows, offset,inputarr
1909  $rs = $this->SelectLimit($secs2cache,$sql,$nrows,$offset,$this->cacheSecs);
1910  } else {
1911  if ($sql === false) {
1912  $this->outp_throw("Warning: \$sql missing from CacheSelectLimit()",'CacheSelectLimit');
1913  }
1914  $rs = $this->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
1915  }
1916  return $rs;
1917  }
1918 
1923  function CacheFlush($sql=false,$inputarr=false) {
1924  global $ADODB_CACHE_DIR, $ADODB_CACHE;
1925 
1926  # Create cache if it does not exist
1927  if (empty($ADODB_CACHE)) {
1928  $this->_CreateCache();
1929  }
1930 
1931  if (!$sql) {
1932  $ADODB_CACHE->flushall($this->debug);
1933  return;
1934  }
1935 
1936  $f = $this->_gencachename($sql.serialize($inputarr),false);
1937  return $ADODB_CACHE->flushcache($f, $this->debug);
1938  }
1939 
1940 
1955  function _gencachename($sql,$createdir) {
1956  global $ADODB_CACHE, $ADODB_CACHE_DIR;
1957 
1958  if ($this->fetchMode === false) {
1959  global $ADODB_FETCH_MODE;
1960  $mode = $ADODB_FETCH_MODE;
1961  } else {
1962  $mode = $this->fetchMode;
1963  }
1964  $m = md5($sql.$this->databaseType.$this->database.$this->user.$mode);
1965  if (!$ADODB_CACHE->createdir) {
1966  return $m;
1967  }
1968  if (!$createdir) {
1969  $dir = $ADODB_CACHE->getdirname($m);
1970  } else {
1971  $dir = $ADODB_CACHE->createdir($m, $this->debug);
1972  }
1973 
1974  return $dir.'/adodb_'.$m.'.cache';
1975  }
1976 
1977 
1987  function CacheExecute($secs2cache,$sql=false,$inputarr=false) {
1988  global $ADODB_CACHE;
1989 
1990  if (empty($ADODB_CACHE)) {
1991  $this->_CreateCache();
1992  }
1993 
1994  if (!is_numeric($secs2cache)) {
1995  $inputarr = $sql;
1996  $sql = $secs2cache;
1997  $secs2cache = $this->cacheSecs;
1998  }
1999 
2000  if (is_array($sql)) {
2001  $sqlparam = $sql;
2002  $sql = $sql[0];
2003  } else
2004  $sqlparam = $sql;
2005 
2006 
2007  $md5file = $this->_gencachename($sql.serialize($inputarr),true);
2008  $err = '';
2009 
2010  if ($secs2cache > 0){
2011  $rs = $ADODB_CACHE->readcache($md5file,$err,$secs2cache,$this->arrayClass);
2012  $this->numCacheHits += 1;
2013  } else {
2014  $err='Timeout 1';
2015  $rs = false;
2016  $this->numCacheMisses += 1;
2017  }
2018 
2019  if (!$rs) {
2020  // no cached rs found
2021  if ($this->debug) {
2022  if (get_magic_quotes_runtime() && !$this->memCache) {
2023  ADOConnection::outp("Please disable magic_quotes_runtime - it corrupts cache files :(");
2024  }
2025  if ($this->debug !== -1) {
2026  ADOConnection::outp( " $md5file cache failure: $err (this is a notice and not an error)");
2027  }
2028  }
2029 
2030  $rs = $this->Execute($sqlparam,$inputarr);
2031 
2032  if ($rs) {
2033  $eof = $rs->EOF;
2034  $rs = $this->_rs2rs($rs); // read entire recordset into memory immediately
2035  $rs->timeCreated = time(); // used by caching
2036  $txt = _rs2serialize($rs,false,$sql); // serialize
2037 
2038  $ok = $ADODB_CACHE->writecache($md5file,$txt,$this->debug, $secs2cache);
2039  if (!$ok) {
2040  if ($ok === false) {
2041  $em = 'Cache write error';
2042  $en = -32000;
2043 
2044  if ($fn = $this->raiseErrorFn) {
2045  $fn($this->databaseType,'CacheExecute', $en, $em, $md5file,$sql,$this);
2046  }
2047  } else {
2048  $em = 'Cache file locked warning';
2049  $en = -32001;
2050  // do not call error handling for just a warning
2051  }
2052 
2053  if ($this->debug) {
2054  ADOConnection::outp( " ".$em);
2055  }
2056  }
2057  if ($rs->EOF && !$eof) {
2058  $rs->MoveFirst();
2059  //$rs = csv2rs($md5file,$err);
2060  $rs->connection = $this; // Pablo suggestion
2061  }
2062 
2063  } else if (!$this->memCache) {
2064  $ADODB_CACHE->flushcache($md5file);
2065  }
2066  } else {
2067  $this->_errorMsg = '';
2068  $this->_errorCode = 0;
2069 
2070  if ($this->fnCacheExecute) {
2071  $fn = $this->fnCacheExecute;
2072  $fn($this, $secs2cache, $sql, $inputarr);
2073  }
2074  // ok, set cached object found
2075  $rs->connection = $this; // Pablo suggestion
2076  if ($this->debug){
2077  if ($this->debug == 99) {
2078  adodb_backtrace();
2079  }
2080  $inBrowser = isset($_SERVER['HTTP_USER_AGENT']);
2081  $ttl = $rs->timeCreated + $secs2cache - time();
2082  $s = is_array($sql) ? $sql[0] : $sql;
2083  if ($inBrowser) {
2084  $s = '<i>'.htmlspecialchars($s).'</i>';
2085  }
2086 
2087  ADOConnection::outp( " $md5file reloaded, ttl=$ttl [ $s ]");
2088  }
2089  }
2090  return $rs;
2091  }
2092 
2093 
2094  /*
2095  Similar to PEAR DB's autoExecute(), except that
2096  $mode can be 'INSERT' or 'UPDATE' or DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
2097  If $mode == 'UPDATE', then $where is compulsory as a safety measure.
2098 
2099  $forceUpdate means that even if the data has not changed, perform update.
2100  */
2101  function AutoExecute($table, $fields_values, $mode = 'INSERT', $where = false, $forceUpdate = true, $magicq = false) {
2102  if ($where === false && ($mode == 'UPDATE' || $mode == 2 /* DB_AUTOQUERY_UPDATE */) ) {
2103  $this->outp_throw('AutoExecute: Illegal mode=UPDATE with empty WHERE clause', 'AutoExecute');
2104  return false;
2105  }
2106 
2107  $sql = "SELECT * FROM $table";
2108  $rs = $this->SelectLimit($sql, 1);
2109  if (!$rs) {
2110  return false; // table does not exist
2111  }
2112 
2113  $rs->tableName = $table;
2114  if ($where !== false) {
2115  $sql .= " WHERE $where";
2116  }
2117  $rs->sql = $sql;
2118 
2119  switch($mode) {
2120  case 'UPDATE':
2121  case DB_AUTOQUERY_UPDATE:
2122  $sql = $this->GetUpdateSQL($rs, $fields_values, $forceUpdate, $magicq);
2123  break;
2124  case 'INSERT':
2125  case DB_AUTOQUERY_INSERT:
2126  $sql = $this->GetInsertSQL($rs, $fields_values, $magicq);
2127  break;
2128  default:
2129  $this->outp_throw("AutoExecute: Unknown mode=$mode", 'AutoExecute');
2130  return false;
2131  }
2132  return $sql && $this->Execute($sql);
2133  }
2134 
2135 
2147  function GetUpdateSQL(&$rs, $arrFields,$forceUpdate=false,$magicq=false,$force=null) {
2148  global $ADODB_INCLUDED_LIB;
2149 
2150  // ********************************************************
2151  // This is here to maintain compatibility
2152  // with older adodb versions. Sets force type to force nulls if $forcenulls is set.
2153  if (!isset($force)) {
2154  global $ADODB_FORCE_TYPE;
2155  $force = $ADODB_FORCE_TYPE;
2156  }
2157  // ********************************************************
2158 
2159  if (empty($ADODB_INCLUDED_LIB)) {
2160  include(ADODB_DIR.'/adodb-lib.inc.php');
2161  }
2162  return _adodb_getupdatesql($this,$rs,$arrFields,$forceUpdate,$magicq,$force);
2163  }
2164 
2173  function GetInsertSQL(&$rs, $arrFields,$magicq=false,$force=null) {
2174  global $ADODB_INCLUDED_LIB;
2175  if (!isset($force)) {
2176  global $ADODB_FORCE_TYPE;
2177  $force = $ADODB_FORCE_TYPE;
2178  }
2179  if (empty($ADODB_INCLUDED_LIB)) {
2180  include(ADODB_DIR.'/adodb-lib.inc.php');
2181  }
2182  return _adodb_getinsertsql($this,$rs,$arrFields,$magicq,$force);
2183  }
2184 
2185 
2204  function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') {
2205  return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false;
2206  }
2207 
2217  function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') {
2218  $fd = fopen($path,'rb');
2219  if ($fd === false) {
2220  return false;
2221  }
2222  $val = fread($fd,filesize($path));
2223  fclose($fd);
2224  return $this->UpdateBlob($table,$column,$val,$where,$blobtype);
2225  }
2226 
2227  function BlobDecode($blob) {
2228  return $blob;
2229  }
2230 
2231  function BlobEncode($blob) {
2232  return $blob;
2233  }
2234 
2235  function GetCharSet() {
2236  return $this->charSet;
2237  }
2238 
2239  function SetCharSet($charset) {
2240  $this->charSet = $charset;
2241  return true;
2242  }
2243 
2244  function IfNull( $field, $ifNull ) {
2245  return " CASE WHEN $field is null THEN $ifNull ELSE $field END ";
2246  }
2247 
2248  function LogSQL($enable=true) {
2249  include_once(ADODB_DIR.'/adodb-perf.inc.php');
2250 
2251  if ($enable) {
2252  $this->fnExecute = 'adodb_log_sql';
2253  } else {
2254  $this->fnExecute = false;
2255  }
2256 
2257  $old = $this->_logsql;
2258  $this->_logsql = $enable;
2259  if ($enable && !$old) {
2260  $this->_affected = false;
2261  }
2262  return $old;
2263  }
2264 
2272  function UpdateClob($table,$column,$val,$where) {
2273  return $this->UpdateBlob($table,$column,$val,$where,'CLOB');
2274  }
2275 
2276  // not the fastest implementation - quick and dirty - jlim
2277  // for best performance, use the actual $rs->MetaType().
2278  function MetaType($t,$len=-1,$fieldobj=false) {
2279 
2280  if (empty($this->_metars)) {
2281  $rsclass = $this->rsPrefix.$this->databaseType;
2282  $this->_metars = new $rsclass(false,$this->fetchMode);
2283  $this->_metars->connection = $this;
2284  }
2285  return $this->_metars->MetaType($t,$len,$fieldobj);
2286  }
2287 
2288 
2293  function SetDateLocale($locale = 'En') {
2294  $this->locale = $locale;
2295  switch (strtoupper($locale))
2296  {
2297  case 'EN':
2298  $this->fmtDate="'Y-m-d'";
2299  $this->fmtTimeStamp = "'Y-m-d H:i:s'";
2300  break;
2301 
2302  case 'US':
2303  $this->fmtDate = "'m-d-Y'";
2304  $this->fmtTimeStamp = "'m-d-Y H:i:s'";
2305  break;
2306 
2307  case 'PT_BR':
2308  case 'NL':
2309  case 'FR':
2310  case 'RO':
2311  case 'IT':
2312  $this->fmtDate="'d-m-Y'";
2313  $this->fmtTimeStamp = "'d-m-Y H:i:s'";
2314  break;
2315 
2316  case 'GE':
2317  $this->fmtDate="'d.m.Y'";
2318  $this->fmtTimeStamp = "'d.m.Y H:i:s'";
2319  break;
2320 
2321  default:
2322  $this->fmtDate="'Y-m-d'";
2323  $this->fmtTimeStamp = "'Y-m-d H:i:s'";
2324  break;
2325  }
2326  }
2327 
2341  function GetActiveRecordsClass(
2342  $class, $table,$whereOrderBy=false,$bindarr=false, $primkeyArr=false,
2343  $extra=array(),
2344  $relations=array())
2345  {
2346  global $_ADODB_ACTIVE_DBS;
2347  ## reduce overhead of adodb.inc.php -- moved to adodb-active-record.inc.php
2348  ## if adodb-active-recordx is loaded -- should be no issue as they will probably use Find()
2349  if (!isset($_ADODB_ACTIVE_DBS)) {
2350  include_once(ADODB_DIR.'/adodb-active-record.inc.php');
2351  }
2352  return adodb_GetActiveRecordsClass($this, $class, $table, $whereOrderBy, $bindarr, $primkeyArr, $extra, $relations);
2353  }
2354 
2355  function GetActiveRecords($table,$where=false,$bindarr=false,$primkeyArr=false) {
2356  $arr = $this->GetActiveRecordsClass('ADODB_Active_Record', $table, $where, $bindarr, $primkeyArr);
2357  return $arr;
2358  }
2359 
2363  function Close() {
2364  $rez = $this->_close();
2365  $this->_connectionID = false;
2366  return $rez;
2367  }
2368 
2374  function BeginTrans() {
2375  if ($this->debug) {
2376  ADOConnection::outp("BeginTrans: Transactions not supported for this driver");
2377  }
2378  return false;
2379  }
2380 
2381  /* set transaction mode */
2382  function SetTransactionMode( $transaction_mode ) {
2383  $transaction_mode = $this->MetaTransaction($transaction_mode, $this->dataProvider);
2384  $this->_transmode = $transaction_mode;
2385  }
2386 /*
2387 http://msdn2.microsoft.com/en-US/ms173763.aspx
2388 http://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-isolation.html
2389 http://www.postgresql.org/docs/8.1/interactive/sql-set-transaction.html
2390 http://www.stanford.edu/dept/itss/docs/oracle/10g/server.101/b10759/statements_10005.htm
2391 */
2392  function MetaTransaction($mode,$db) {
2393  $mode = strtoupper($mode);
2394  $mode = str_replace('ISOLATION LEVEL ','',$mode);
2395 
2396  switch($mode) {
2397 
2398  case 'READ UNCOMMITTED':
2399  switch($db) {
2400  case 'oci8':
2401  case 'oracle':
2402  return 'ISOLATION LEVEL READ COMMITTED';
2403  default:
2404  return 'ISOLATION LEVEL READ UNCOMMITTED';
2405  }
2406  break;
2407 
2408  case 'READ COMMITTED':
2409  return 'ISOLATION LEVEL READ COMMITTED';
2410  break;
2411 
2412  case 'REPEATABLE READ':
2413  switch($db) {
2414  case 'oci8':
2415  case 'oracle':
2416  return 'ISOLATION LEVEL SERIALIZABLE';
2417  default:
2418  return 'ISOLATION LEVEL REPEATABLE READ';
2419  }
2420  break;
2421 
2422  case 'SERIALIZABLE':
2423  return 'ISOLATION LEVEL SERIALIZABLE';
2424  break;
2425 
2426  default:
2427  return $mode;
2428  }
2429  }
2430 
2438  function CommitTrans($ok=true) {
2439  return true;
2440  }
2441 
2442 
2448  function RollbackTrans() {
2449  return false;
2450  }
2451 
2452 
2459  function MetaDatabases() {
2460  global $ADODB_FETCH_MODE;
2461 
2462  if ($this->metaDatabasesSQL) {
2463  $save = $ADODB_FETCH_MODE;
2464  $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
2465 
2466  if ($this->fetchMode !== false) {
2467  $savem = $this->SetFetchMode(false);
2468  }
2469 
2470  $arr = $this->GetCol($this->metaDatabasesSQL);
2471  if (isset($savem)) {
2472  $this->SetFetchMode($savem);
2473  }
2474  $ADODB_FETCH_MODE = $save;
2475 
2476  return $arr;
2477  }
2478 
2479  return false;
2480  }
2481 
2499  function MetaProcedures($procedureNamePattern = null, $catalog = null, $schemaPattern = null) {
2500  return false;
2501  }
2502 
2503 
2514  function MetaTables($ttype=false,$showSchema=false,$mask=false) {
2515  global $ADODB_FETCH_MODE;
2516 
2517  if ($mask) {
2518  return false;
2519  }
2520  if ($this->metaTablesSQL) {
2521  $save = $ADODB_FETCH_MODE;
2522  $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
2523 
2524  if ($this->fetchMode !== false) {
2525  $savem = $this->SetFetchMode(false);
2526  }
2527 
2528  $rs = $this->Execute($this->metaTablesSQL);
2529  if (isset($savem)) {
2530  $this->SetFetchMode($savem);
2531  }
2532  $ADODB_FETCH_MODE = $save;
2533 
2534  if ($rs === false) {
2535  return false;
2536  }
2537  $arr = $rs->GetArray();
2538  $arr2 = array();
2539 
2540  if ($hast = ($ttype && isset($arr[0][1]))) {
2541  $showt = strncmp($ttype,'T',1);
2542  }
2543 
2544  for ($i=0; $i < sizeof($arr); $i++) {
2545  if ($hast) {
2546  if ($showt == 0) {
2547  if (strncmp($arr[$i][1],'T',1) == 0) {
2548  $arr2[] = trim($arr[$i][0]);
2549  }
2550  } else {
2551  if (strncmp($arr[$i][1],'V',1) == 0) {
2552  $arr2[] = trim($arr[$i][0]);
2553  }
2554  }
2555  } else
2556  $arr2[] = trim($arr[$i][0]);
2557  }
2558  $rs->Close();
2559  return $arr2;
2560  }
2561  return false;
2562  }
2563 
2564 
2565  function _findschema(&$table,&$schema) {
2566  if (!$schema && ($at = strpos($table,'.')) !== false) {
2567  $schema = substr($table,0,$at);
2568  $table = substr($table,$at+1);
2569  }
2570  }
2571 
2582  function MetaColumns($table,$normalize=true) {
2583  global $ADODB_FETCH_MODE;
2584 
2585  if (!empty($this->metaColumnsSQL)) {
2586  $schema = false;
2587  $this->_findschema($table,$schema);
2588 
2589  $save = $ADODB_FETCH_MODE;
2590  $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
2591  if ($this->fetchMode !== false) {
2592  $savem = $this->SetFetchMode(false);
2593  }
2594  $rs = $this->Execute(sprintf($this->metaColumnsSQL,($normalize)?strtoupper($table):$table));
2595  if (isset($savem)) {
2596  $this->SetFetchMode($savem);
2597  }
2598  $ADODB_FETCH_MODE = $save;
2599  if ($rs === false || $rs->EOF) {
2600  return false;
2601  }
2602 
2603  $retarr = array();
2604  while (!$rs->EOF) { //print_r($rs->fields);
2605  $fld = new ADOFieldObject();
2606  $fld->name = $rs->fields[0];
2607  $fld->type = $rs->fields[1];
2608  if (isset($rs->fields[3]) && $rs->fields[3]) {
2609  if ($rs->fields[3]>0) {
2610  $fld->max_length = $rs->fields[3];
2611  }
2612  $fld->scale = $rs->fields[4];
2613  if ($fld->scale>0) {
2614  $fld->max_length += 1;
2615  }
2616  } else {
2617  $fld->max_length = $rs->fields[2];
2618  }
2619 
2620  if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) {
2621  $retarr[] = $fld;
2622  } else {
2623  $retarr[strtoupper($fld->name)] = $fld;
2624  }
2625  $rs->MoveNext();
2626  }
2627  $rs->Close();
2628  return $retarr;
2629  }
2630  return false;
2631  }
2632 
2650  function MetaIndexes($table, $primary = false, $owner = false) {
2651  return false;
2652  }
2653 
2660  function MetaColumnNames($table, $numIndexes=false,$useattnum=false /* only for postgres */) {
2661  $objarr = $this->MetaColumns($table);
2662  if (!is_array($objarr)) {
2663  return false;
2664  }
2665  $arr = array();
2666  if ($numIndexes) {
2667  $i = 0;
2668  if ($useattnum) {
2669  foreach($objarr as $v)
2670  $arr[$v->attnum] = $v->name;
2671 
2672  } else
2673  foreach($objarr as $v) $arr[$i++] = $v->name;
2674  } else
2675  foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name;
2676 
2677  return $arr;
2678  }
2679 
2690  function Concat() {
2691  $arr = func_get_args();
2692  return implode($this->concat_operator, $arr);
2693  }
2694 
2695 
2703  function DBDate($d, $isfld=false) {
2704  if (empty($d) && $d !== 0) {
2705  return 'null';
2706  }
2707  if ($isfld) {
2708  return $d;
2709  }
2710  if (is_object($d)) {
2711  return $d->format($this->fmtDate);
2712  }
2713 
2714  if (is_string($d) && !is_numeric($d)) {
2715  if ($d === 'null') {
2716  return $d;
2717  }
2718  if (strncmp($d,"'",1) === 0) {
2719  $d = _adodb_safedateq($d);
2720  return $d;
2721  }
2722  if ($this->isoDates) {
2723  return "'$d'";
2724  }
2725  $d = ADOConnection::UnixDate($d);
2726  }
2727 
2728  return adodb_date($this->fmtDate,$d);
2729  }
2730 
2731  function BindDate($d) {
2732  $d = $this->DBDate($d);
2733  if (strncmp($d,"'",1)) {
2734  return $d;
2735  }
2736 
2737  return substr($d,1,strlen($d)-2);
2738  }
2739 
2740  function BindTimeStamp($d) {
2741  $d = $this->DBTimeStamp($d);
2742  if (strncmp($d,"'",1)) {
2743  return $d;
2744  }
2745 
2746  return substr($d,1,strlen($d)-2);
2747  }
2748 
2749 
2757  function DBTimeStamp($ts,$isfld=false) {
2758  if (empty($ts) && $ts !== 0) {
2759  return 'null';
2760  }
2761  if ($isfld) {
2762  return $ts;
2763  }
2764  if (is_object($ts)) {
2765  return $ts->format($this->fmtTimeStamp);
2766  }
2767 
2768  # strlen(14) allows YYYYMMDDHHMMSS format
2769  if (!is_string($ts) || (is_numeric($ts) && strlen($ts)<14)) {
2770  return adodb_date($this->fmtTimeStamp,$ts);
2771  }
2772 
2773  if ($ts === 'null') {
2774  return $ts;
2775  }
2776  if ($this->isoDates && strlen($ts) !== 14) {
2777  $ts = _adodb_safedate($ts);
2778  return "'$ts'";
2779  }
2780  $ts = ADOConnection::UnixTimeStamp($ts);
2781  return adodb_date($this->fmtTimeStamp,$ts);
2782  }
2783 
2790  static function UnixDate($v) {
2791  if (is_object($v)) {
2792  // odbtp support
2793  //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
2794  return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year);
2795  }
2796 
2797  if (is_numeric($v) && strlen($v) !== 8) {
2798  return $v;
2799  }
2800  if (!preg_match( "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})|", $v, $rr)) {
2801  return false;
2802  }
2803 
2804  if ($rr[1] <= TIMESTAMP_FIRST_YEAR) {
2805  return 0;
2806  }
2807 
2808  // h-m-s-MM-DD-YY
2809  return @adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
2810  }
2811 
2812 
2819  static function UnixTimeStamp($v) {
2820  if (is_object($v)) {
2821  // odbtp support
2822  //( [year] => 2004 [month] => 9 [day] => 4 [hour] => 12 [minute] => 44 [second] => 8 [fraction] => 0 )
2823  return adodb_mktime($v->hour,$v->minute,$v->second,$v->month,$v->day, $v->year);
2824  }
2825 
2826  if (!preg_match(
2827  "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ ,-]*(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
2828  ($v), $rr)) return false;
2829 
2830  if ($rr[1] <= TIMESTAMP_FIRST_YEAR && $rr[2]<= 1) {
2831  return 0;
2832  }
2833 
2834  // h-m-s-MM-DD-YY
2835  if (!isset($rr[5])) {
2836  return adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
2837  }
2838  return @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
2839  }
2840 
2851  function UserDate($v,$fmt='Y-m-d',$gmt=false) {
2852  $tt = $this->UnixDate($v);
2853 
2854  // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
2855  if (($tt === false || $tt == -1) && $v != false) {
2856  return $v;
2857  } else if ($tt == 0) {
2858  return $this->emptyDate;
2859  } else if ($tt == -1) {
2860  // pre-TIMESTAMP_FIRST_YEAR
2861  }
2862 
2863  return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
2864 
2865  }
2866 
2874  function UserTimeStamp($v,$fmt='Y-m-d H:i:s',$gmt=false) {
2875  if (!isset($v)) {
2876  return $this->emptyTimeStamp;
2877  }
2878  # strlen(14) allows YYYYMMDDHHMMSS format
2879  if (is_numeric($v) && strlen($v)<14) {
2880  return ($gmt) ? adodb_gmdate($fmt,$v) : adodb_date($fmt,$v);
2881  }
2882  $tt = $this->UnixTimeStamp($v);
2883  // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
2884  if (($tt === false || $tt == -1) && $v != false) {
2885  return $v;
2886  }
2887  if ($tt == 0) {
2888  return $this->emptyTimeStamp;
2889  }
2890  return ($gmt) ? adodb_gmdate($fmt,$tt) : adodb_date($fmt,$tt);
2891  }
2892 
2893  function escape($s,$magic_quotes=false) {
2894  return $this->addq($s,$magic_quotes);
2895  }
2896 
2900  function addq($s,$magic_quotes=false) {
2901  if (!$magic_quotes) {
2902  if ($this->replaceQuote[0] == '\\') {
2903  // only since php 4.0.5
2904  $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
2905  //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s));
2906  }
2907  return str_replace("'",$this->replaceQuote,$s);
2908  }
2909 
2910  // undo magic quotes for "
2911  $s = str_replace('\\"','"',$s);
2912 
2913  if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) {
2914  // ' already quoted, no need to change anything
2915  return $s;
2916  } else {
2917  // change \' to '' for sybase/mssql
2918  $s = str_replace('\\\\','\\',$s);
2919  return str_replace("\\'",$this->replaceQuote,$s);
2920  }
2921  }
2922 
2934  function qstr($s,$magic_quotes=false) {
2935  if (!$magic_quotes) {
2936  if ($this->replaceQuote[0] == '\\'){
2937  // only since php 4.0.5
2938  $s = adodb_str_replace(array('\\',"\0"),array('\\\\',"\\\0"),$s);
2939  //$s = str_replace("\0","\\\0", str_replace('\\','\\\\',$s));
2940  }
2941  return "'".str_replace("'",$this->replaceQuote,$s)."'";
2942  }
2943 
2944  // undo magic quotes for "
2945  $s = str_replace('\\"','"',$s);
2946 
2947  if ($this->replaceQuote == "\\'" || ini_get('magic_quotes_sybase')) {
2948  // ' already quoted, no need to change anything
2949  return "'$s'";
2950  } else {
2951  // change \' to '' for sybase/mssql
2952  $s = str_replace('\\\\','\\',$s);
2953  return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
2954  }
2955  }
2956 
2957 
2975  function PageExecute($sql, $nrows, $page, $inputarr=false, $secs2cache=0) {
2976  global $ADODB_INCLUDED_LIB;
2977  if (empty($ADODB_INCLUDED_LIB)) {
2978  include(ADODB_DIR.'/adodb-lib.inc.php');
2979  }
2980  if ($this->pageExecuteCountRows) {
2981  $rs = _adodb_pageexecute_all_rows($this, $sql, $nrows, $page, $inputarr, $secs2cache);
2982  } else {
2983  $rs = _adodb_pageexecute_no_last_page($this, $sql, $nrows, $page, $inputarr, $secs2cache);
2984  }
2985  return $rs;
2986  }
2987 
2988 
3001  function CachePageExecute($secs2cache, $sql, $nrows, $page,$inputarr=false) {
3002  /*switch($this->dataProvider) {
3003  case 'postgres':
3004  case 'mysql':
3005  break;
3006  default: $secs2cache = 0; break;
3007  }*/
3008  $rs = $this->PageExecute($sql,$nrows,$page,$inputarr,$secs2cache);
3009  return $rs;
3010  }
3011 
3012 } // end class ADOConnection
3013 
3014 
3015 
3016  //==============================================================================================
3017  // CLASS ADOFetchObj
3018  //==============================================================================================
3019 
3023  class ADOFetchObj {
3024  };
3025 
3026  //==============================================================================================
3027  // CLASS ADORecordSet_empty
3028  //==============================================================================================
3029 
3030  class ADODB_Iterator_empty implements Iterator {
3031 
3032  private $rs;
3033 
3034  function __construct($rs) {
3035  $this->rs = $rs;
3036  }
3037 
3038  function rewind() {}
3039 
3040  function valid() {
3041  return !$this->rs->EOF;
3042  }
3043 
3044  function key() {
3045  return false;
3046  }
3047 
3048  function current() {
3049  return false;
3050  }
3051 
3052  function next() {}
3053 
3054  function __call($func, $params) {
3055  return call_user_func_array(array($this->rs, $func), $params);
3056  }
3057 
3058  function hasMore() {
3059  return false;
3060  }
3061 
3062  }
3063 
3064 
3068  class ADORecordSet_empty implements IteratorAggregate
3069  {
3070  var $dataProvider = 'empty';
3071  var $databaseType = false;
3072  var $EOF = true;
3073  var $_numOfRows = 0;
3074  var $fields = false;
3075  var $connection = false;
3076 
3077  function RowCount() {
3078  return 0;
3079  }
3080 
3081  function RecordCount() {
3082  return 0;
3083  }
3084 
3085  function PO_RecordCount() {
3086  return 0;
3087  }
3088 
3089  function Close() {
3090  return true;
3091  }
3092 
3093  function FetchRow() {
3094  return false;
3095  }
3096 
3097  function FieldCount() {
3098  return 0;
3099  }
3100 
3101  function Init() {}
3102 
3103  function getIterator() {
3104  return new ADODB_Iterator_empty($this);
3105  }
3106 
3107  function GetAssoc() {
3108  return array();
3109  }
3110 
3111  function GetArray() {
3112  return array();
3113  }
3114 
3115  function GetAll() {
3116  return array();
3117  }
3118 
3119  function GetArrayLimit() {
3120  return array();
3121  }
3122 
3123  function GetRows() {
3124  return array();
3125  }
3126 
3127  function GetRowAssoc() {
3128  return array();
3129  }
3130 
3131  function MaxRecordCount() {
3132  return 0;
3133  }
3134 
3135  function NumRows() {
3136  return 0;
3137  }
3138 
3139  function NumCols() {
3140  return 0;
3141  }
3142  }
3143 
3144  //==============================================================================================
3145  // DATE AND TIME FUNCTIONS
3146  //==============================================================================================
3147  if (!defined('ADODB_DATE_VERSION')) {
3148  include(ADODB_DIR.'/adodb-time.inc.php');
3149  }
3150 
3151  //==============================================================================================
3152  // CLASS ADORecordSet
3153  //==============================================================================================
3154 
3155  class ADODB_Iterator implements Iterator {
3156 
3157  private $rs;
3158 
3159  function __construct($rs) {
3160  $this->rs = $rs;
3161  }
3162 
3163  function rewind() {
3164  $this->rs->MoveFirst();
3165  }
3166 
3167  function valid() {
3168  return !$this->rs->EOF;
3169  }
3170 
3171  function key() {
3172  return $this->rs->_currentRow;
3173  }
3174 
3175  function current() {
3176  return $this->rs->fields;
3177  }
3178 
3179  function next() {
3180  $this->rs->MoveNext();
3181  }
3182 
3183  function __call($func, $params) {
3184  return call_user_func_array(array($this->rs, $func), $params);
3185  }
3186 
3187  function hasMore() {
3188  return !$this->rs->EOF;
3189  }
3190 
3191  }
3192 
3193 
3200  class ADORecordSet implements IteratorAggregate {
3201 
3205  var $dataProvider = "native";
3206  var $fields = false;
3207  var $blobSize = 100;
3208  var $canSeek = false;
3210  var $sql;
3211  var $EOF = false;
3212 
3213  var $emptyTimeStamp = '&nbsp;';
3214  var $emptyDate = '&nbsp;';
3215  var $debug = false;
3216  var $timeCreated=0;
3217 
3218  var $bind = false;
3219  var $fetchMode;
3220  var $connection = false;
3221 
3225  var $_numOfRows = -1;
3226  var $_numOfFields = -1;
3227  var $_queryID = -1;
3228  var $_currentRow = -1;
3229  var $_closed = false;
3230  var $_inited = false;
3231  var $_obj;
3232  var $_names;
3234  var $_currentPage = -1;
3235  var $_atFirstPage = false;
3236  var $_atLastPage = false;
3237  var $_lastPageNo = -1;
3238  var $_maxRecordCount = 0;
3239  var $datetime = false;
3240 
3247  function __construct($queryID) {
3248  $this->_queryID = $queryID;
3249  }
3250 
3251  function __destruct() {
3252  $this->Close();
3253  }
3254 
3255  function getIterator() {
3256  return new ADODB_Iterator($this);
3257  }
3258 
3259  /* this is experimental - i don't really know what to return... */
3260  function __toString() {
3261  include_once(ADODB_DIR.'/toexport.inc.php');
3262  return _adodb_export($this,',',',',false,true);
3263  }
3264 
3265  function Init() {
3266  if ($this->_inited) {
3267  return;
3268  }
3269  $this->_inited = true;
3270  if ($this->_queryID) {
3271  @$this->_initrs();
3272  } else {
3273  $this->_numOfRows = 0;
3274  $this->_numOfFields = 0;
3275  }
3276  if ($this->_numOfRows != 0 && $this->_numOfFields && $this->_currentRow == -1) {
3277  $this->_currentRow = 0;
3278  if ($this->EOF = ($this->_fetch() === false)) {
3279  $this->_numOfRows = 0; // _numOfRows could be -1
3280  }
3281  } else {
3282  $this->EOF = true;
3283  }
3284  }
3285 
3286 
3307  function GetMenu($name,$defstr='',$blank1stItem=true,$multiple=false,
3308  $size=0, $selectAttr='',$compareFields0=true)
3309  {
3310  global $ADODB_INCLUDED_LIB;
3311  if (empty($ADODB_INCLUDED_LIB)) {
3312  include(ADODB_DIR.'/adodb-lib.inc.php');
3313  }
3314  return _adodb_getmenu($this, $name,$defstr,$blank1stItem,$multiple,
3315  $size, $selectAttr,$compareFields0);
3316  }
3317 
3318 
3319 
3327  function GetMenu2($name,$defstr='',$blank1stItem=true,$multiple=false,$size=0, $selectAttr='') {
3328  return $this->GetMenu($name,$defstr,$blank1stItem,$multiple,
3329  $size, $selectAttr,false);
3330  }
3331 
3332  /*
3333  Grouped Menu
3334  */
3335  function GetMenu3($name,$defstr='',$blank1stItem=true,$multiple=false,
3336  $size=0, $selectAttr='')
3337  {
3338  global $ADODB_INCLUDED_LIB;
3339  if (empty($ADODB_INCLUDED_LIB)) {
3340  include(ADODB_DIR.'/adodb-lib.inc.php');
3341  }
3342  return _adodb_getmenu_gp($this, $name,$defstr,$blank1stItem,$multiple,
3343  $size, $selectAttr,false);
3344  }
3345 
3353  function GetArray($nRows = -1) {
3354  global $ADODB_EXTENSION; if ($ADODB_EXTENSION) {
3355  $results = adodb_getall($this,$nRows);
3356  return $results;
3357  }
3358  $results = array();
3359  $cnt = 0;
3360  while (!$this->EOF && $nRows != $cnt) {
3361  $results[] = $this->fields;
3362  $this->MoveNext();
3363  $cnt++;
3364  }
3365  return $results;
3366  }
3367 
3368  function GetAll($nRows = -1) {
3369  $arr = $this->GetArray($nRows);
3370  return $arr;
3371  }
3372 
3373  /*
3374  * Some databases allow multiple recordsets to be returned. This function
3375  * will return true if there is a next recordset, or false if no more.
3376  */
3377  function NextRecordSet() {
3378  return false;
3379  }
3380 
3390  function GetArrayLimit($nrows,$offset=-1) {
3391  if ($offset <= 0) {
3392  $arr = $this->GetArray($nrows);
3393  return $arr;
3394  }
3395 
3396  $this->Move($offset);
3397 
3398  $results = array();
3399  $cnt = 0;
3400  while (!$this->EOF && $nrows != $cnt) {
3401  $results[$cnt++] = $this->fields;
3402  $this->MoveNext();
3403  }
3404 
3405  return $results;
3406  }
3407 
3408 
3416  function GetRows($nRows = -1) {
3417  $arr = $this->GetArray($nRows);
3418  return $arr;
3419  }
3420 
3437  function GetAssoc($force_array = false, $first2cols = false) {
3438  global $ADODB_EXTENSION;
3439 
3440  $cols = $this->_numOfFields;
3441  if ($cols < 2) {
3442  return false;
3443  }
3444 
3445  // Empty recordset
3446  if (!$this->fields) {
3447  return array();
3448  }
3449 
3450  // Determine whether the array is associative or 0-based numeric
3451  $numIndex = array_keys($this->fields) == range(0, count($this->fields) - 1);
3452 
3453  $results = array();
3454 
3455  if (!$first2cols && ($cols > 2 || $force_array)) {
3456  if ($ADODB_EXTENSION) {
3457  if ($numIndex) {
3458  while (!$this->EOF) {
3459  $results[trim($this->fields[0])] = array_slice($this->fields, 1);
3460  adodb_movenext($this);
3461  }
3462  } else {
3463  while (!$this->EOF) {
3464  // Fix for array_slice re-numbering numeric associative keys
3465  $keys = array_slice(array_keys($this->fields), 1);
3466  $sliced_array = array();
3467 
3468  foreach($keys as $key) {
3469  $sliced_array[$key] = $this->fields[$key];
3470  }
3471 
3472  $results[trim(reset($this->fields))] = $sliced_array;
3473  adodb_movenext($this);
3474  }
3475  }
3476  } else {
3477  if ($numIndex) {
3478  while (!$this->EOF) {
3479  $results[trim($this->fields[0])] = array_slice($this->fields, 1);
3480  $this->MoveNext();
3481  }
3482  } else {
3483  while (!$this->EOF) {
3484  // Fix for array_slice re-numbering numeric associative keys
3485  $keys = array_slice(array_keys($this->fields), 1);
3486  $sliced_array = array();
3487 
3488  foreach($keys as $key) {
3489  $sliced_array[$key] = $this->fields[$key];
3490  }
3491 
3492  $results[trim(reset($this->fields))] = $sliced_array;
3493  $this->MoveNext();
3494  }
3495  }
3496  }
3497  } else {
3498  if ($ADODB_EXTENSION) {
3499  // return scalar values
3500  if ($numIndex) {
3501  while (!$this->EOF) {
3502  // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
3503  $results[trim(($this->fields[0]))] = $this->fields[1];
3504  adodb_movenext($this);
3505  }
3506  } else {
3507  while (!$this->EOF) {
3508  // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
3509  $v1 = trim(reset($this->fields));
3510  $v2 = ''.next($this->fields);
3511  $results[$v1] = $v2;
3512  adodb_movenext($this);
3513  }
3514  }
3515  } else {
3516  if ($numIndex) {
3517  while (!$this->EOF) {
3518  // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
3519  $results[trim(($this->fields[0]))] = $this->fields[1];
3520  $this->MoveNext();
3521  }
3522  } else {
3523  while (!$this->EOF) {
3524  // some bug in mssql PHP 4.02 -- doesn't handle references properly so we FORCE creating a new string
3525  $v1 = trim(reset($this->fields));
3526  $v2 = ''.next($this->fields);
3527  $results[$v1] = $v2;
3528  $this->MoveNext();
3529  }
3530  }
3531  }
3532  }
3533 
3534  $ref = $results; # workaround accelerator incompat with PHP 4.4 :(
3535  return $ref;
3536  }
3537 
3538 
3546  function UserTimeStamp($v,$fmt='Y-m-d H:i:s') {
3547  if (is_numeric($v) && strlen($v)<14) {
3548  return adodb_date($fmt,$v);
3549  }
3550  $tt = $this->UnixTimeStamp($v);
3551  // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
3552  if (($tt === false || $tt == -1) && $v != false) {
3553  return $v;
3554  }
3555  if ($tt === 0) {
3556  return $this->emptyTimeStamp;
3557  }
3558  return adodb_date($fmt,$tt);
3559  }
3560 
3561 
3568  function UserDate($v,$fmt='Y-m-d') {
3569  $tt = $this->UnixDate($v);
3570  // $tt == -1 if pre TIMESTAMP_FIRST_YEAR
3571  if (($tt === false || $tt == -1) && $v != false) {
3572  return $v;
3573  } else if ($tt == 0) {
3574  return $this->emptyDate;
3575  } else if ($tt == -1) {
3576  // pre-TIMESTAMP_FIRST_YEAR
3577  }
3578  return adodb_date($fmt,$tt);
3579  }
3580 
3581 
3587  static function UnixDate($v) {
3588  return ADOConnection::UnixDate($v);
3589  }
3590 
3591 
3597  static function UnixTimeStamp($v) {
3598  return ADOConnection::UnixTimeStamp($v);
3599  }
3600 
3601 
3605  function Free() {
3606  return $this->Close();
3607  }
3608 
3609 
3613  function NumRows() {
3614  return $this->_numOfRows;
3615  }
3616 
3617 
3621  function NumCols() {
3622  return $this->_numOfFields;
3623  }
3624 
3631  function FetchRow() {
3632  if ($this->EOF) {
3633  return false;
3634  }
3635  $arr = $this->fields;
3636  $this->_currentRow++;
3637  if (!$this->_fetch()) {
3638  $this->EOF = true;
3639  }
3640  return $arr;
3641  }
3642 
3643 
3650  function FetchInto(&$arr) {
3651  if ($this->EOF) {
3652  return (defined('PEAR_ERROR_RETURN')) ? new PEAR_Error('EOF',-1): false;
3653  }
3654  $arr = $this->fields;
3655  $this->MoveNext();
3656  return 1; // DB_OK
3657  }
3658 
3659 
3665  function MoveFirst() {
3666  if ($this->_currentRow == 0) {
3667  return true;
3668  }
3669  return $this->Move(0);
3670  }
3671 
3672 
3678  function MoveLast() {
3679  if ($this->_numOfRows >= 0) {
3680  return $this->Move($this->_numOfRows-1);
3681  }
3682  if ($this->EOF) {
3683  return false;
3684  }
3685  while (!$this->EOF) {
3686  $f = $this->fields;
3687  $this->MoveNext();
3688  }
3689  $this->fields = $f;
3690  $this->EOF = false;
3691  return true;
3692  }
3693 
3694 
3700  function MoveNext() {
3701  if (!$this->EOF) {
3702  $this->_currentRow++;
3703  if ($this->_fetch()) {
3704  return true;
3705  }
3706  }
3707  $this->EOF = true;
3708  /* -- tested error handling when scrolling cursor -- seems useless.
3709  $conn = $this->connection;
3710  if ($conn && $conn->raiseErrorFn && ($errno = $conn->ErrorNo())) {
3711  $fn = $conn->raiseErrorFn;
3712  $fn($conn->databaseType,'MOVENEXT',$errno,$conn->ErrorMsg().' ('.$this->sql.')',$conn->host,$conn->database);
3713  }
3714  */
3715  return false;
3716  }
3717 
3718 
3727  function Move($rowNumber = 0) {
3728  $this->EOF = false;
3729  if ($rowNumber == $this->_currentRow) {
3730  return true;
3731  }
3732  if ($rowNumber >= $this->_numOfRows) {
3733  if ($this->_numOfRows != -1) {
3734  $rowNumber = $this->_numOfRows-2;
3735  }
3736  }
3737 
3738  if ($rowNumber < 0) {
3739  $this->EOF = true;
3740  return false;
3741  }
3742 
3743  if ($this->canSeek) {
3744  if ($this->_seek($rowNumber)) {
3745  $this->_currentRow = $rowNumber;
3746  if ($this->_fetch()) {
3747  return true;
3748  }
3749  } else {
3750  $this->EOF = true;
3751  return false;
3752  }
3753  } else {
3754  if ($rowNumber < $this->_currentRow) {
3755  return false;
3756  }
3757  global $ADODB_EXTENSION;
3758  if ($ADODB_EXTENSION) {
3759  while (!$this->EOF && $this->_currentRow < $rowNumber) {
3760  adodb_movenext($this);
3761  }
3762  } else {
3763  while (! $this->EOF && $this->_currentRow < $rowNumber) {
3764  $this->_currentRow++;
3765 
3766  if (!$this->_fetch()) {
3767  $this->EOF = true;
3768  }
3769  }
3770  }
3771  return !($this->EOF);
3772  }
3773 
3774  $this->fields = false;
3775  $this->EOF = true;
3776  return false;
3777  }
3778 
3779 
3788  function Fields($colname) {
3789  return $this->fields[$colname];
3790  }
3791 
3797  protected function AssocCaseConvertFunction($case = ADODB_ASSOC_CASE) {
3798  switch($case) {
3799  case ADODB_ASSOC_CASE_UPPER:
3800  return 'strtoupper';
3801  case ADODB_ASSOC_CASE_LOWER:
3802  return 'strtolower';
3803  case ADODB_ASSOC_CASE_NATIVE:
3804  default:
3805  return false;
3806  }
3807  }
3808 
3815  function GetAssocKeys($upper = ADODB_ASSOC_CASE) {
3816  if ($this->bind) {
3817  return;
3818  }
3819  $this->bind = array();
3820 
3821  // Define case conversion function for ASSOC fetch mode
3822  $fn_change_case = $this->AssocCaseConvertFunction($upper);
3823 
3824  // Build the bind array
3825  for ($i=0; $i < $this->_numOfFields; $i++) {
3826  $o = $this->FetchField($i);
3827 
3828  // Set the array's key
3829  if(is_numeric($o->name)) {
3830  // Just use the field ID
3831  $key = $i;
3832  }
3833  elseif( $fn_change_case ) {
3834  // Convert the key's case
3835  $key = $fn_change_case($o->name);
3836  }
3837  else {
3838  $key = $o->name;
3839  }
3840 
3841  $this->bind[$key] = $i;
3842  }
3843  }
3844 
3852  function GetRowAssoc($upper = ADODB_ASSOC_CASE) {
3853  $record = array();
3854  $this->GetAssocKeys($upper);
3855 
3856  foreach($this->bind as $k => $v) {
3857  if( array_key_exists( $v, $this->fields ) ) {
3858  $record[$k] = $this->fields[$v];
3859  } elseif( array_key_exists( $k, $this->fields ) ) {
3860  $record[$k] = $this->fields[$k];
3861  } else {
3862  # This should not happen... trigger error ?
3863  $record[$k] = null;
3864  }
3865  }
3866  return $record;
3867  }
3868 
3874  function Close() {
3875  // free connection object - this seems to globally free the object
3876  // and not merely the reference, so don't do this...
3877  // $this->connection = false;
3878  if (!$this->_closed) {
3879  $this->_closed = true;
3880  return $this->_close();
3881  } else
3882  return true;
3883  }
3884 
3890  function RecordCount() {
3891  return $this->_numOfRows;
3892  }
3893 
3894 
3895  /*
3896  * If we are using PageExecute(), this will return the maximum possible rows
3897  * that can be returned when paging a recordset.
3898  */
3899  function MaxRecordCount() {
3900  return ($this->_maxRecordCount) ? $this->_maxRecordCount : $this->RecordCount();
3901  }
3902 
3908  function RowCount() {
3909  return $this->_numOfRows;
3910  }
3911 
3912 
3921  function PO_RecordCount($table="", $condition="") {
3922 
3923  $lnumrows = $this->_numOfRows;
3924  // the database doesn't support native recordcount, so we do a workaround
3925  if ($lnumrows == -1 && $this->connection) {
3926  IF ($table) {
3927  if ($condition) {
3928  $condition = " WHERE " . $condition;
3929  }
3930  $resultrows = $this->connection->Execute("SELECT COUNT(*) FROM $table $condition");
3931  if ($resultrows) {
3932  $lnumrows = reset($resultrows->fields);
3933  }
3934  }
3935  }
3936  return $lnumrows;
3937  }
3938 
3939 
3943  function CurrentRow() {
3944  return $this->_currentRow;
3945  }
3946 
3952  function AbsolutePosition() {
3953  return $this->_currentRow;
3954  }
3955 
3960  function FieldCount() {
3961  return $this->_numOfFields;
3962  }
3963 
3964 
3972  function FetchField($fieldoffset = -1) {
3973  // must be defined by child class
3974 
3975  return false;
3976  }
3977 
3982  function FieldTypesArray() {
3983  $arr = array();
3984  for ($i=0, $max=$this->_numOfFields; $i < $max; $i++)
3985  $arr[] = $this->FetchField($i);
3986  return $arr;
3987  }
3988 
3995  function FetchObj() {
3996  $o = $this->FetchObject(false);
3997  return $o;
3998  }
3999 
4008  function FetchObject($isupper=true) {
4009  if (empty($this->_obj)) {
4010  $this->_obj = new ADOFetchObj();
4011  $this->_names = array();
4012  for ($i=0; $i <$this->_numOfFields; $i++) {
4013  $f = $this->FetchField($i);
4014  $this->_names[] = $f->name;
4015  }
4016  }
4017  $i = 0;
4018  if (PHP_VERSION >= 5) {
4019  $o = clone($this->_obj);
4020  } else {
4021  $o = $this->_obj;
4022  }
4023 
4024  for ($i=0; $i <$this->_numOfFields; $i++) {
4025  $name = $this->_names[$i];
4026  if ($isupper) {
4027  $n = strtoupper($name);
4028  } else {
4029  $n = $name;
4030  }
4031 
4032  $o->$n = $this->Fields($name);
4033  }
4034  return $o;
4035  }
4036 
4046  function FetchNextObj() {
4047  $o = $this->FetchNextObject(false);
4048  return $o;
4049  }
4050 
4051 
4063  function FetchNextObject($isupper=true) {
4064  $o = false;
4065  if ($this->_numOfRows != 0 && !$this->EOF) {
4066  $o = $this->FetchObject($isupper);
4067  $this->_currentRow++;
4068  if ($this->_fetch()) {
4069  return $o;
4070  }
4071  }
4072  $this->EOF = true;
4073  return $o;
4074  }
4075 
4100  function MetaType($t,$len=-1,$fieldobj=false) {
4101  if (is_object($t)) {
4102  $fieldobj = $t;
4103  $t = $fieldobj->type;
4104  $len = $fieldobj->max_length;
4105  }
4106 
4107  // changed in 2.32 to hashing instead of switch stmt for speed...
4108  static $typeMap = array(
4109  'VARCHAR' => 'C',
4110  'VARCHAR2' => 'C',
4111  'CHAR' => 'C',
4112  'C' => 'C',
4113  'STRING' => 'C',
4114  'NCHAR' => 'C',
4115  'NVARCHAR' => 'C',
4116  'VARYING' => 'C',
4117  'BPCHAR' => 'C',
4118  'CHARACTER' => 'C',
4119  'INTERVAL' => 'C', # Postgres
4120  'MACADDR' => 'C', # postgres
4121  'VAR_STRING' => 'C', # mysql
4122  ##
4123  'LONGCHAR' => 'X',
4124  'TEXT' => 'X',
4125  'NTEXT' => 'X',
4126  'M' => 'X',
4127  'X' => 'X',
4128  'CLOB' => 'X',
4129  'NCLOB' => 'X',
4130  'LVARCHAR' => 'X',
4131  ##
4132  'BLOB' => 'B',
4133  'IMAGE' => 'B',
4134  'BINARY' => 'B',
4135  'VARBINARY' => 'B',
4136  'LONGBINARY' => 'B',
4137  'B' => 'B',
4138  ##
4139  'YEAR' => 'D', // mysql
4140  'DATE' => 'D',
4141  'D' => 'D',
4142  ##
4143  'UNIQUEIDENTIFIER' => 'C', # MS SQL Server
4144  ##
4145  'SMALLDATETIME' => 'T',
4146  'TIME' => 'T',
4147  'TIMESTAMP' => 'T',
4148  'DATETIME' => 'T',
4149  'DATETIME2' => 'T',
4150  'TIMESTAMPTZ' => 'T',
4151  'T' => 'T',
4152  'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
4153  ##
4154  'BOOL' => 'L',
4155  'BOOLEAN' => 'L',
4156  'BIT' => 'L',
4157  'L' => 'L',
4158  ##
4159  'COUNTER' => 'R',
4160  'R' => 'R',
4161  'SERIAL' => 'R', // ifx
4162  'INT IDENTITY' => 'R',
4163  ##
4164  'INT' => 'I',
4165  'INT2' => 'I',
4166  'INT4' => 'I',
4167  'INT8' => 'I',
4168  'INTEGER' => 'I',
4169  'INTEGER UNSIGNED' => 'I',
4170  'SHORT' => 'I',
4171  'TINYINT' => 'I',
4172  'SMALLINT' => 'I',
4173  'I' => 'I',
4174  ##
4175  'LONG' => 'N', // interbase is numeric, oci8 is blob
4176  'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
4177  'DECIMAL' => 'N',
4178  'DEC' => 'N',
4179  'REAL' => 'N',
4180  'DOUBLE' => 'N',
4181  'DOUBLE PRECISION' => 'N',
4182  'SMALLFLOAT' => 'N',
4183  'FLOAT' => 'N',
4184  'NUMBER' => 'N',
4185  'NUM' => 'N',
4186  'NUMERIC' => 'N',
4187  'MONEY' => 'N',
4188 
4189  ## informix 9.2
4190  'SQLINT' => 'I',
4191  'SQLSERIAL' => 'I',
4192  'SQLSMINT' => 'I',
4193  'SQLSMFLOAT' => 'N',
4194  'SQLFLOAT' => 'N',
4195  'SQLMONEY' => 'N',
4196  'SQLDECIMAL' => 'N',
4197  'SQLDATE' => 'D',
4198  'SQLVCHAR' => 'C',
4199  'SQLCHAR' => 'C',
4200  'SQLDTIME' => 'T',
4201  'SQLINTERVAL' => 'N',
4202  'SQLBYTES' => 'B',
4203  'SQLTEXT' => 'X',
4204  ## informix 10
4205  "SQLINT8" => 'I8',
4206  "SQLSERIAL8" => 'I8',
4207  "SQLNCHAR" => 'C',
4208  "SQLNVCHAR" => 'C',
4209  "SQLLVARCHAR" => 'X',
4210  "SQLBOOL" => 'L'
4211  );
4212 
4213  $tmap = false;
4214  $t = strtoupper($t);
4215  $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N';
4216  switch ($tmap) {
4217  case 'C':
4218  // is the char field is too long, return as text field...
4219  if ($this->blobSize >= 0) {
4220  if ($len > $this->blobSize) {
4221  return 'X';
4222  }
4223  } else if ($len > 250) {
4224  return 'X';
4225  }
4226  return 'C';
4227 
4228  case 'I':
4229  if (!empty($fieldobj->primary_key)) {
4230  return 'R';
4231  }
4232  return 'I';
4233 
4234  case false:
4235  return 'N';
4236 
4237  case 'B':
4238  if (isset($fieldobj->binary)) {
4239  return ($fieldobj->binary) ? 'B' : 'X';
4240  }
4241  return 'B';
4242 
4243  case 'D':
4244  if (!empty($this->connection) && !empty($this->connection->datetime)) {
4245  return 'T';
4246  }
4247  return 'D';
4248 
4249  default:
4250  if ($t == 'LONG' && $this->dataProvider == 'oci8') {
4251  return 'B';
4252  }
4253  return $tmap;
4254  }
4255  }
4256 
4261  protected function _updatefields()
4262  {
4263  if( empty($this->fields)) {
4264  return;
4265  }
4266 
4267  // Determine case conversion function
4268  $fn_change_case = $this->AssocCaseConvertFunction();
4269  if(!$fn_change_case) {
4270  // No conversion needed
4271  return;
4272  }
4273 
4274  $arr = array();
4275 
4276  // Change the case
4277  foreach($this->fields as $k => $v) {
4278  if (!is_integer($k)) {
4279  $k = $fn_change_case($k);
4280  }
4281  $arr[$k] = $v;
4282  }
4283  $this->fields = $arr;
4284  }
4285 
4286  function _close() {}
4287 
4291  function AbsolutePage($page=-1) {
4292  if ($page != -1) {
4293  $this->_currentPage = $page;
4294  }
4295  return $this->_currentPage;
4296  }
4297 
4301  function AtFirstPage($status=false) {
4302  if ($status != false) {
4303  $this->_atFirstPage = $status;
4304  }
4305  return $this->_atFirstPage;
4306  }
4307 
4308  function LastPageNo($page = false) {
4309  if ($page != false) {
4310  $this->_lastPageNo = $page;
4311  }
4312  return $this->_lastPageNo;
4313  }
4314 
4318  function AtLastPage($status=false) {
4319  if ($status != false) {
4320  $this->_atLastPage = $status;
4321  }
4322  return $this->_atLastPage;
4323  }
4324 
4325 } // end class ADORecordSet
4326 
4327  //==============================================================================================
4328  // CLASS ADORecordSet_array
4329  //==============================================================================================
4330 
4337  class ADORecordSet_array extends ADORecordSet
4338  {
4339  var $databaseType = 'array';
4340 
4341  var $_array; // holds the 2-dimensional data array
4342  var $_types; // the array of types of each column (C B I L M)
4343  var $_colnames; // names of each column in array
4344  var $_skiprow1; // skip 1st row because it holds column names
4345  var $_fieldobjects; // holds array of field objects
4346  var $canSeek = true;
4347  var $affectedrows = false;
4348  var $insertid = false;
4349  var $sql = '';
4350  var $compat = false;
4351 
4355  function __construct($fakeid=1) {
4356  global $ADODB_FETCH_MODE,$ADODB_COMPAT_FETCH;
4357 
4358  // fetch() on EOF does not delete $this->fields
4359  $this->compat = !empty($ADODB_COMPAT_FETCH);
4360  parent::__construct($fakeid); // fake queryID
4361  $this->fetchMode = $ADODB_FETCH_MODE;
4362  }
4363 
4364  function _transpose($addfieldnames=true) {
4365  global $ADODB_INCLUDED_LIB;
4366 
4367  if (empty($ADODB_INCLUDED_LIB)) {
4368  include(ADODB_DIR.'/adodb-lib.inc.php');
4369  }
4370  $hdr = true;
4371 
4372  $fobjs = $addfieldnames ? $this->_fieldobjects : false;
4373  adodb_transpose($this->_array, $newarr, $hdr, $fobjs);
4374  //adodb_pr($newarr);
4375 
4376  $this->_skiprow1 = false;
4377  $this->_array = $newarr;
4378  $this->_colnames = $hdr;
4379 
4380  adodb_probetypes($newarr,$this->_types);
4381 
4382  $this->_fieldobjects = array();
4383 
4384  foreach($hdr as $k => $name) {
4385  $f = new ADOFieldObject();
4386  $f->name = $name;
4387  $f->type = $this->_types[$k];
4388  $f->max_length = -1;
4389  $this->_fieldobjects[] = $f;
4390  }
4391  $this->fields = reset($this->_array);
4392 
4393  $this->_initrs();
4394 
4395  }
4396 
4408  function InitArray($array,$typearr,$colnames=false) {
4409  $this->_array = $array;
4410  $this->_types = $typearr;
4411  if ($colnames) {
4412  $this->_skiprow1 = false;
4413  $this->_colnames = $colnames;
4414  } else {
4415  $this->_skiprow1 = true;
4416  $this->_colnames = $array[0];
4417  }
4418  $this->Init();
4419  }
4428  function InitArrayFields(&$array,&$fieldarr) {
4429  $this->_array = $array;
4430  $this->_skiprow1= false;
4431  if ($fieldarr) {
4432  $this->_fieldobjects = $fieldarr;
4433  }
4434  $this->Init();
4435  }
4436 
4437  function GetArray($nRows=-1) {
4438  if ($nRows == -1 && $this->_currentRow <= 0 && !$this->_skiprow1) {
4439  return $this->_array;
4440  } else {
4441  $arr = ADORecordSet::GetArray($nRows);
4442  return $arr;
4443  }
4444  }
4445 
4446  function _initrs() {
4447  $this->_numOfRows = sizeof($this->_array);
4448  if ($this->_skiprow1) {
4449  $this->_numOfRows -= 1;
4450  }
4451 
4452  $this->_numOfFields = (isset($this->_fieldobjects))
4453  ? sizeof($this->_fieldobjects)
4454  : sizeof($this->_types);
4455  }
4456 
4457  /* Use associative array to get fields array */
4458  function Fields($colname) {
4459  $mode = isset($this->adodbFetchMode) ? $this->adodbFetchMode : $this->fetchMode;
4460 
4461  if ($mode & ADODB_FETCH_ASSOC) {
4462  if (!isset($this->fields[$colname]) && !is_null($this->fields[$colname])) {
4463  $colname = strtolower($colname);
4464  }
4465  return $this->fields[$colname];
4466  }
4467  if (!$this->bind) {
4468  $this->bind = array();
4469  for ($i=0; $i < $this->_numOfFields; $i++) {
4470  $o = $this->FetchField($i);
4471  $this->bind[strtoupper($o->name)] = $i;
4472  }
4473  }
4474  return $this->fields[$this->bind[strtoupper($colname)]];
4475  }
4476 
4477  function FetchField($fieldOffset = -1) {
4478  if (isset($this->_fieldobjects)) {
4479  return $this->_fieldobjects[$fieldOffset];
4480  }
4481  $o = new ADOFieldObject();
4482  $o->name = $this->_colnames[$fieldOffset];
4483  $o->type = $this->_types[$fieldOffset];
4484  $o->max_length = -1; // length not known
4485 
4486  return $o;
4487  }
4488 
4489  function _seek($row) {
4490  if (sizeof($this->_array) && 0 <= $row && $row < $this->_numOfRows) {
4491  $this->_currentRow = $row;
4492  if ($this->_skiprow1) {
4493  $row += 1;
4494  }
4495  $this->fields = $this->_array[$row];
4496  return true;
4497  }
4498  return false;
4499  }
4500 
4501  function MoveNext() {
4502  if (!$this->EOF) {
4503  $this->_currentRow++;
4504 
4505  $pos = $this->_currentRow;
4506 
4507  if ($this->_numOfRows <= $pos) {
4508  if (!$this->compat) {
4509  $this->fields = false;
4510  }
4511  } else {
4512  if ($this->_skiprow1) {
4513  $pos += 1;
4514  }
4515  $this->fields = $this->_array[$pos];
4516  return true;
4517  }
4518  $this->EOF = true;
4519  }
4520 
4521  return false;
4522  }
4523 
4524  function _fetch() {
4525  $pos = $this->_currentRow;
4526 
4527  if ($this->_numOfRows <= $pos) {
4528  if (!$this->compat) {
4529  $this->fields = false;
4530  }
4531  return false;
4532  }
4533  if ($this->_skiprow1) {
4534  $pos += 1;
4535  }
4536  $this->fields = $this->_array[$pos];
4537  return true;
4538  }
4539 
4540  function _close() {
4541  return true;
4542  }
4543 
4544  } // ADORecordSet_array
4545 
4546  //==============================================================================================
4547  // HELPER FUNCTIONS
4548  //==============================================================================================
4549 
4555  function ADOLoadDB($dbType) {
4556  return ADOLoadCode($dbType);
4557  }
4558 
4562  function ADOLoadCode($dbType) {
4563  global $ADODB_LASTDB;
4564 
4565  if (!$dbType) {
4566  return false;
4567  }
4568  $db = strtolower($dbType);
4569  switch ($db) {
4570  case 'ado':
4571  if (PHP_VERSION >= 5) {
4572  $db = 'ado5';
4573  }
4574  $class = 'ado';
4575  break;
4576 
4577  case 'ifx':
4578  case 'maxsql':
4579  $class = $db = 'mysqlt';
4580  break;
4581 
4582  case 'pgsql':
4583  case 'postgres':
4584  $class = $db = 'postgres8';
4585  break;
4586 
4587  default:
4588  $class = $db; break;
4589  }
4590 
4591  $file = ADODB_DIR."/drivers/adodb-".$db.".inc.php";
4592  @include_once($file);
4593  $ADODB_LASTDB = $class;
4594  if (class_exists("ADODB_" . $class)) {
4595  return $class;
4596  }
4597 
4598  //ADOConnection::outp(adodb_pr(get_declared_classes(),true));
4599  if (!file_exists($file)) {
4600  ADOConnection::outp("Missing file: $file");
4601  } else {
4602  ADOConnection::outp("Syntax error in file: $file");
4603  }
4604  return false;
4605  }
4606 
4610  function NewADOConnection($db='') {
4611  $tmp = ADONewConnection($db);
4612  return $tmp;
4613  }
4614 
4623  function ADONewConnection($db='') {
4624  global $ADODB_NEWCONNECTION, $ADODB_LASTDB;
4625 
4626  if (!defined('ADODB_ASSOC_CASE')) {
4627  define('ADODB_ASSOC_CASE', ADODB_ASSOC_CASE_NATIVE);
4628  }
4629  $errorfn = (defined('ADODB_ERROR_HANDLER')) ? ADODB_ERROR_HANDLER : false;
4630  if (($at = strpos($db,'://')) !== FALSE) {
4631  $origdsn = $db;
4632  $fakedsn = 'fake'.substr($origdsn,$at);
4633  if (($at2 = strpos($origdsn,'@/')) !== FALSE) {
4634  // special handling of oracle, which might not have host
4635  $fakedsn = str_replace('@/','@adodb-fakehost/',$fakedsn);
4636  }
4637 
4638  if ((strpos($origdsn, 'sqlite')) !== FALSE && stripos($origdsn, '%2F') === FALSE) {
4639  // special handling for SQLite, it only might have the path to the database file.
4640  // If you try to connect to a SQLite database using a dsn
4641  // like 'sqlite:///path/to/database', the 'parse_url' php function
4642  // will throw you an exception with a message such as "unable to parse url"
4643  list($scheme, $path) = explode('://', $origdsn);
4644  $dsna['scheme'] = $scheme;
4645  if ($qmark = strpos($path,'?')) {
4646  $dsn['query'] = substr($path,$qmark+1);
4647  $path = substr($path,0,$qmark);
4648  }
4649  $dsna['path'] = '/' . urlencode($path);
4650  } else
4651  $dsna = @parse_url($fakedsn);
4652 
4653  if (!$dsna) {
4654  return false;
4655  }
4656  $dsna['scheme'] = substr($origdsn,0,$at);
4657  if ($at2 !== FALSE) {
4658  $dsna['host'] = '';
4659  }
4660 
4661  if (strncmp($origdsn,'pdo',3) == 0) {
4662  $sch = explode('_',$dsna['scheme']);
4663  if (sizeof($sch)>1) {
4664  $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
4665  if ($sch[1] == 'sqlite') {
4666  $dsna['host'] = rawurlencode($sch[1].':'.rawurldecode($dsna['host']));
4667  } else {
4668  $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
4669  }
4670  $dsna['scheme'] = 'pdo';
4671  }
4672  }
4673 
4674  $db = @$dsna['scheme'];
4675  if (!$db) {
4676  return false;
4677  }
4678  $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
4679  $dsna['user'] = isset($dsna['user']) ? rawurldecode($dsna['user']) : '';
4680  $dsna['pass'] = isset($dsna['pass']) ? rawurldecode($dsna['pass']) : '';
4681  $dsna['path'] = isset($dsna['path']) ? rawurldecode(substr($dsna['path'],1)) : ''; # strip off initial /
4682 
4683  if (isset($dsna['query'])) {
4684  $opt1 = explode('&',$dsna['query']);
4685  foreach($opt1 as $k => $v) {
4686  $arr = explode('=',$v);
4687  $opt[$arr[0]] = isset($arr[1]) ? rawurldecode($arr[1]) : 1;
4688  }
4689  } else {
4690  $opt = array();
4691  }
4692  }
4693  /*
4694  * phptype: Database backend used in PHP (mysql, odbc etc.)
4695  * dbsyntax: Database used with regards to SQL syntax etc.
4696  * protocol: Communication protocol to use (tcp, unix etc.)
4697  * hostspec: Host specification (hostname[:port])
4698  * database: Database to use on the DBMS server
4699  * username: User name for login
4700  * password: Password for login
4701  */
4702  if (!empty($ADODB_NEWCONNECTION)) {
4703  $obj = $ADODB_NEWCONNECTION($db);
4704 
4705  }
4706 
4707  if(empty($obj)) {
4708 
4709  if (!isset($ADODB_LASTDB)) {
4710  $ADODB_LASTDB = '';
4711  }
4712  if (empty($db)) {
4713  $db = $ADODB_LASTDB;
4714  }
4715  if ($db != $ADODB_LASTDB) {
4716  $db = ADOLoadCode($db);
4717  }
4718 
4719  if (!$db) {
4720  if (isset($origdsn)) {
4721  $db = $origdsn;
4722  }
4723  if ($errorfn) {
4724  // raise an error
4725  $ignore = false;
4726  $errorfn('ADONewConnection', 'ADONewConnection', -998,
4727  "could not load the database driver for '$db'",
4728  $db,false,$ignore);
4729  } else {
4730  ADOConnection::outp( "<p>ADONewConnection: Unable to load database driver '$db'</p>",false);
4731  }
4732  return false;
4733  }
4734 
4735  $cls = 'ADODB_'.$db;
4736  if (!class_exists($cls)) {
4737  adodb_backtrace();
4738  return false;
4739  }
4740 
4741  $obj = new $cls();
4742  }
4743 
4744  # constructor should not fail
4745  if ($obj) {
4746  if ($errorfn) {
4747  $obj->raiseErrorFn = $errorfn;
4748  }
4749  if (isset($dsna)) {
4750  if (isset($dsna['port'])) {
4751  $obj->port = $dsna['port'];
4752  }
4753  foreach($opt as $k => $v) {
4754  switch(strtolower($k)) {
4755  case 'new':
4756  $nconnect = true; $persist = true; break;
4757  case 'persist':
4758  case 'persistent': $persist = $v; break;
4759  case 'debug': $obj->debug = (integer) $v; break;
4760  #ibase
4761  case 'role': $obj->role = $v; break;
4762  case 'dialect': $obj->dialect = (integer) $v; break;
4763  case 'charset': $obj->charset = $v; $obj->charSet=$v; break;
4764  case 'buffers': $obj->buffers = $v; break;
4765  case 'fetchmode': $obj->SetFetchMode($v); break;
4766  #ado
4767  case 'charpage': $obj->charPage = $v; break;
4768  #mysql, mysqli
4769  case 'clientflags': $obj->clientFlags = $v; break;
4770  #mysql, mysqli, postgres
4771  case 'port': $obj->port = $v; break;
4772  #mysqli
4773  case 'socket': $obj->socket = $v; break;
4774  #oci8
4775  case 'nls_date_format': $obj->NLS_DATE_FORMAT = $v; break;
4776  case 'cachesecs': $obj->cacheSecs = $v; break;
4777  case 'memcache':
4778  $varr = explode(':',$v);
4779  $vlen = sizeof($varr);
4780  if ($vlen == 0) {
4781  break;
4782  }
4783  $obj->memCache = true;
4784  $obj->memCacheHost = explode(',',$varr[0]);
4785  if ($vlen == 1) {
4786  break;
4787  }
4788  $obj->memCachePort = $varr[1];
4789  if ($vlen == 2) {
4790  break;
4791  }
4792  $obj->memCacheCompress = $varr[2] ? true : false;
4793  break;
4794  }
4795  }
4796  if (empty($persist)) {
4797  $ok = $obj->Connect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']);
4798  } else if (empty($nconnect)) {
4799  $ok = $obj->PConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']);
4800  } else {
4801  $ok = $obj->NConnect($dsna['host'], $dsna['user'], $dsna['pass'], $dsna['path']);
4802  }
4803 
4804  if (!$ok) {
4805  return false;
4806  }
4807  }
4808  }
4809  return $obj;
4810  }
4811 
4812 
4813 
4814  // $perf == true means called by NewPerfMonitor(), otherwise for data dictionary
4815  function _adodb_getdriver($provider,$drivername,$perf=false) {
4816  switch ($provider) {
4817  case 'odbtp':
4818  if (strncmp('odbtp_',$drivername,6)==0) {
4819  return substr($drivername,6);
4820  }
4821  case 'odbc' :
4822  if (strncmp('odbc_',$drivername,5)==0) {
4823  return substr($drivername,5);
4824  }
4825  case 'ado' :
4826  if (strncmp('ado_',$drivername,4)==0) {
4827  return substr($drivername,4);
4828  }
4829  case 'native':
4830  break;
4831  default:
4832  return $provider;
4833  }
4834 
4835  switch($drivername) {
4836  case 'mysqlt':
4837  case 'mysqli':
4838  $drivername='mysql';
4839  break;
4840  case 'postgres7':
4841  case 'postgres8':
4842  $drivername = 'postgres';
4843  break;
4844  case 'firebird15':
4845  $drivername = 'firebird';
4846  break;
4847  case 'oracle':
4848  $drivername = 'oci8';
4849  break;
4850  case 'access':
4851  if ($perf) {
4852  $drivername = '';
4853  }
4854  break;
4855  case 'db2' :
4856  case 'sapdb' :
4857  break;
4858  default:
4859  $drivername = 'generic';
4860  break;
4861  }
4862  return $drivername;
4863  }
4864 
4865  function NewPerfMonitor(&$conn) {
4866  $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType,true);
4867  if (!$drivername || $drivername == 'generic') {
4868  return false;
4869  }
4870  include_once(ADODB_DIR.'/adodb-perf.inc.php');
4871  @include_once(ADODB_DIR."/perf/perf-$drivername.inc.php");
4872  $class = "Perf_$drivername";
4873  if (!class_exists($class)) {
4874  return false;
4875  }
4876  $perf = new $class($conn);
4877 
4878  return $perf;
4879  }
4880 
4881  function NewDataDictionary(&$conn,$drivername=false) {
4882  if (!$drivername) {
4883  $drivername = _adodb_getdriver($conn->dataProvider,$conn->databaseType);
4884  }
4885 
4886  include_once(ADODB_DIR.'/adodb-lib.inc.php');
4887  include_once(ADODB_DIR.'/adodb-datadict.inc.php');
4888  $path = ADODB_DIR."/datadict/datadict-$drivername.inc.php";
4889 
4890  if (!file_exists($path)) {
4891  ADOConnection::outp("Dictionary driver '$path' not available");
4892  return false;
4893  }
4894  include_once($path);
4895  $class = "ADODB2_$drivername";
4896  $dict = new $class();
4897  $dict->dataProvider = $conn->dataProvider;
4898  $dict->connection = $conn;
4899  $dict->upperName = strtoupper($drivername);
4900  $dict->quote = $conn->nameQuote;
4901  if (!empty($conn->_connectionID)) {
4902  $dict->serverInfo = $conn->ServerInfo();
4903  }
4904 
4905  return $dict;
4906  }
4907 
4908 
4909 
4910  /*
4911  Perform a print_r, with pre tags for better formatting.
4912  */
4913  function adodb_pr($var,$as_string=false) {
4914  if ($as_string) {
4915  ob_start();
4916  }
4917 
4918  if (isset($_SERVER['HTTP_USER_AGENT'])) {
4919  echo " <pre>\n";print_r($var);echo "</pre>\n";
4920  } else {
4921  print_r($var);
4922  }
4923 
4924  if ($as_string) {
4925  $s = ob_get_contents();
4926  ob_end_clean();
4927  return $s;
4928  }
4929  }
4930 
4931  /*
4932  Perform a stack-crawl and pretty print it.
4933 
4934  @param printOrArr Pass in a boolean to indicate print, or an $exception->trace array (assumes that print is true then).
4935  @param levels Number of levels to display
4936  */
4937  function adodb_backtrace($printOrArr=true,$levels=9999,$ishtml=null) {
4938  global $ADODB_INCLUDED_LIB;
4939  if (empty($ADODB_INCLUDED_LIB)) {
4940  include(ADODB_DIR.'/adodb-lib.inc.php');
4941  }
4942  return _adodb_backtrace($printOrArr,$levels,0,$ishtml);
4943  }
4944 
4945 }
_adodb_getupdatesql(&$zthis, &$rs, $arrFields, $forceUpdate=false, $magicq=false, $force=2)
_adodb_backtrace($printOrArr=true, $levels=9999, $skippy=0, $ishtml=null)
$database
Definition: server.php:40
if(false) adodb_probetypes(&$array, &$types, $probe=8)
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:94
global $_ADODB_ACTIVE_DBS
_rs2serialize(&$rs, $conn=false, $sql='')
debug($variable='', $name=' *variable *', $line=' *line *', $file=' *file *', $recursiveDepth=3, $debugLevel='E_DEBUG')
global $ADODB_INCLUDED_LIB
_adodb_getinsertsql(&$zthis, &$rs, $arrFields, $magicq=false, $force=2)
global $ADODB_INCLUDED_CSV
_adodb_export(&$rs, $sep, $sepreplace, $fp=false, $addtitles=true, $quote='"',$escquote = '"', $replaceNewLine=' ')
_adodb_getmenu_gp(&$zthis, $name, $defstr='', $blank1stItem=true, $multiple=false, $size=0, $selectAttr='', $compareFields0=true)
_adodb_debug_execute(&$zthis, $sql, $inputarr)
adodb_gmdate($fmt, $d=false)
$conn
Definition: server.php:81
adodb_throw($dbms, $fn, $errno, $errmsg, $p1, $p2, $thisConnection)
adodb_date($fmt, $d=false, $is_gmt=false)
_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
adodb_error($provider, $dbType, $errno)
_adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
const ADODB_ERROR_HANDLER
ADODB_PEAR_Error()
if(!defined("DB_ERROR_SYNTAX")) adodb_errormsg($value)
csv2rs($url, &$err, $timeout=0, $rsclass='ADORecordSet_array')
_adodb_getmenu(&$zthis, $name, $defstr='', $blank1stItem=true, $multiple=false, $size=0, $selectAttr='', $compareFields0=true)
adodb_transpose(&$arr, &$newarr, &$hdr, &$fobjs)
adodb_mktime($hr, $min, $sec, $mon=false, $day=false, $year=false, $is_dst=false, $is_gmt=false)
$host
Definition: server.php:37
adodb_GetActiveRecordsClass(&$db, $class, $table, $whereOrderBy, $bindarr, $primkeyArr, $extra)
$sql
Definition: server.php:84
global $ADODB_INCLUDED_MEMCACHE
_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
adodb_write_file($filename, $contents, $debug=false)