TYPO3 CMS  TYPO3_6-2
adodb-pdo.inc.php
Go to the documentation of this file.
1 <?php
2 /*
3 V5.19 23-Apr-2014 (c) 2000-2014 John Lim (jlim#natsoft.com). All rights reserved.
4  Released under both BSD license and Lesser GPL library license.
5  Whenever there is any discrepancy between the two licenses,
6  the BSD license will take precedence.
7 Set tabs to 4 for best viewing.
8 
9  Latest version is available at http://adodb.sourceforge.net
10 
11  Requires ODBC. Works on Windows and Unix.
12 
13  Problems:
14  Where is float/decimal type in pdo_param_type
15  LOB handling for CLOB/BLOB differs significantly
16 */
17 // security - hide paths
18 if (!defined('ADODB_DIR')) die();
19 
20 
21 /*
22 enum pdo_param_type {
23 PDO::PARAM_NULL, 0
24 
25 /* int as in long (the php native int type).
26  * If you mark a column as an int, PDO expects get_col to return
27  * a pointer to a long
28 PDO::PARAM_INT, 1
29 
30 /* get_col ptr should point to start of the string buffer
31 PDO::PARAM_STR, 2
32 
33 /* get_col: when len is 0 ptr should point to a php_stream *,
34  * otherwise it should behave like a string. Indicate a NULL field
35  * value by setting the ptr to NULL
36 PDO::PARAM_LOB, 3
37 
38 /* get_col: will expect the ptr to point to a new PDOStatement object handle,
39  * but this isn't wired up yet
40 PDO::PARAM_STMT, 4 /* hierarchical result set
41 
42 /* get_col ptr should point to a zend_bool
43 PDO::PARAM_BOOL, 5
44 
45 
46 /* magic flag to denote a parameter as being input/output
47 PDO::PARAM_INPUT_OUTPUT = 0x80000000
48 };
49 */
50 
51 function adodb_pdo_type($t)
52 {
53  switch($t) {
54  case 2: return 'VARCHAR';
55  case 3: return 'BLOB';
56  default: return 'NUMERIC';
57  }
58 }
59 
60 /*--------------------------------------------------------------------------------------
61 --------------------------------------------------------------------------------------*/
62 
64 
65 
66 
67 
68 
69 
70 class ADODB_pdo extends ADOConnection {
71  var $databaseType = "pdo";
72  var $dataProvider = "pdo";
73  var $fmtDate = "'Y-m-d'";
74  var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
75  var $replaceQuote = "''"; // string to use to replace quotes
76  var $hasAffectedRows = true;
77  var $_bindInputArray = true;
78  var $_genSeqSQL = "create table %s (id integer)";
79  var $_autocommit = true;
80  var $_haserrorfunctions = true;
82 
83  var $_errormsg = false;
84  var $_errorno = false;
85 
86  var $dsnType = '';
87  var $stmt = false;
88 
89  function ADODB_pdo()
90  {
91  }
92 
93  function _UpdatePDO()
94  {
95  $d = $this->_driver;
96  $this->fmtDate = $d->fmtDate;
97  $this->fmtTimeStamp = $d->fmtTimeStamp;
98  $this->replaceQuote = $d->replaceQuote;
99  $this->sysDate = $d->sysDate;
100  $this->sysTimeStamp = $d->sysTimeStamp;
101  $this->random = $d->random;
102  $this->concat_operator = $d->concat_operator;
103  $this->nameQuote = $d->nameQuote;
104 
105  $this->hasGenID = $d->hasGenID;
106  $this->_genIDSQL = $d->_genIDSQL;
107  $this->_genSeqSQL = $d->_genSeqSQL;
108  $this->_dropSeqSQL = $d->_dropSeqSQL;
109 
110  $d->_init($this);
111  }
112 
113  function Time()
114  {
115  if (!empty($this->_driver->_hasdual)) $sql = "select $this->sysTimeStamp from dual";
116  else $sql = "select $this->sysTimeStamp";
117 
118  $rs = $this->_Execute($sql);
119  if ($rs && !$rs->EOF) return $this->UnixTimeStamp(reset($rs->fields));
120 
121  return false;
122  }
123 
124  // returns true or false
125  function _connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persist=false)
126  {
127  $at = strpos($argDSN,':');
128  $this->dsnType = substr($argDSN,0,$at);
129 
130  if ($argDatabasename) {
131  $argDSN .= ';dbname='.$argDatabasename;
132  }
133  try {
134  $this->_connectionID = new PDO($argDSN, $argUsername, $argPassword);
135  } catch (Exception $e) {
136  $this->_connectionID = false;
137  $this->_errorno = -1;
138  //var_dump($e);
139  $this->_errormsg = 'Connection attempt failed: '.$e->getMessage();
140  return false;
141  }
142 
143  if ($this->_connectionID) {
144  switch(ADODB_ASSOC_CASE){
145  case 0: $m = PDO::CASE_LOWER; break;
146  case 1: $m = PDO::CASE_UPPER; break;
147  default:
148  case 2: $m = PDO::CASE_NATURAL; break;
149  }
150 
151  //$this->_connectionID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT );
152  $this->_connectionID->setAttribute(PDO::ATTR_CASE,$m);
153 
154  $class = 'ADODB_pdo_'.$this->dsnType;
155  //$this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
156  switch($this->dsnType) {
157  case 'oci':
158  case 'mysql':
159  case 'pgsql':
160  case 'mssql':
161  case 'sqlite':
162  include_once(ADODB_DIR.'/drivers/adodb-pdo_'.$this->dsnType.'.inc.php');
163  break;
164  }
165  if (class_exists($class))
166  $this->_driver = new $class();
167  else
168  $this->_driver = new ADODB_pdo_base();
169 
170  $this->_driver->_connectionID = $this->_connectionID;
171  $this->_UpdatePDO();
172  return true;
173  }
174  $this->_driver = new ADODB_pdo_base();
175  return false;
176  }
177 
178  function Concat()
179  {
180  $args = func_get_args();
181  if(method_exists($this->_driver, 'Concat'))
182  return call_user_func_array(array($this->_driver, 'Concat'), $args);
183 
184  if (PHP_VERSION >= 5.3) return call_user_func_array('parent::Concat', $args);
185  return call_user_func_array(array($this,'parent::Concat'), $args);
186  }
187 
188  // returns true or false
189  function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
190  {
191  return $this->_connect($argDSN, $argUsername, $argPassword, $argDatabasename, true);
192  }
193 
194  /*------------------------------------------------------------------------------*/
195 
196 
197  function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
198  {
199  $save = $this->_driver->fetchMode;
200  $this->_driver->fetchMode = $this->fetchMode;
201  $this->_driver->debug = $this->debug;
202  $ret = $this->_driver->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
203  $this->_driver->fetchMode = $save;
204  return $ret;
205  }
206 
207 
208  function ServerInfo()
209  {
210  return $this->_driver->ServerInfo();
211  }
212 
213  function MetaTables($ttype=false,$showSchema=false,$mask=false)
214  {
215  return $this->_driver->MetaTables($ttype,$showSchema,$mask);
216  }
217 
218  function MetaColumns($table,$normalize=true)
219  {
220  return $this->_driver->MetaColumns($table,$normalize);
221  }
222 
223  function InParameter(&$stmt,&$var,$name,$maxLen=4000,$type=false)
224  {
225  $obj = $stmt[1];
226  if ($type) $obj->bindParam($name,$var,$type,$maxLen);
227  else $obj->bindParam($name, $var);
228  }
229 
230  function OffsetDate($dayFraction,$date=false)
231  {
232  return $this->_driver->OffsetDate($dayFraction,$date);
233  }
234 
235  function ErrorMsg()
236  {
237  if ($this->_errormsg !== false) return $this->_errormsg;
238  if (!empty($this->_stmt)) $arr = $this->_stmt->errorInfo();
239  else if (!empty($this->_connectionID)) $arr = $this->_connectionID->errorInfo();
240  else return 'No Connection Established';
241 
242 
243  if ($arr) {
244  if (sizeof($arr)<2) return '';
245  if ((integer)$arr[0]) return $arr[2];
246  else return '';
247  } else return '-1';
248  }
249 
250 
251  function ErrorNo()
252  {
253  if ($this->_errorno !== false) return $this->_errorno;
254  if (!empty($this->_stmt)) $err = $this->_stmt->errorCode();
255  else if (!empty($this->_connectionID)) {
256  $arr = $this->_connectionID->errorInfo();
257  if (isset($arr[0])) $err = $arr[0];
258  else $err = -1;
259  } else
260  return 0;
261 
262  if ($err == '00000') return 0; // allows empty check
263  return $err;
264  }
265 
266  function SetTransactionMode($transaction_mode)
267  {
268  if(method_exists($this->_driver, 'SetTransactionMode'))
269  return $this->_driver->SetTransactionMode($transaction_mode);
270 
271  return parent::SetTransactionMode($seqname);
272  }
273 
274  function BeginTrans()
275  {
276  if(method_exists($this->_driver, 'BeginTrans'))
277  return $this->_driver->BeginTrans();
278 
279  if (!$this->hasTransactions) return false;
280  if ($this->transOff) return true;
281  $this->transCnt += 1;
282  $this->_autocommit = false;
283  $this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,false);
284  return $this->_connectionID->beginTransaction();
285  }
286 
287  function CommitTrans($ok=true)
288  {
289  if(method_exists($this->_driver, 'CommitTrans'))
290  return $this->_driver->CommitTrans($ok);
291 
292  if (!$this->hasTransactions) return false;
293  if ($this->transOff) return true;
294  if (!$ok) return $this->RollbackTrans();
295  if ($this->transCnt) $this->transCnt -= 1;
296  $this->_autocommit = true;
297 
298  $ret = $this->_connectionID->commit();
299  $this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
300  return $ret;
301  }
302 
303  function RollbackTrans()
304  {
305  if(method_exists($this->_driver, 'RollbackTrans'))
306  return $this->_driver->RollbackTrans();
307 
308  if (!$this->hasTransactions) return false;
309  if ($this->transOff) return true;
310  if ($this->transCnt) $this->transCnt -= 1;
311  $this->_autocommit = true;
312 
313  $ret = $this->_connectionID->rollback();
314  $this->_connectionID->setAttribute(PDO::ATTR_AUTOCOMMIT,true);
315  return $ret;
316  }
317 
318  function Prepare($sql)
319  {
320  $this->_stmt = $this->_connectionID->prepare($sql);
321  if ($this->_stmt) return array($sql,$this->_stmt);
322 
323  return false;
324  }
325 
326  function PrepareStmt($sql)
327  {
328  $stmt = $this->_connectionID->prepare($sql);
329  if (!$stmt) return false;
330  $obj = new ADOPDOStatement($stmt,$this);
331  return $obj;
332  }
333 
334  function CreateSequence($seqname='adodbseq',$startID=1)
335  {
336  if(method_exists($this->_driver, 'CreateSequence'))
337  return $this->_driver->CreateSequence($seqname, $startID);
338 
339  return parent::CreateSequence($seqname, $startID);
340  }
341 
342  function DropSequence($seqname='adodbseq')
343  {
344  if(method_exists($this->_driver, 'DropSequence'))
345  return $this->_driver->DropSequence($seqname);
346 
347  return parent::DropSequence($seqname);
348  }
349 
350  function GenID($seqname='adodbseq',$startID=1)
351  {
352  if(method_exists($this->_driver, 'GenID'))
353  return $this->_driver->GenID($seqname, $startID);
354 
355  return parent::GenID($seqname, $startID);
356  }
357 
358 
359  /* returns queryID or false */
360  function _query($sql,$inputarr=false)
361  {
362  if (is_array($sql)) {
363  $stmt = $sql[1];
364  } else {
365  $stmt = $this->_connectionID->prepare($sql);
366  }
367  #adodb_backtrace();
368  #var_dump($this->_bindInputArray);
369  if ($stmt) {
370  $this->_driver->debug = $this->debug;
371  if ($inputarr) $ok = $stmt->execute($inputarr);
372  else $ok = $stmt->execute();
373  }
374 
375 
376  $this->_errormsg = false;
377  $this->_errorno = false;
378 
379  if ($ok) {
380  $this->_stmt = $stmt;
381  return $stmt;
382  }
383 
384  if ($stmt) {
385 
386  $arr = $stmt->errorinfo();
387  if ((integer)$arr[1]) {
388  $this->_errormsg = $arr[2];
389  $this->_errorno = $arr[1];
390  }
391 
392  } else {
393  $this->_errormsg = false;
394  $this->_errorno = false;
395  }
396  return false;
397  }
398 
399  // returns true or false
400  function _close()
401  {
402  $this->_stmt = false;
403  return true;
404  }
405 
406  function _affectedrows()
407  {
408  return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
409  }
410 
411  function _insertid()
412  {
413  return ($this->_connectionID) ? $this->_connectionID->lastInsertId() : 0;
414  }
415 }
416 
417 class ADODB_pdo_base extends ADODB_pdo {
418 
419  var $sysDate = "'?'";
420  var $sysTimeStamp = "'?'";
421 
422 
423  function _init($parentDriver)
424  {
425  $parentDriver->_bindInputArray = true;
426  #$parentDriver->_connectionID->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);
427  }
428 
429  function ServerInfo()
430  {
431  return ADOConnection::ServerInfo();
432  }
433 
434  function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
435  {
436  $ret = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
437  return $ret;
438  }
439 
440  function MetaTables()
441  {
442  return false;
443  }
444 
445  function MetaColumns()
446  {
447  return false;
448  }
449 }
450 
452 
453  var $databaseType = "pdo";
454  var $dataProvider = "pdo";
455  var $_stmt;
457 
458  function ADOPDOStatement($stmt,$connection)
459  {
460  $this->_stmt = $stmt;
461  $this->_connectionID = $connection;
462  }
463 
464  function Execute($inputArr=false)
465  {
466  $savestmt = $this->_connectionID->_stmt;
467  $rs = $this->_connectionID->Execute(array(false,$this->_stmt),$inputArr);
468  $this->_connectionID->_stmt = $savestmt;
469  return $rs;
470  }
471 
472  function InParameter(&$var,$name,$maxLen=4000,$type=false)
473  {
474 
475  if ($type) $this->_stmt->bindParam($name,$var,$type,$maxLen);
476  else $this->_stmt->bindParam($name, $var);
477  }
478 
479  function Affected_Rows()
480  {
481  return ($this->_stmt) ? $this->_stmt->rowCount() : 0;
482  }
483 
484  function ErrorMsg()
485  {
486  if ($this->_stmt) $arr = $this->_stmt->errorInfo();
487  else $arr = $this->_connectionID->errorInfo();
488 
489  if (is_array($arr)) {
490  if ((integer) $arr[0] && isset($arr[2])) return $arr[2];
491  else return '';
492  } else return '-1';
493  }
494 
495  function NumCols()
496  {
497  return ($this->_stmt) ? $this->_stmt->columnCount() : 0;
498  }
499 
500  function ErrorNo()
501  {
502  if ($this->_stmt) return $this->_stmt->errorCode();
503  else return $this->_connectionID->errorInfo();
504  }
505 }
506 
507 /*--------------------------------------------------------------------------------------
508  Class Name: Recordset
509 --------------------------------------------------------------------------------------*/
510 
511 class ADORecordSet_pdo extends ADORecordSet {
512 
513  var $bind = false;
514  var $databaseType = "pdo";
515  var $dataProvider = "pdo";
516 
517  function ADORecordSet_pdo($id,$mode=false)
518  {
519  if ($mode === false) {
520  global $ADODB_FETCH_MODE;
521  $mode = $ADODB_FETCH_MODE;
522  }
523  $this->adodbFetchMode = $mode;
524  switch($mode) {
525  case ADODB_FETCH_NUM: $mode = PDO::FETCH_NUM; break;
526  case ADODB_FETCH_ASSOC: $mode = PDO::FETCH_ASSOC; break;
527 
528  case ADODB_FETCH_BOTH:
529  default: $mode = PDO::FETCH_BOTH; break;
530  }
531  $this->fetchMode = $mode;
532 
533  $this->_queryID = $id;
534  $this->ADORecordSet($id);
535  }
536 
537 
538  function Init()
539  {
540  if ($this->_inited) return;
541  $this->_inited = true;
542  if ($this->_queryID) @$this->_initrs();
543  else {
544  $this->_numOfRows = 0;
545  $this->_numOfFields = 0;
546  }
547  if ($this->_numOfRows != 0 && $this->_currentRow == -1) {
548  $this->_currentRow = 0;
549  if ($this->EOF = ($this->_fetch() === false)) {
550  $this->_numOfRows = 0; // _numOfRows could be -1
551  }
552  } else {
553  $this->EOF = true;
554  }
555  }
556 
557  function _initrs()
558  {
559  global $ADODB_COUNTRECS;
560 
561  $this->_numOfRows = ($ADODB_COUNTRECS) ? @$this->_queryID->rowCount() : -1;
562  if (!$this->_numOfRows) $this->_numOfRows = -1;
563  $this->_numOfFields = $this->_queryID->columnCount();
564  }
565 
566  // returns the field object
567  function FetchField($fieldOffset = -1)
568  {
569  $off=$fieldOffset+1; // offsets begin at 1
570 
571  $o= new ADOFieldObject();
572  $arr = @$this->_queryID->getColumnMeta($fieldOffset);
573  if (!$arr) {
574  $o->name = 'bad getColumnMeta()';
575  $o->max_length = -1;
576  $o->type = 'VARCHAR';
577  $o->precision = 0;
578  # $false = false;
579  return $o;
580  }
581  //adodb_pr($arr);
582  $o->name = $arr['name'];
583  if (isset($arr['native_type']) && $arr['native_type'] <> "null") $o->type = $arr['native_type'];
584  else $o->type = adodb_pdo_type($arr['pdo_type']);
585  $o->max_length = $arr['len'];
586  $o->precision = $arr['precision'];
587 
588  if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name);
589  else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name);
590  return $o;
591  }
592 
593  function _seek($row)
594  {
595  return false;
596  }
597 
598  function _fetch()
599  {
600  if (!$this->_queryID) return false;
601 
602  $this->fields = $this->_queryID->fetch($this->fetchMode);
603  return !empty($this->fields);
604  }
605 
606  function _close()
607  {
608  $this->_queryID = false;
609  }
610 
611  function Fields($colname)
612  {
613  if ($this->adodbFetchMode != ADODB_FETCH_NUM) return @$this->fields[$colname];
614 
615  if (!$this->bind) {
616  $this->bind = array();
617  for ($i=0; $i < $this->_numOfFields; $i++) {
618  $o = $this->FetchField($i);
619  $this->bind[strtoupper($o->name)] = $i;
620  }
621  }
622  return $this->fields[$this->bind[strtoupper($colname)]];
623  }
624 
625 }
adodb_pdo_type($t)
InParameter(&$var, $name, $maxLen=4000, $type=false)
Execute($inputArr=false)
SetTransactionMode($transaction_mode)
$sql
Definition: server.php:82
DropSequence($seqname='adodbseq')
MetaColumns($table, $normalize=true)
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:92
MetaTables($ttype=false, $showSchema=false, $mask=false)
die
Definition: index.php:6
ADOPDOStatement($stmt, $connection)
_query($sql, $inputarr=false)
GenID($seqname='adodbseq', $startID=1)
InParameter(&$stmt, &$var, $name, $maxLen=4000, $type=false)
SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0)
ADORecordSet_pdo($id, $mode=false)
_init($parentDriver)
CommitTrans($ok=true)
OffsetDate($dayFraction, $date=false)
PrepareStmt($sql)
FetchField($fieldOffset=-1)
SelectLimit($sql, $nrows=-1, $offset=-1, $inputarr=false, $secs2cache=0)
CreateSequence($seqname='adodbseq', $startID=1)
_pconnect($argDSN, $argUsername, $argPassword, $argDatabasename)
_connect($argDSN, $argUsername, $argPassword, $argDatabasename, $persist=false)