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