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