source: tmp/version-2_5-test/data/module/adodb/drivers/adodb-ado.inc.php @ 18609

Revision 18609, 15.4 KB checked in by kajiwara, 14 years ago (diff)

正式版にナイトリービルド版をマージしてみるテスト

Line 
1<?php
2/*
3v4.992 10 Nov 2009  (c) 2000-2009 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.
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            case 11: //BIT;
591                $val = "";
592                if(is_bool($f->value))  {
593                    if($f->value==true) $val = 1;
594                    else $val = 0;
595                }
596                if(is_null($f->value)) $val = null;
597               
598                $this->fields[] = $val;
599                break;
600
601            default:
602                $this->fields[] = $f->value;
603                break;
604            }
605            //print " $f->value $t, ";
606            $f = next($this->_flds);
607            $t = next($this->_tarr);
608        } // for
609        if ($this->hideErrors) error_reporting($olde);
610        @$rs->MoveNext(); // @ needed for some versions of PHP!
611       
612        if ($this->fetchMode & ADODB_FETCH_ASSOC) {
613            $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);
614        }
615        return true;
616    }
617   
618        function NextRecordSet()
619        {
620            $rs = $this->_queryID;
621            $this->_queryID = $rs->NextRecordSet();
622            //$this->_queryID = $this->_QueryId->NextRecordSet();
623            if ($this->_queryID == null) return false;
624           
625            $this->_currentRow = -1;
626            $this->_currentPage = -1;
627            $this->bind = false;
628            $this->fields = false;
629            $this->_flds = false;
630            $this->_tarr = false;
631           
632            $this->_inited = false;
633            $this->Init();
634            return true;
635        }
636
637    function _close() {
638        $this->_flds = false;
639        @$this->_queryID->Close();// by Pete Dishman (peterd@telephonetics.co.uk)
640        $this->_queryID = false;   
641    }
642
643}
644
645?>
Note: See TracBrowser for help on using the repository browser.