source: trunk/phpgwapi/inc/adodb/drivers/adodb-ado.inc.php @ 34

Revision 34, 15.2 KB checked in by niltonneto, 17 years ago (diff)

Versão nova do ADODB (4.5 para 4.95)

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2/*
3V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). 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.
7Set 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
15if (!defined('ADODB_DIR')) die();
16       
17define("_ADODB_ADO_LAYER", 1 );
18/*--------------------------------------------------------------------------------------
19--------------------------------------------------------------------------------------*/
20
21       
22class 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;
32        var $_thisTransactions;
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)
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                        foreach($inputarr as $val) {
225                                // name, type, direction 1 = input, len,
226                                $this->adoParameterType = 130;
227                                $p = $oCmd->CreateParameter('name',$this->adoParameterType,1,strlen($val),$val);
228                                //print $p->Type.' '.$p->value;
229                                $oCmd->Parameters->Append($p);
230                        }
231                        $p = false;
232                        $rs = $oCmd->Execute();
233                        $e = $dbc->Errors;
234                        if ($dbc->Errors->Count > 0) return $false;
235                        return $rs;
236                }
237               
238                $rs = @$dbc->Execute($sql,$this->_affectedRows, $this->_execute_option);
239
240                if ($dbc->Errors->Count > 0) return $false;
241                if (! $rs) return $false;
242               
243                if ($rs->State == 0) {
244                        $true = true;
245                        return $true; // 0 = adStateClosed means no records returned
246                }
247                return $rs;
248        }
249
250       
251        function BeginTrans()
252        {
253                if ($this->transOff) return true;
254               
255                if (isset($this->_thisTransactions))
256                        if (!$this->_thisTransactions) return false;
257                else {
258                        $o = $this->_connectionID->Properties("Transaction DDL");
259                        $this->_thisTransactions = $o ? true : false;
260                        if (!$o) return false;
261                }
262                @$this->_connectionID->BeginTrans();
263                $this->transCnt += 1;
264                return true;
265        }
266       
267        function CommitTrans($ok=true)
268        {
269                if (!$ok) return $this->RollbackTrans();
270                if ($this->transOff) return true;
271               
272                @$this->_connectionID->CommitTrans();
273                if ($this->transCnt) @$this->transCnt -= 1;
274                return true;
275        }
276        function RollbackTrans() {
277                if ($this->transOff) return true;
278                @$this->_connectionID->RollbackTrans();
279                if ($this->transCnt) @$this->transCnt -= 1;
280                return true;
281        }
282       
283        /*      Returns: the last error message from previous database operation        */     
284
285        function ErrorMsg()
286        {
287                if (!$this->_connectionID) return "No connection established";
288                $errc = $this->_connectionID->Errors;
289                if (!$errc) return "No Errors object found";
290                if ($errc->Count == 0) return '';
291                $err = $errc->Item($errc->Count-1);
292                return $err->Description;
293        }
294       
295        function ErrorNo()
296        {
297                $errc = $this->_connectionID->Errors;
298                if ($errc->Count == 0) return 0;
299                $err = $errc->Item($errc->Count-1);
300                return $err->NativeError;
301        }
302
303        // returns true or false
304        function _close()
305        {
306                if ($this->_connectionID) $this->_connectionID->Close();
307                $this->_connectionID = false;
308                return true;
309        }
310       
311       
312}
313       
314/*--------------------------------------------------------------------------------------
315         Class Name: Recordset
316--------------------------------------------------------------------------------------*/
317
318class ADORecordSet_ado extends ADORecordSet {   
319       
320        var $bind = false;
321        var $databaseType = "ado";     
322        var $dataProvider = "ado";     
323        var $_tarr = false; // caches the types
324        var $_flds; // and field objects
325        var $canSeek = true;
326        var $hideErrors = true;
327                 
328        function ADORecordSet_ado($id,$mode=false)
329        {
330                if ($mode === false) {
331                        global $ADODB_FETCH_MODE;
332                        $mode = $ADODB_FETCH_MODE;
333                }
334                $this->fetchMode = $mode;
335                return $this->ADORecordSet($id,$mode);
336        }
337
338
339        // returns the field object
340        function &FetchField($fieldOffset = -1) {
341                $off=$fieldOffset+1; // offsets begin at 1
342               
343                $o= new ADOFieldObject();
344                $rs = $this->_queryID;
345                $f = $rs->Fields($fieldOffset);
346                $o->name = $f->Name;
347                $t = $f->Type;
348                $o->type = $this->MetaType($t);
349                $o->max_length = $f->DefinedSize;
350                $o->ado_type = $t;     
351
352                //print "off=$off name=$o->name type=$o->type len=$o->max_length<br>";
353                return $o;
354        }
355       
356        /* Use associative array to get fields array */
357        function Fields($colname)
358        {
359                if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];
360                if (!$this->bind) {
361                        $this->bind = array();
362                        for ($i=0; $i < $this->_numOfFields; $i++) {
363                                $o = $this->FetchField($i);
364                                $this->bind[strtoupper($o->name)] = $i;
365                        }
366                }
367               
368                 return $this->fields[$this->bind[strtoupper($colname)]];
369        }
370
371               
372        function _initrs()
373        {
374                $rs = $this->_queryID;
375                $this->_numOfRows = $rs->RecordCount;
376               
377                $f = $rs->Fields;
378                $this->_numOfFields = $f->Count;
379        }
380       
381       
382         // should only be used to move forward as we normally use forward-only cursors
383        function _seek($row)
384        {
385           $rs = $this->_queryID;
386                // absoluteposition doesn't work -- my maths is wrong ?
387                //      $rs->AbsolutePosition->$row-2;
388                //      return true;
389                if ($this->_currentRow > $row) return false;
390                @$rs->Move((integer)$row - $this->_currentRow-1); //adBookmarkFirst
391                return true;
392        }
393       
394/*
395        OLEDB types
396       
397         enum DBTYPEENUM
398        {       DBTYPE_EMPTY    = 0,
399        DBTYPE_NULL     = 1,
400        DBTYPE_I2       = 2,
401        DBTYPE_I4       = 3,
402        DBTYPE_R4       = 4,
403        DBTYPE_R8       = 5,
404        DBTYPE_CY       = 6,
405        DBTYPE_DATE     = 7,
406        DBTYPE_BSTR     = 8,
407        DBTYPE_IDISPATCH        = 9,
408        DBTYPE_ERROR    = 10,
409        DBTYPE_BOOL     = 11,
410        DBTYPE_VARIANT  = 12,
411        DBTYPE_IUNKNOWN = 13,
412        DBTYPE_DECIMAL  = 14,
413        DBTYPE_UI1      = 17,
414        DBTYPE_ARRAY    = 0x2000,
415        DBTYPE_BYREF    = 0x4000,
416        DBTYPE_I1       = 16,
417        DBTYPE_UI2      = 18,
418        DBTYPE_UI4      = 19,
419        DBTYPE_I8       = 20,
420        DBTYPE_UI8      = 21,
421        DBTYPE_GUID     = 72,
422        DBTYPE_VECTOR   = 0x1000,
423        DBTYPE_RESERVED = 0x8000,
424        DBTYPE_BYTES    = 128,
425        DBTYPE_STR      = 129,
426        DBTYPE_WSTR     = 130,
427        DBTYPE_NUMERIC  = 131,
428        DBTYPE_UDT      = 132,
429        DBTYPE_DBDATE   = 133,
430        DBTYPE_DBTIME   = 134,
431        DBTYPE_DBTIMESTAMP      = 135
432       
433        ADO Types
434       
435        adEmpty = 0,
436        adTinyInt       = 16,
437        adSmallInt      = 2,
438        adInteger       = 3,
439        adBigInt        = 20,
440        adUnsignedTinyInt       = 17,
441        adUnsignedSmallInt      = 18,
442        adUnsignedInt   = 19,
443        adUnsignedBigInt        = 21,
444        adSingle        = 4,
445        adDouble        = 5,
446        adCurrency      = 6,
447        adDecimal       = 14,
448        adNumeric       = 131,
449        adBoolean       = 11,
450        adError = 10,
451        adUserDefined   = 132,
452        adVariant       = 12,
453        adIDispatch     = 9,
454        adIUnknown      = 13,   
455        adGUID  = 72,
456        adDate  = 7,
457        adDBDate        = 133,
458        adDBTime        = 134,
459        adDBTimeStamp   = 135,
460        adBSTR  = 8,
461        adChar  = 129,
462        adVarChar       = 200,
463        adLongVarChar   = 201,
464        adWChar = 130,
465        adVarWChar      = 202,
466        adLongVarWChar  = 203,
467        adBinary        = 128,
468        adVarBinary     = 204,
469        adLongVarBinary = 205,
470        adChapter       = 136,
471        adFileTime      = 64,
472        adDBFileTime    = 137,
473        adPropVariant   = 138,
474        adVarNumeric    = 139
475*/
476        function MetaType($t,$len=-1,$fieldobj=false)
477        {
478                if (is_object($t)) {
479                        $fieldobj = $t;
480                        $t = $fieldobj->type;
481                        $len = $fieldobj->max_length;
482                }
483               
484                if (!is_numeric($t)) return $t;
485               
486                switch ($t) {
487                case 0:
488                case 12: // variant
489                case 8: // bstr
490                case 129: //char
491                case 130: //wc
492                case 200: // varc
493                case 202:// varWC
494                case 128: // bin
495                case 204: // varBin
496                case 72: // guid
497                        if ($len <= $this->blobSize) return 'C';
498               
499                case 201:
500                case 203:
501                        return 'X';
502                case 128:
503                case 204:
504                case 205:
505                         return 'B';
506                case 7:
507                case 133: return 'D';
508               
509                case 134:
510                case 135: return 'T';
511               
512                case 11: return 'L';
513               
514                case 16://      adTinyInt       = 16,
515                case 2://adSmallInt     = 2,
516                case 3://adInteger      = 3,
517                case 4://adBigInt       = 20,
518                case 17://adUnsignedTinyInt     = 17,
519                case 18://adUnsignedSmallInt    = 18,
520                case 19://adUnsignedInt = 19,
521                case 20://adUnsignedBigInt      = 21,
522                        return 'I';
523                default: return 'N';
524                }
525        }
526       
527        // time stamp not supported yet
528        function _fetch()
529        {       
530                $rs = $this->_queryID;
531                if (!$rs or $rs->EOF) {
532                        $this->fields = false;
533                        return false;
534                }
535                $this->fields = array();
536       
537                if (!$this->_tarr) {
538                        $tarr = array();
539                        $flds = array();
540                        for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
541                                $f = $rs->Fields($i);
542                                $flds[] = $f;
543                                $tarr[] = $f->Type;
544                        }
545                        // bind types and flds only once
546                        $this->_tarr = $tarr;
547                        $this->_flds = $flds;
548                }
549                $t = reset($this->_tarr);
550                $f = reset($this->_flds);
551               
552                if ($this->hideErrors)  $olde = error_reporting(E_ERROR|E_CORE_ERROR);// sometimes $f->value be null
553                for ($i=0,$max = $this->_numOfFields; $i < $max; $i++) {
554                        //echo "<p>",$t,' ';var_dump($f->value); echo '</p>';
555                        switch($t) {
556                        case 135: // timestamp
557                                if (!strlen((string)$f->value)) $this->fields[] = false;
558                                else {
559                                        if (!is_numeric($f->value)) # $val = variant_date_to_timestamp($f->value);
560                                                // VT_DATE stores dates as (float) fractional days since 1899/12/30 00:00:00
561                                                $val=(float) variant_cast($f->value,VT_R8)*3600*24-2209161600;
562                                        else
563                                                $val = $f->value;
564                                        $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
565                                }
566                                break;                 
567                        case 133:// A date value (yyyymmdd)
568                                if ($val = $f->value) {
569                                        $this->fields[] = substr($val,0,4).'-'.substr($val,4,2).'-'.substr($val,6,2);
570                                } else
571                                        $this->fields[] = false;
572                                break;
573                        case 7: // adDate
574                                if (!strlen((string)$f->value)) $this->fields[] = false;
575                                else {
576                                        if (!is_numeric($f->value)) $val = variant_date_to_timestamp($f->value);
577                                        else $val = $f->value;
578                                       
579                                        if (($val % 86400) == 0) $this->fields[] = adodb_date('Y-m-d',$val);
580                                        else $this->fields[] = adodb_date('Y-m-d H:i:s',$val);
581                                }
582                                break;
583                        case 1: // null
584                                $this->fields[] = false;
585                                break;
586                        case 6: // currency is not supported properly;
587                                ADOConnection::outp( '<b>'.$f->Name.': currency type not supported by PHP</b>');
588                                $this->fields[] = (float) $f->value;
589                                break;
590                        default:
591                                $this->fields[] = $f->value;
592                                break;
593                        }
594                        //print " $f->value $t, ";
595                        $f = next($this->_flds);
596                        $t = next($this->_tarr);
597                } // for
598                if ($this->hideErrors) error_reporting($olde);
599                @$rs->MoveNext(); // @ needed for some versions of PHP!
600               
601                if ($this->fetchMode & ADODB_FETCH_ASSOC) {
602                        $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
603                }
604                return true;
605        }
606       
607                function NextRecordSet()
608                {
609                        $rs = $this->_queryID;
610                        $this->_queryID = $rs->NextRecordSet();
611                        //$this->_queryID = $this->_QueryId->NextRecordSet();
612                        if ($this->_queryID == null) return false;
613                       
614                        $this->_currentRow = -1;
615                        $this->_currentPage = -1;
616                        $this->bind = false;
617                        $this->fields = false;
618                        $this->_flds = false;
619                        $this->_tarr = false;
620                       
621                        $this->_inited = false;
622                        $this->Init();
623                        return true;
624                }
625
626        function _close() {
627                $this->_flds = false;
628                @$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
629                $this->_queryID = false;       
630        }
631
632}
633
634?>
Note: See TracBrowser for help on using the repository browser.