TYPO3 CMS  TYPO3_7-6
adodb-ado.inc.php
Go to the documentation of this file.
1 <?php
2 /*
3 @version v5.20.3 01-Jan-2016
4 @copyright (c) 2000-2013 John Lim (jlim#natsoft.com). All rights reserved.
5 @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
6  Released under both BSD license and Lesser GPL library license.
7  Whenever there is any discrepancy between the two licenses,
8  the BSD license will take precedence.
9 Set tabs to 4 for best viewing.
10 
11  Latest version is available at http://adodb.sourceforge.net
12 
13  Microsoft ADO data driver. Requires ADO. Works only on MS Windows.
14 */
15 
16 // security - hide paths
17 if (!defined('ADODB_DIR')) die();
18 
19 define("_ADODB_ADO_LAYER", 1 );
20 /*--------------------------------------------------------------------------------------
21 --------------------------------------------------------------------------------------*/
22 
23 
24 class ADODB_ado extends ADOConnection {
25  var $databaseType = "ado";
26  var $_bindInputArray = false;
27  var $fmtDate = "'Y-m-d'";
28  var $fmtTimeStamp = "'Y-m-d, h:i:sA'";
29  var $replaceQuote = "''"; // string to use to replace quotes
30  var $dataProvider = "ado";
31  var $hasAffectedRows = true;
32  var $adoParameterType = 201; // 201 = long varchar, 203=long wide varchar, 205 = long varbinary
33  var $_affectedRows = false;
35  var $_cursor_type = 3; // 3=adOpenStatic,0=adOpenForwardOnly,1=adOpenKeyset,2=adOpenDynamic
36  var $_cursor_location = 3; // 2=adUseServer, 3 = adUseClient;
37  var $_lock_type = -1;
38  var $_execute_option = -1;
39  var $poorAffectedRows = true;
40  var $charPage;
41 
42  function __construct()
43  {
44  $this->_affectedRows = new VARIANT;
45  }
46 
47  function ServerInfo()
48  {
49  if (!empty($this->_connectionID)) $desc = $this->_connectionID->provider;
50  return array('description' => $desc, 'version' => '');
51  }
52 
53  function _affectedrows()
54  {
55  if (PHP_VERSION >= 5) return $this->_affectedRows;
56 
57  return $this->_affectedRows->value;
58  }
59 
60  // you can also pass a connection string like this:
61  //
62  // $DB->Connect('USER ID=sa;PASSWORD=pwd;SERVER=mangrove;DATABASE=ai',false,false,'SQLOLEDB');
63  function _connect($argHostname, $argUsername, $argPassword, $argProvider= 'MSDASQL')
64  {
65  $u = 'UID';
66  $p = 'PWD';
67 
68  if (!empty($this->charPage))
69  $dbc = new COM('ADODB.Connection',null,$this->charPage);
70  else
71  $dbc = new COM('ADODB.Connection');
72 
73  if (! $dbc) return false;
74 
75  /* special support if provider is mssql or access */
76  if ($argProvider=='mssql') {
77  $u = 'User Id'; //User parameter name for OLEDB
78  $p = 'Password';
79  $argProvider = "SQLOLEDB"; // SQL Server Provider
80 
81  // not yet
82  //if ($argDatabasename) $argHostname .= ";Initial Catalog=$argDatabasename";
83 
84  //use trusted conection for SQL if username not specified
85  if (!$argUsername) $argHostname .= ";Trusted_Connection=Yes";
86  } else if ($argProvider=='access')
87  $argProvider = "Microsoft.Jet.OLEDB.4.0"; // Microsoft Jet Provider
88 
89  if ($argProvider) $dbc->Provider = $argProvider;
90 
91  if ($argUsername) $argHostname .= ";$u=$argUsername";
92  if ($argPassword)$argHostname .= ";$p=$argPassword";
93 
94  if ($this->debug) ADOConnection::outp( "Host=".$argHostname."<BR>\n version=$dbc->version");
95  // @ added below for php 4.0.1 and earlier
96  @$dbc->Open((string) $argHostname);
97 
98  $this->_connectionID = $dbc;
99 
100  $dbc->CursorLocation = $this->_cursor_location;
101  return $dbc->State > 0;
102  }
103 
104  // returns true or false
105  function _pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
106  {
107  return $this->_connect($argHostname,$argUsername,$argPassword,$argProvider);
108  }
109 
110 /*
111  adSchemaCatalogs = 1,
112  adSchemaCharacterSets = 2,
113  adSchemaCollations = 3,
114  adSchemaColumns = 4,
115  adSchemaCheckConstraints = 5,
116  adSchemaConstraintColumnUsage = 6,
117  adSchemaConstraintTableUsage = 7,
118  adSchemaKeyColumnUsage = 8,
119  adSchemaReferentialContraints = 9,
120  adSchemaTableConstraints = 10,
121  adSchemaColumnsDomainUsage = 11,
122  adSchemaIndexes = 12,
123  adSchemaColumnPrivileges = 13,
124  adSchemaTablePrivileges = 14,
125  adSchemaUsagePrivileges = 15,
126  adSchemaProcedures = 16,
127  adSchemaSchemata = 17,
128  adSchemaSQLLanguages = 18,
129  adSchemaStatistics = 19,
130  adSchemaTables = 20,
131  adSchemaTranslations = 21,
132  adSchemaProviderTypes = 22,
133  adSchemaViews = 23,
134  adSchemaViewColumnUsage = 24,
135  adSchemaViewTableUsage = 25,
136  adSchemaProcedureParameters = 26,
137  adSchemaForeignKeys = 27,
138  adSchemaPrimaryKeys = 28,
139  adSchemaProcedureColumns = 29,
140  adSchemaDBInfoKeywords = 30,
141  adSchemaDBInfoLiterals = 31,
142  adSchemaCubes = 32,
143  adSchemaDimensions = 33,
144  adSchemaHierarchies = 34,
145  adSchemaLevels = 35,
146  adSchemaMeasures = 36,
147  adSchemaProperties = 37,
148  adSchemaMembers = 38
149 
150 */
151 
152  function MetaTables($ttype = false, $showSchema = false, $mask = false)
153  {
154  $arr= array();
155  $dbc = $this->_connectionID;
156 
157  $adors=@$dbc->OpenSchema(20);//tables
158  if ($adors){
159  $f = $adors->Fields(2);//table/view name
160  $t = $adors->Fields(3);//table type
161  while (!$adors->EOF){
162  $tt=substr($t->value,0,6);
163  if ($tt!='SYSTEM' && $tt !='ACCESS')
164  $arr[]=$f->value;
165  //print $f->value . ' ' . $t->value.'<br>';
166  $adors->MoveNext();
167  }
168  $adors->Close();
169  }
170 
171  return $arr;
172  }
173 
174  function MetaColumns($table, $normalize=true)
175  {
176  $table = strtoupper($table);
177  $arr = array();
178  $dbc = $this->_connectionID;
179 
180  $adors=@$dbc->OpenSchema(4);//tables
181 
182  if ($adors){
183  $t = $adors->Fields(2);//table/view name
184  while (!$adors->EOF){
185 
186 
187  if (strtoupper($t->Value) == $table) {
188 
189  $fld = new ADOFieldObject();
190  $c = $adors->Fields(3);
191  $fld->name = $c->Value;
192  $fld->type = 'CHAR'; // cannot discover type in ADO!
193  $fld->max_length = -1;
194  $arr[strtoupper($fld->name)]=$fld;
195  }
196 
197  $adors->MoveNext();
198  }
199  $adors->Close();
200  }
201  $false = false;
202  return empty($arr) ? $false : $arr;
203  }
204 
205 
206 
207 
208  /* returns queryID or false */
209  function _query($sql,$inputarr=false)
210  {
211 
212  $dbc = $this->_connectionID;
213  $false = false;
214 
215  // return rs
216  if ($inputarr) {
217 
218  if (!empty($this->charPage))
219  $oCmd = new COM('ADODB.Command',null,$this->charPage);
220  else
221  $oCmd = new COM('ADODB.Command');
222  $oCmd->ActiveConnection = $dbc;
223  $oCmd->CommandText = $sql;
224  $oCmd->CommandType = 1;
225 
226  // Map by http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmthcreateparam.asp
227  // Check issue http://bugs.php.net/bug.php?id=40664 !!!
228  while(list(, $val) = each($inputarr)) {
229  $type = gettype($val);
230  $len=strlen($val);
231  if ($type == 'boolean')
232  $this->adoParameterType = 11;
233  else if ($type == 'integer')
234  $this->adoParameterType = 3;
235  else if ($type == 'double')
236  $this->adoParameterType = 5;
237  elseif ($type == 'string')
238  $this->adoParameterType = 202;
239  else if (($val === null) || (!defined($val)))
240  $len=1;
241  else
242  $this->adoParameterType = 130;
243 
244  // name, type, direction 1 = input, len,
245  $p = $oCmd->CreateParameter('name',$this->adoParameterType,1,$len,$val);
246 
247  $oCmd->Parameters->Append($p);
248  }
249  $p = false;
250  $rs = $oCmd->Execute();
251  $e = $dbc->Errors;
252  if ($dbc->Errors->Count > 0) return $false;
253  return $rs;
254  }
255 
256  $rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option);
257 
258  if ($dbc->Errors->Count > 0) return $false;
259  if (! $rs) return $false;
260 
261  if ($rs->State == 0) {
262  $true = true;
263  return $true; // 0 = adStateClosed means no records returned
264  }
265  return $rs;
266  }
267 
268 
269  function BeginTrans()
270  {
271  if ($this->transOff) return true;
272 
273  if (isset($this->_thisTransactions))
274  if (!$this->_thisTransactions) return false;
275  else {
276  $o = $this->_connectionID->Properties("Transaction DDL");
277  $this->_thisTransactions = $o ? true : false;
278  if (!$o) return false;
279  }
280  @$this->_connectionID->BeginTrans();
281  $this->transCnt += 1;
282  return true;
283  }
284 
285  function CommitTrans($ok=true)
286  {
287  if (!$ok) return $this->RollbackTrans();
288  if ($this->transOff) return true;
289 
290  @$this->_connectionID->CommitTrans();
291  if ($this->transCnt) @$this->transCnt -= 1;
292  return true;
293  }
294  function RollbackTrans() {
295  if ($this->transOff) return true;
296  @$this->_connectionID->RollbackTrans();
297  if ($this->transCnt) @$this->transCnt -= 1;
298  return true;
299  }
300 
301  /* Returns: the last error message from previous database operation */
302 
303  function ErrorMsg()
304  {
305  if (!$this->_connectionID) return "No connection established";
306  $errc = $this->_connectionID->Errors;
307  if (!$errc) return "No Errors object found";
308  if ($errc->Count == 0) return '';
309  $err = $errc->Item($errc->Count-1);
310  return $err->Description;
311  }
312 
313  function ErrorNo()
314  {
315  $errc = $this->_connectionID->Errors;
316  if ($errc->Count == 0) return 0;
317  $err = $errc->Item($errc->Count-1);
318  return $err->NativeError;
319  }
320 
321  // returns true or false
322  function _close()
323  {
324  if ($this->_connectionID) $this->_connectionID->Close();
325  $this->_connectionID = false;
326  return true;
327  }
328 
329 
330 }
331 
332 /*--------------------------------------------------------------------------------------
333  Class Name: Recordset
334 --------------------------------------------------------------------------------------*/
335 
336 class ADORecordSet_ado extends ADORecordSet {
337 
338  var $bind = false;
339  var $databaseType = "ado";
340  var $dataProvider = "ado";
341  var $_tarr = false; // caches the types
342  var $_flds; // and field objects
343  var $canSeek = true;
344  var $hideErrors = true;
345 
346  function __construct($id,$mode=false)
347  {
348  if ($mode === false) {
349  global $ADODB_FETCH_MODE;
350  $mode = $ADODB_FETCH_MODE;
351  }
352  $this->fetchMode = $mode;
353  return parent::__construct($id,$mode);
354  }
355 
356 
357  // returns the field object
358  function FetchField($fieldOffset = -1) {
359  $off=$fieldOffset+1; // offsets begin at 1
360 
361  $o= new ADOFieldObject();
362  $rs = $this->_queryID;
363  $f = $rs->Fields($fieldOffset);
364  $o->name = $f->Name;
365  $t = $f->Type;
366  $o->type = $this->MetaType($t);
367  $o->max_length = $f->DefinedSize;
368  $o->ado_type = $t;
369 
370  //print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
371  return $o;
372  }
373 
374  /* Use associative array to get fields array */
375  function Fields($colname)
376  {
377  if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
378  if (!$this->bind) {
379  $this->bind = array();
380  for ($i=0; $i < $this->_numOfFields; $i++) {
381  $o = $this->FetchField($i);
382  $this->bind[strtoupper($o->name)] = $i;
383  }
384  }
385 
386  return $this->fields[$this->bind[strtoupper($colname)]];
387  }
388 
389 
390  function _initrs()
391  {
392  $rs = $this->_queryID;
393  $this->_numOfRows = $rs->RecordCount;
394 
395  $f = $rs->Fields;
396  $this->_numOfFields = $f->Count;
397  }
398 
399 
400  // should only be used to move forward as we normally use forward-only cursors
401  function _seek($row)
402  {
403  $rs = $this->_queryID;
404  // absoluteposition doesn't work -- my maths is wrong ?
405  // $rs->AbsolutePosition->$row-2;
406  // return true;
407  if ($this->_currentRow > $row) return false;
408  @$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
409  return true;
410  }
411 
412 /*
413  OLEDB types
414 
415  enum DBTYPEENUM
416  { DBTYPE_EMPTY = 0,
417  DBTYPE_NULL = 1,
418  DBTYPE_I2 = 2,
419  DBTYPE_I4 = 3,
420  DBTYPE_R4 = 4,
421  DBTYPE_R8 = 5,
422  DBTYPE_CY = 6,
423  DBTYPE_DATE = 7,
424  DBTYPE_BSTR = 8,
425  DBTYPE_IDISPATCH = 9,
426  DBTYPE_ERROR = 10,
427  DBTYPE_BOOL = 11,
428  DBTYPE_VARIANT = 12,
429  DBTYPE_IUNKNOWN = 13,
430  DBTYPE_DECIMAL = 14,
431  DBTYPE_UI1 = 17,
432  DBTYPE_ARRAY = 0x2000,
433  DBTYPE_BYREF = 0x4000,
434  DBTYPE_I1 = 16,
435  DBTYPE_UI2 = 18,
436  DBTYPE_UI4 = 19,
437  DBTYPE_I8 = 20,
438  DBTYPE_UI8 = 21,
439  DBTYPE_GUID = 72,
440  DBTYPE_VECTOR = 0x1000,
441  DBTYPE_RESERVED = 0x8000,
442  DBTYPE_BYTES = 128,
443  DBTYPE_STR = 129,
444  DBTYPE_WSTR = 130,
445  DBTYPE_NUMERIC = 131,
446  DBTYPE_UDT = 132,
447  DBTYPE_DBDATE = 133,
448  DBTYPE_DBTIME = 134,
449  DBTYPE_DBTIMESTAMP = 135
450 
451  ADO Types
452 
453  adEmpty = 0,
454  adTinyInt = 16,
455  adSmallInt = 2,
456  adInteger = 3,
457  adBigInt = 20,
458  adUnsignedTinyInt = 17,
459  adUnsignedSmallInt = 18,
460  adUnsignedInt = 19,
461  adUnsignedBigInt = 21,
462  adSingle = 4,
463  adDouble = 5,
464  adCurrency = 6,
465  adDecimal = 14,
466  adNumeric = 131,
467  adBoolean = 11,
468  adError = 10,
469  adUserDefined = 132,
470  adVariant = 12,
471  adIDispatch = 9,
472  adIUnknown = 13,
473  adGUID = 72,
474  adDate = 7,
475  adDBDate = 133,
476  adDBTime = 134,
477  adDBTimeStamp = 135,
478  adBSTR = 8,
479  adChar = 129,
480  adVarChar = 200,
481  adLongVarChar = 201,
482  adWChar = 130,
483  adVarWChar = 202,
484  adLongVarWChar = 203,
485  adBinary = 128,
486  adVarBinary = 204,
487  adLongVarBinary = 205,
488  adChapter = 136,
489  adFileTime = 64,
490  adDBFileTime = 137,
491  adPropVariant = 138,
492  adVarNumeric = 139
493 */
494  function MetaType($t,$len=-1,$fieldobj=false)
495  {
496  if (is_object($t)) {
497  $fieldobj = $t;
498  $t = $fieldobj->type;
499  $len = $fieldobj->max_length;
500  }
501 
502  if (!is_numeric($t)) return $t;
503 
504  switch ($t) {
505  case 0:
506  case 12: // variant
507  case 8: // bstr
508  case 129: //char
509  case 130: //wc
510  case 200: // varc
511  case 202:// varWC
512  case 128: // bin
513  case 204: // varBin
514  case 72: // guid
515  if ($len <= $this->blobSize) return 'C';
516 
517  case 201:
518  case 203:
519  return 'X';
520  case 128:
521  case 204:
522  case 205:
523  return 'B';
524  case 7:
525  case 133: return 'D';
526 
527  case 134:
528  case 135: return 'T';
529 
530  case 11: return 'L';
531 
532  case 16:// adTinyInt = 16,
533  case 2://adSmallInt = 2,
534  case 3://adInteger = 3,
535  case 4://adBigInt = 20,
536  case 17://adUnsignedTinyInt = 17,
537  case 18://adUnsignedSmallInt = 18,
538  case 19://adUnsignedInt = 19,
539  case 20://adUnsignedBigInt = 21,
540  return 'I';
541  default: return 'N';
542  }
543  }
544 
545  // time stamp not supported yet
546  function _fetch()
547  {
548  $rs = $this->_queryID;
549  if (!$rs or $rs->EOF) {
550  $this->fields = false;
551  return false;
552  }
553  $this->fields = array();
554 
555  if (!$this->_tarr) {
556  $tarr = array();
557  $flds = array();
558  for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
559  $f = $rs->Fields($i);
560  $flds[] = $f;
561  $tarr[] = $f->Type;
562  }
563  // bind types and flds only once
564  $this->_tarr = $tarr;
565  $this->_flds = $flds;
566  }
567  $t = reset($this->_tarr);
568  $f = reset($this->_flds);
569 
570  if ($this->hideErrors) $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
571  for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
572  //echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
573  switch($t) {
574  case 135: // timestamp
575  if (!strlen((string)$f->value)) $this->fields[] = false;
576  else {
577  if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value);
578  // VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00
579  $val=(float) variant_cast($f->value,VT_R8)*3600*24-2209161600;
580  else
581  $val = $f->value;
582  $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
583  }
584  break;
585  case 133:// A date value (yyyymmdd)
586  if ($val = $f->value) {
587  $this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
588  } else
589  $this->fields[] = false;
590  break;
591  case 7: // adDate
592  if (!strlen((string)$f->value)) $this->fields[] = false;
593  else {
594  if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
595  else $val = $f->value;
596 
597  if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val);
598  else $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
599  }
600  break;
601  case 1: // null
602  $this->fields[] = false;
603  break;
604  case 6: // currency is not supported properly;
605  ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>');
606  $this->fields[] = (float) $f->value;
607  break;
608  case 11: //BIT;
609  $val = "";
610  if(is_bool($f->value)) {
611  if($f->value==true) $val = 1;
612  else $val = 0;
613  }
614  if(is_null($f->value)) $val = null;
615 
616  $this->fields[] = $val;
617  break;
618  default:
619  $this->fields[] = $f->value;
620  break;
621  }
622  //print " $f->value $t, ";
623  $f = next($this->_flds);
624  $t = next($this->_tarr);
625  } // for
626  if ($this->hideErrors) error_reporting($olde);
627  @$rs->MoveNext(); // @ needed for some versions of PHP!
628 
629  if ($this->fetchMode & ADODB_FETCH_ASSOC) {
630  $this->fields = $this->GetRowAssoc();
631  }
632  return true;
633  }
634 
635  function NextRecordSet()
636  {
637  $rs = $this->_queryID;
638  $this->_queryID = $rs->NextRecordSet();
639  //$this->_queryID = $this->_QueryId->NextRecordSet();
640  if ($this->_queryID == null) return false;
641 
642  $this->_currentRow = -1;
643  $this->_currentPage = -1;
644  $this->bind = false;
645  $this->fields = false;
646  $this->_flds = false;
647  $this->_tarr = false;
648 
649  $this->_inited = false;
650  $this->Init();
651  return true;
652  }
653 
654  function _close() {
655  $this->_flds = false;
656  @$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
657  $this->_queryID = false;
658  }
659 
660 }
__construct($id, $mode=false)
MetaTables($ttype=false, $showSchema=false, $mask=false)
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:94
debug($variable='', $name=' *variable *', $line=' *line *', $file=' *file *', $recursiveDepth=3, $debugLevel='E_DEBUG')
_query($sql, $inputarr=false)
_connect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
adodb_date($fmt, $d=false, $is_gmt=false)
CommitTrans($ok=true)
MetaColumns($table, $normalize=true)
MetaType($t, $len=-1, $fieldobj=false)
_pconnect($argHostname, $argUsername, $argPassword, $argProvider='MSDASQL')
FetchField($fieldOffset=-1)
$sql
Definition: server.php:84