C:/lib/adodb/drivers/adodb-ado.inc.php Quellcode

adodb-ado.inc.php
gehe zur Dokumentation dieser Datei
1 <?php
2 /*
3 V5.19dev ??-???-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 }
659 
660 ?>




Korrekturen, Hinweise und Ergänzungen

Bitte scheuen Sie sich nicht und melden Sie, was auf dieser Seite sachlich falsch oder irreführend ist, was ergänzt werden sollte, was fehlt usw. Dazu bitte oben aus dem Menü Seite den Eintrag Support Forum wählen. Es ist eine kostenlose Anmeldung erforderlich, um Anmerkungen zu posten. Unpassende Postings, Spam usw. werden kommentarlos entfernt.