Ignore:
Timestamp:
06/29/07 15:17:46 (17 years ago)
Author:
niltonneto
Message:

Versão nova do ADODB (4.5 para 4.95)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/phpgwapi/inc/adodb/drivers/adodb-db2.inc.php

    r2 r34  
    11<?php 
    22/*  
    3 V4.51 29 July 2004  (c) 2000-2004 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.  
    7 Set tabs to 4 for best viewing. 
    8    
    9   Latest version is available at http://adodb.sourceforge.net 
    10    
    11   DB2 data driver. Requires ODBC. 
    12   
    13 From phpdb list: 
    14  
    15 Hi Andrew, 
    16  
    17 thanks a lot for your help. Today we discovered what 
    18 our real problem was: 
    19  
    20 After "playing" a little bit with the php-scripts that try 
    21 to connect to the IBM DB2, we set the optional parameter 
    22 Cursortype when calling odbc_pconnect(....). 
    23  
    24 And the exciting thing: When we set the cursor type 
    25 to SQL_CUR_USE_ODBC Cursor Type, then 
    26 the whole query speed up from 1 till 10 seconds 
    27 to 0.2 till 0.3 seconds for 100 records. Amazing!!! 
    28  
    29 Therfore, PHP is just almost fast as calling the DB2 
    30 from Servlets using JDBC (don't take too much care 
    31 about the speed at whole: the database was on a 
    32 completely other location, so the whole connection 
    33 was made over a slow network connection). 
    34  
    35 I hope this helps when other encounter the same 
    36 problem when trying to connect to DB2 from 
    37 PHP. 
    38  
    39 Kind regards, 
    40 Christian Szardenings 
    41  
    42 2 Oct 2001 
    43 Mark Newnham has discovered that the SQL_CUR_USE_ODBC is not supported by  
    44 IBM's DB2 ODBC driver, so this must be a 3rd party ODBC driver. 
    45  
    46 From the IBM CLI Reference: 
    47  
    48 SQL_ATTR_ODBC_CURSORS (DB2 CLI v5)  
    49 This connection attribute is defined by ODBC, but is not supported by DB2 
    50 CLI. Any attempt to set or get this attribute will result in an SQLSTATE of 
    51 HYC00 (Driver not capable).  
    52  
    53 A 32-bit option specifying how the Driver Manager uses the ODBC cursor 
    54 library.  
    55  
    56 So I guess this means the message [above] was related to using a 3rd party 
    57 odbc driver. 
    58  
    59 Setting SQL_CUR_USE_ODBC 
    60 ======================== 
    61 To set SQL_CUR_USE_ODBC for drivers that require it, do this: 
    62  
    63 $db = NewADOConnection('db2'); 
    64 $db->curMode = SQL_CUR_USE_ODBC; 
    65 $db->Connect($dsn, $userid, $pwd); 
    66  
    67  
    68  
    69 USING CLI INTERFACE 
    70 =================== 
    71  
    72 I have had reports that the $host and $database params have to be reversed in  
    73 Connect() when using the CLI interface. From Halmai Csongor csongor.halmai#nexum.hu: 
    74  
    75 > The symptom is that if I change the database engine from postgres or any other to DB2 then the following 
    76 > connection command becomes wrong despite being described this version to be correct in the docs.  
    77 > 
    78 > $connection_object->Connect( $DATABASE_HOST, $DATABASE_AUTH_USER_NAME, $DATABASE_AUTH_PASSWORD, $DATABASE_NAME ) 
    79 > 
    80 > In case of DB2 I had to swap the first and last arguments in order to connect properly.  
    81  
    82  
     3  V4.94 23 Jan 2007  (c) 2006 John Lim (jlim#natsoft.com.my). All rights reserved. 
     4 
     5  This is a version of the ADODB driver for DB2.  It uses the 'ibm_db2' PECL extension 
     6  for PHP (http://pecl.php.net/package/ibm_db2), which in turn requires DB2 V8.2.2 or 
     7  higher. 
     8 
     9  Originally tested with PHP 5.1.1 and Apache 2.0.55 on Windows XP SP2. 
     10  More recently tested with PHP 5.1.2 and Apache 2.0.55 on Windows XP SP2. 
     11 
     12  This file was ported from "adodb-odbc.inc.php" by Larry Menard, "larry.menard#rogers.com". 
     13  I ripped out what I believed to be a lot of redundant or obsolete code, but there are 
     14  probably still some remnants of the ODBC support in this file; I'm relying on reviewers 
     15  of this code to point out any other things that can be removed. 
    8316*/ 
    8417 
     
    8619if (!defined('ADODB_DIR')) die(); 
    8720 
    88 if (!defined('_ADODB_ODBC_LAYER')) { 
    89         include(ADODB_DIR."/drivers/adodb-odbc.inc.php"); 
    90 } 
    91 if (!defined('ADODB_DB2')){ 
    92 define('ADODB_DB2',1); 
    93  
    94 class ADODB_DB2 extends ADODB_odbc { 
     21  define("_ADODB_DB2_LAYER", 2 ); 
     22          
     23/*-------------------------------------------------------------------------------------- 
     24--------------------------------------------------------------------------------------*/ 
     25 
     26 
     27class ADODB_db2 extends ADOConnection { 
    9528        var $databaseType = "db2";       
     29        var $fmtDate = "'Y-m-d'"; 
    9630        var $concat_operator = '||'; 
    97         var $sysDate = 'CURRENT_DATE'; 
     31         
     32        var $sysTime = 'CURRENT TIME'; 
     33        var $sysDate = 'CURRENT DATE'; 
    9834        var $sysTimeStamp = 'CURRENT TIMESTAMP'; 
    99         // The complete string representation of a timestamp has the form  
    100         // yyyy-mm-dd-hh.mm.ss.nnnnnn. 
    101         var $fmtTimeStamp = "'Y-m-d-H.i.s'"; 
    102         var $ansiOuter = true; 
    103         var $identitySQL = 'values IDENTITY_VAL_LOCAL()'; 
    104         var $_bindInputArray = true; 
    105          var $hasInsertID = true; 
    106          
    107         function ADODB_DB2() 
    108         { 
    109                 if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC; 
    110                 $this->ADODB_odbc(); 
    111         } 
    112          
    113         function IfNull( $field, $ifNull )  
    114         { 
    115                 return " COALESCE($field, $ifNull) "; // if DB2 UDB 
    116         } 
    117          
    118         function ServerInfo() 
    119         { 
    120                 //odbc_setoption($this->_connectionID,1,101 /*SQL_ATTR_ACCESS_MODE*/, 1 /*SQL_MODE_READ_ONLY*/); 
    121                 $vers = $this->GetOne('select versionnumber from sysibm.sysversions'); 
    122                 //odbc_setoption($this->_connectionID,1,101, 0 /*SQL_MODE_READ_WRITE*/); 
    123                 return array('description'=>'DB2 ODBC driver', 'version'=>$vers); 
    124         } 
    125          
    126         function _insertid() 
    127         { 
    128                 return $this->GetOne($this->identitySQL); 
    129         } 
    130          
    131         function RowLock($tables,$where) 
    132         { 
    133                 if ($this->_autocommit) $this->BeginTrans(); 
    134                 return $this->GetOne("select 1 as ignore from $tables where $where for update"); 
    135         } 
    136          
    137         function &MetaTables($ttype=false,$showSchema=false, $qtable="%", $qschema="%") 
    138         { 
    139         global $ADODB_FETCH_MODE; 
    140          
    141                 $savem = $ADODB_FETCH_MODE; 
    142                 $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
    143                 $qid = odbc_tables($this->_connectionID, "", $qschema, $qtable, ""); 
    144                  
    145                 $rs = new ADORecordSet_odbc($qid); 
    146                  
    147                 $ADODB_FETCH_MODE = $savem; 
    148                 if (!$rs) return false; 
    149                  
    150                 $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change; 
    151                  
    152                 $arr =& $rs->GetArray(); 
    153                 //print_r($arr); 
    154                  
    155                 $rs->Close(); 
    156                 $arr2 = array(); 
    157                  
    158                 if ($ttype) { 
    159                         $isview = strncmp($ttype,'V',1) === 0; 
    160                 } 
    161                 for ($i=0; $i < sizeof($arr); $i++) { 
    162                  
    163                         if (!$arr[$i][2]) continue; 
    164                         if (strncmp($arr[$i][1],'SYS',3) === 0) continue; 
    165                          
    166                         $type = $arr[$i][3]; 
    167                          
    168                         if ($showSchema) $arr[$i][2] = $arr[$i][1].'.'.$arr[$i][2]; 
    169                          
    170                         if ($ttype) {  
    171                                 if ($isview) { 
    172                                         if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2]; 
    173                                 } else if (strncmp($type,'T',1) === 0) $arr2[] = $arr[$i][2]; 
    174                         } else if (strncmp($type,'S',1) !== 0) $arr2[] = $arr[$i][2]; 
    175                 } 
    176                 return $arr2; 
    177         } 
    178          
     35         
     36        var $fmtTimeStamp = "'Y-m-d-H:i:s'"; 
     37        var $replaceQuote = "''"; // string to use to replace quotes 
     38        var $dataProvider = "db2"; 
     39        var $hasAffectedRows = true; 
     40 
     41        var $binmode = DB2_BINARY; 
     42 
     43        var $useFetchArray = false; // setting this to true will make array elements in FETCH_ASSOC mode case-sensitive 
     44                                                                // breaking backward-compat 
     45        var $_bindInputArray = false;    
     46        var $_genIDSQL = "VALUES NEXTVAL FOR %s"; 
     47        var $_genSeqSQL = "CREATE SEQUENCE %s START WITH 1 NO MAXVALUE NO CYCLE"; 
     48        var $_dropSeqSQL = "DROP SEQUENCE %s"; 
     49        var $_autocommit = true; 
     50        var $_haserrorfunctions = true; 
     51        var $_lastAffectedRows = 0; 
     52        var $uCaseTables = true; // for meta* functions, uppercase table names 
     53        var $hasInsertID = true; 
     54         
     55    function _insertid() 
     56    { 
     57        return ADOConnection::GetOne('VALUES IDENTITY_VAL_LOCAL()'); 
     58    } 
     59         
     60        function ADODB_db2()  
     61        {        
     62                $this->_haserrorfunctions = ADODB_PHPVER >= 0x4050; 
     63        } 
     64         
     65                // returns true or false 
     66        function _connect($argDSN, $argUsername, $argPassword, $argDatabasename) 
     67        { 
     68                global $php_errormsg; 
     69                 
     70                if (!function_exists('db2_connect')) { 
     71                        ADOConnection::outp("Warning: The old ODBC based DB2 driver has been renamed 'odbc_db2'. This ADOdb driver calls PHP's native db2 extension."); 
     72                        return null; 
     73                } 
     74                // This needs to be set before the connect(). 
     75                // Replaces the odbc_binmode() call that was in Execute() 
     76                ini_set('ibm_db2.binmode', $this->binmode); 
     77 
     78                if ($argDatabasename) { 
     79                        $this->_connectionID = db2_connect($argDatabasename,$argUsername,$argPassword); 
     80                } else { 
     81                        $this->_connectionID = db2_connect($argDSN,$argUsername,$argPassword); 
     82                } 
     83                if (isset($php_errormsg)) $php_errormsg = ''; 
     84 
     85                // For db2_connect(), there is an optional 4th arg.  If present, it must be 
     86                // an array of valid options.  So far, we don't use them. 
     87 
     88                $this->_errorMsg = @db2_conn_errormsg(); 
     89  
     90                if (isset($this->connectStmt)) $this->Execute($this->connectStmt); 
     91                 
     92                return $this->_connectionID != false; 
     93        } 
     94         
     95        // returns true or false 
     96        function _pconnect($argDSN, $argUsername, $argPassword, $argDatabasename) 
     97        { 
     98                global $php_errormsg; 
     99         
     100                if (!function_exists('db2_connect')) return null; 
     101                 
     102                // This needs to be set before the connect(). 
     103                // Replaces the odbc_binmode() call that was in Execute() 
     104                ini_set('ibm_db2.binmode', $this->binmode); 
     105 
     106                if (isset($php_errormsg)) $php_errormsg = ''; 
     107                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 
     108                 
     109                if ($argDatabasename) { 
     110                        $this->_connectionID = db2_pconnect($argDatabasename,$argUsername,$argPassword); 
     111                } else { 
     112                        $this->_connectionID = db2_pconnect($argDSN,$argUsername,$argPassword); 
     113                } 
     114                if (isset($php_errormsg)) $php_errormsg = ''; 
     115 
     116                $this->_errorMsg = @db2_conn_errormsg(); 
     117                if ($this->_connectionID && $this->autoRollback) @db2_rollback($this->_connectionID); 
     118                if (isset($this->connectStmt)) $this->Execute($this->connectStmt); 
     119                 
     120                return $this->_connectionID != false; 
     121        } 
     122 
     123        // format and return date string in database timestamp format 
     124        function DBTimeStamp($ts) 
     125        { 
     126                if (empty($ts) && $ts !== 0) return 'null'; 
     127                if (is_string($ts)) $ts = ADORecordSet::UnixTimeStamp($ts); 
     128                return 'TO_DATE('.adodb_date($this->fmtTimeStamp,$ts).",'YYYY-MM-DD HH24:MI:SS')"; 
     129        } 
    179130         
    180131        // Format date column in sql string given an input format that understands Y M D 
     
    183134        // use right() and replace() ? 
    184135                if (!$col) $col = $this->sysDate; 
     136 
     137                /* use TO_CHAR() if $fmt is TO_CHAR() allowed fmt */ 
     138                if ($fmt== 'Y-m-d H:i:s') 
     139                        return 'TO_CHAR('.$col.", 'YYYY-MM-DD HH24:MI:SS')"; 
     140 
    185141                $s = ''; 
    186142                 
    187143                $len = strlen($fmt); 
    188144                for ($i=0; $i < $len; $i++) { 
    189                         if ($s) $s .= '||'; 
     145                        if ($s) $s .= $this->concat_operator; 
    190146                        $ch = $fmt[$i]; 
    191147                        switch($ch) { 
    192148                        case 'Y': 
    193149                        case 'y': 
     150                                if ($len==1) return "year($col)"; 
    194151                                $s .= "char(year($col))"; 
    195152                                break; 
    196153                        case 'M': 
     154                                if ($len==1) return "monthname($col)"; 
    197155                                $s .= "substr(monthname($col),1,3)"; 
    198156                                break; 
    199157                        case 'm': 
     158                                if ($len==1) return "month($col)"; 
    200159                                $s .= "right(digits(month($col)),2)"; 
    201160                                break; 
    202161                        case 'D': 
    203162                        case 'd': 
     163                                if ($len==1) return "day($col)"; 
    204164                                $s .= "right(digits(day($col)),2)"; 
    205165                                break; 
    206166                        case 'H': 
    207167                        case 'h': 
     168                                if ($len==1) return "hour($col)"; 
    208169                                if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";         
    209170                                else $s .= "''"; 
     
    211172                        case 'i': 
    212173                        case 'I': 
     174                                if ($len==1) return "minute($col)"; 
    213175                                if ($col != $this->sysDate) 
    214176                                        $s .= "right(digits(minute($col)),2)"; 
     
    217179                        case 'S': 
    218180                        case 's': 
     181                                if ($len==1) return "second($col)"; 
    219182                                if ($col != $this->sysDate) 
    220183                                        $s .= "right(digits(second($col)),2)"; 
     
    233196  
    234197         
    235         function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false) 
    236         { 
    237                 if ($offset <= 0) { 
    238                 // could also use " OPTIMIZE FOR $nrows ROWS " 
    239                         if ($nrows >= 0) $sql .=  " FETCH FIRST $nrows ROWS ONLY "; 
    240                         $rs =& $this->Execute($sql,$inputArr); 
     198        function ServerInfo() 
     199        { 
     200         
     201                if (!empty($this->host) && ADODB_PHPVER >= 0x4300) { 
     202                        $dsn = strtoupper($this->host); 
     203                        $first = true; 
     204                        $found = false; 
     205                         
     206                        if (!function_exists('db2_data_source')) return false; 
     207                         
     208                        while(true) { 
     209                                 
     210                                $rez = @db2_data_source($this->_connectionID, 
     211                                        $first ? SQL_FETCH_FIRST : SQL_FETCH_NEXT); 
     212                                $first = false; 
     213                                if (!is_array($rez)) break; 
     214                                if (strtoupper($rez['server']) == $dsn) { 
     215                                        $found = true; 
     216                                        break; 
     217                                } 
     218                        }  
     219                        if (!$found) return ADOConnection::ServerInfo(); 
     220                        if (!isset($rez['version'])) $rez['version'] = ''; 
     221                        return $rez; 
    241222                } else { 
    242                         if ($offset > 0 && $nrows < 0); 
    243                         else { 
    244                                 $nrows += $offset; 
    245                                 $sql .=  " FETCH FIRST $nrows ROWS ONLY "; 
    246                         } 
    247                         $rs =& ADOConnection::SelectLimit($sql,-1,$offset,$inputArr); 
    248                 } 
    249                  
    250                 return $rs; 
    251         } 
    252          
    253 }; 
    254   
    255  
    256 class  ADORecordSet_db2 extends ADORecordSet_odbc {      
    257          
    258         var $databaseType = "db2";               
    259          
    260         function ADORecordSet_db2($id,$mode=false) 
    261         { 
    262                 $this->ADORecordSet_odbc($id,$mode); 
    263         } 
    264  
    265         function MetaType($t,$len=-1,$fieldobj=false) 
    266         { 
    267                 if (is_object($t)) { 
    268                         $fieldobj = $t; 
    269                         $t = $fieldobj->type; 
    270                         $len = $fieldobj->max_length; 
    271                 } 
    272                  
    273                 switch (strtoupper($t)) { 
    274                 case 'VARCHAR': 
    275                 case 'CHAR': 
    276                 case 'CHARACTER': 
    277                         if ($len <= $this->blobSize) return 'C'; 
    278                  
    279                 case 'LONGCHAR': 
    280                 case 'TEXT': 
    281                 case 'CLOB': 
    282                 case 'DBCLOB': // double-byte 
     223                        return ADOConnection::ServerInfo(); 
     224                } 
     225        } 
     226 
     227         
     228        function CreateSequence($seqname='adodbseq',$start=1) 
     229        { 
     230                if (empty($this->_genSeqSQL)) return false; 
     231                $ok = $this->Execute(sprintf($this->_genSeqSQL,$seqname)); 
     232                if (!$ok) return false; 
     233                return true; 
     234        } 
     235         
     236        function DropSequence($seqname) 
     237        { 
     238                if (empty($this->_dropSeqSQL)) return false; 
     239                return $this->Execute(sprintf($this->_dropSeqSQL,$seqname)); 
     240        } 
     241         
     242        /* 
     243                This algorithm is not very efficient, but works even if table locking 
     244                is not available. 
     245                 
     246                Will return false if unable to generate an ID after $MAXLOOPS attempts. 
     247        */ 
     248        function GenID($seq='adodbseq',$start=1) 
     249        {        
     250                // if you have to modify the parameter below, your database is overloaded, 
     251                // or you need to implement generation of id's yourself! 
     252                $num = $this->GetOne("VALUES NEXTVAL FOR $seq"); 
     253                                return $num; 
     254                        } 
     255 
     256 
     257        function ErrorMsg() 
     258        { 
     259                if ($this->_haserrorfunctions) { 
     260                        if ($this->_errorMsg !== false) return $this->_errorMsg; 
     261                        if (empty($this->_connectionID)) return @db2_conn_errormsg(); 
     262                        return @db2_conn_errormsg($this->_connectionID); 
     263                } else return ADOConnection::ErrorMsg(); 
     264        } 
     265         
     266        function ErrorNo() 
     267        { 
     268                 
     269                if ($this->_haserrorfunctions) { 
     270                        if ($this->_errorCode !== false) { 
     271                                // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 
     272                                return (strlen($this->_errorCode)<=2) ? 0 : $this->_errorCode; 
     273                        } 
     274 
     275                        if (empty($this->_connectionID)) $e = @db2_conn_error();  
     276                        else $e = @db2_conn_error($this->_connectionID); 
     277                         
     278                         // bug in 4.0.6, error number can be corrupted string (should be 6 digits) 
     279                         // so we check and patch 
     280                        if (strlen($e)<=2) return 0; 
     281                        return $e; 
     282                } else return ADOConnection::ErrorNo(); 
     283        } 
     284         
     285         
     286 
     287        function BeginTrans() 
     288        {        
     289                if (!$this->hasTransactions) return false; 
     290                if ($this->transOff) return true;  
     291                $this->transCnt += 1; 
     292                $this->_autocommit = false; 
     293                return db2_autocommit($this->_connectionID,false); 
     294        } 
     295         
     296        function CommitTrans($ok=true)  
     297        {  
     298                if ($this->transOff) return true;  
     299                if (!$ok) return $this->RollbackTrans(); 
     300                if ($this->transCnt) $this->transCnt -= 1; 
     301                $this->_autocommit = true; 
     302                $ret = db2_commit($this->_connectionID); 
     303                db2_autocommit($this->_connectionID,true); 
     304                return $ret; 
     305        } 
     306         
     307        function RollbackTrans() 
     308        { 
     309                if ($this->transOff) return true;  
     310                if ($this->transCnt) $this->transCnt -= 1; 
     311                $this->_autocommit = true; 
     312                $ret = db2_rollback($this->_connectionID); 
     313                db2_autocommit($this->_connectionID,true); 
     314                return $ret; 
     315        } 
     316         
     317        function MetaPrimaryKeys($table) 
     318        { 
     319        global $ADODB_FETCH_MODE; 
     320         
     321                if ($this->uCaseTables) $table = strtoupper($table); 
     322                $schema = ''; 
     323                $this->_findschema($table,$schema); 
     324 
     325                $savem = $ADODB_FETCH_MODE; 
     326                $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
     327                $qid = @db2_primarykeys($this->_connectionID,'',$schema,$table); 
     328                 
     329                if (!$qid) { 
     330                        $ADODB_FETCH_MODE = $savem; 
     331                        return false; 
     332                } 
     333                $rs = new ADORecordSet_db2($qid); 
     334                $ADODB_FETCH_MODE = $savem; 
     335                 
     336                if (!$rs) return false; 
     337                 
     338                $arr =& $rs->GetArray(); 
     339                $rs->Close(); 
     340                $arr2 = array(); 
     341                for ($i=0; $i < sizeof($arr); $i++) { 
     342                        if ($arr[$i][3]) $arr2[] = $arr[$i][3]; 
     343                } 
     344                return $arr2; 
     345        } 
     346         
     347        function MetaForeignKeys($table, $owner = FALSE, $upper = FALSE, $asociative = FALSE ) 
     348        { 
     349        global $ADODB_FETCH_MODE; 
     350         
     351                if ($this->uCaseTables) $table = strtoupper($table); 
     352                $schema = ''; 
     353                $this->_findschema($table,$schema); 
     354 
     355                $savem = $ADODB_FETCH_MODE; 
     356                $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
     357                $qid = @db2_foreign_keys($this->_connectionID,'',$schema,$table); 
     358                if (!$qid) { 
     359                        $ADODB_FETCH_MODE = $savem; 
     360                        return false; 
     361                } 
     362                $rs = new ADORecordSet_db2($qid); 
     363 
     364                $ADODB_FETCH_MODE = $savem; 
     365                /* 
     366                $rs->fields indices 
     367                0 PKTABLE_CAT 
     368                1 PKTABLE_SCHEM 
     369                2 PKTABLE_NAME 
     370                3 PKCOLUMN_NAME 
     371                4 FKTABLE_CAT 
     372                5 FKTABLE_SCHEM 
     373                6 FKTABLE_NAME 
     374                7 FKCOLUMN_NAME 
     375                */       
     376                if (!$rs) return false; 
     377 
     378                $foreign_keys = array();                  
     379                while (!$rs->EOF) { 
     380                        if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 
     381                                if (!is_array($foreign_keys[$rs->fields[5].'.'.$rs->fields[6]]))  
     382                                        $foreign_keys[$rs->fields[5].'.'.$rs->fields[6]] = array(); 
     383                                $foreign_keys[$rs->fields[5].'.'.$rs->fields[6]][$rs->fields[7]] = $rs->fields[3];                       
     384                        } 
     385                        $rs->MoveNext(); 
     386                } 
     387 
     388                $rs->Close(); 
     389                return $foreign_key; 
     390        } 
     391         
     392         
     393        function &MetaTables($ttype=false,$schema=false) 
     394        { 
     395        global $ADODB_FETCH_MODE; 
     396         
     397                $savem = $ADODB_FETCH_MODE; 
     398                $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
     399                $qid = db2_tables($this->_connectionID); 
     400                 
     401                $rs = new ADORecordSet_db2($qid); 
     402                 
     403                $ADODB_FETCH_MODE = $savem; 
     404                if (!$rs) { 
     405                        $false = false; 
     406                        return $false; 
     407                } 
     408                 
     409                $arr =& $rs->GetArray(); 
     410                 
     411                $rs->Close(); 
     412                $arr2 = array(); 
     413                 
     414                if ($ttype) { 
     415                        $isview = strncmp($ttype,'V',1) === 0; 
     416                } 
     417                for ($i=0; $i < sizeof($arr); $i++) { 
     418                        if (!$arr[$i][2]) continue; 
     419                        $type = $arr[$i][3]; 
     420                        $schemaval = ($schema) ? $arr[$i][1].'.' : ''; 
     421                        if ($ttype) {  
     422                                if ($isview) { 
     423                                        if (strncmp($type,'V',1) === 0) $arr2[] = $schemaval.$arr[$i][2]; 
     424                                } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2]; 
     425                        } else if (strncmp($type,'SYS',3) !== 0) $arr2[] = $schemaval.$arr[$i][2]; 
     426                } 
     427                return $arr2; 
     428        } 
     429         
     430/* 
     431See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/db2/htm/db2datetime_data_type_changes.asp 
     432/ SQL data type codes / 
     433#define SQL_UNKNOWN_TYPE        0 
     434#define SQL_CHAR                        1 
     435#define SQL_NUMERIC              2 
     436#define SQL_DECIMAL              3 
     437#define SQL_INTEGER              4 
     438#define SQL_SMALLINT            5 
     439#define SQL_FLOAT                  6 
     440#define SQL_REAL                        7 
     441#define SQL_DOUBLE                8 
     442#if (DB2VER >= 0x0300) 
     443#define SQL_DATETIME            9 
     444#endif 
     445#define SQL_VARCHAR             12 
     446 
     447 
     448/ One-parameter shortcuts for date/time data types / 
     449#if (DB2VER >= 0x0300) 
     450#define SQL_TYPE_DATE     91 
     451#define SQL_TYPE_TIME     92 
     452#define SQL_TYPE_TIMESTAMP 93 
     453 
     454#define SQL_UNICODE                             (-95) 
     455#define SQL_UNICODE_VARCHAR                     (-96) 
     456#define SQL_UNICODE_LONGVARCHAR                 (-97) 
     457*/ 
     458        function DB2Types($t) 
     459        { 
     460                switch ((integer)$t) { 
     461                case 1:  
     462                case 12: 
     463                case 0: 
     464                case -95: 
     465                case -96: 
     466                        return 'C'; 
     467                case -97: 
     468                case -1: //text 
    283469                        return 'X'; 
    284                  
    285                 case 'BLOB': 
    286                 case 'GRAPHIC': 
    287                 case 'VARGRAPHIC': 
     470                case -4: //image 
    288471                        return 'B'; 
     472                                 
     473                case 9:  
     474                case 91: 
     475                        return 'D'; 
     476                 
     477                case 10: 
     478                case 11: 
     479                case 92: 
     480                case 93: 
     481                        return 'T'; 
    289482                         
    290                 case 'DATE': 
    291                         return 'D'; 
    292                  
    293                 case 'TIME': 
    294                 case 'TIMESTAMP': 
    295                         return 'T'; 
    296                  
    297                 //case 'BOOLEAN':  
    298                 //case 'BIT': 
    299                 //      return 'L'; 
    300                          
    301                 //case 'COUNTER': 
    302                 //      return 'R'; 
    303                          
    304                 case 'INT': 
    305                 case 'INTEGER': 
    306                 case 'BIGINT': 
    307                 case 'SMALLINT': 
     483                case 4: 
     484                case 5: 
     485                case -6: 
    308486                        return 'I'; 
    309487                         
    310                 default: return 'N'; 
    311                 } 
    312         } 
     488                case -11: // uniqidentifier 
     489                        return 'R'; 
     490                case -7: //bit 
     491                        return 'L'; 
     492                 
     493                default: 
     494                        return 'N'; 
     495                } 
     496        } 
     497         
     498        function &MetaColumns($table) 
     499        { 
     500        global $ADODB_FETCH_MODE; 
     501         
     502                $false = false; 
     503                if ($this->uCaseTables) $table = strtoupper($table); 
     504                $schema = ''; 
     505                $this->_findschema($table,$schema); 
     506                 
     507                $savem = $ADODB_FETCH_MODE; 
     508                $ADODB_FETCH_MODE = ADODB_FETCH_NUM; 
     509         
     510                $colname = "%"; 
     511                $qid = db2_columns($this->_connectionID, "", $schema, $table, $colname); 
     512                if (empty($qid)) return $false; 
     513                 
     514                $rs =& new ADORecordSet_db2($qid); 
     515                $ADODB_FETCH_MODE = $savem; 
     516                 
     517                if (!$rs) return $false; 
     518                $rs->_fetch(); 
     519                 
     520                $retarr = array(); 
     521                 
     522                /* 
     523                $rs->fields indices 
     524                0 TABLE_QUALIFIER 
     525                1 TABLE_SCHEM 
     526                2 TABLE_NAME 
     527                3 COLUMN_NAME 
     528                4 DATA_TYPE 
     529                5 TYPE_NAME 
     530                6 PRECISION 
     531                7 LENGTH 
     532                8 SCALE 
     533                9 RADIX 
     534                10 NULLABLE 
     535                11 REMARKS 
     536                */ 
     537                while (!$rs->EOF) { 
     538                        if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 
     539                                $fld = new ADOFieldObject(); 
     540                                $fld->name = $rs->fields[3]; 
     541                                $fld->type = $this->DB2Types($rs->fields[4]); 
     542                                 
     543                                // ref: http://msdn.microsoft.com/library/default.asp?url=/archive/en-us/dnaraccgen/html/msdn_odk.asp 
     544                                // access uses precision to store length for char/varchar 
     545                                if ($fld->type == 'C' or $fld->type == 'X') { 
     546                                        if ($rs->fields[4] <= -95) // UNICODE 
     547                                                $fld->max_length = $rs->fields[7]/2; 
     548                                        else 
     549                                                $fld->max_length = $rs->fields[7]; 
     550                                } else  
     551                                        $fld->max_length = $rs->fields[7]; 
     552                                $fld->not_null = !empty($rs->fields[10]); 
     553                                $fld->scale = $rs->fields[8]; 
     554                                $fld->primary_key = false; 
     555                                $retarr[strtoupper($fld->name)] = $fld;  
     556                        } else if (sizeof($retarr)>0) 
     557                                break; 
     558                        $rs->MoveNext(); 
     559                } 
     560                $rs->Close();  
     561                if (empty($retarr)) $retarr = false; 
     562 
     563              $qid = db2_primary_keys($this->_connectionID, "", $schema, $table); 
     564                if (empty($qid)) return $false; 
     565                 
     566                $rs =& new ADORecordSet_db2($qid); 
     567                $ADODB_FETCH_MODE = $savem; 
     568                 
     569                if (!$rs) return $retarr; 
     570                $rs->_fetch(); 
     571                 
     572                /* 
     573                $rs->fields indices 
     574                0 TABLE_CAT 
     575                1 TABLE_SCHEM 
     576                2 TABLE_NAME 
     577                3 COLUMN_NAME 
     578                4 KEY_SEQ 
     579                5 PK_NAME 
     580                */ 
     581                while (!$rs->EOF) { 
     582                        if (strtoupper(trim($rs->fields[2])) == $table && (!$schema || strtoupper($rs->fields[1]) == $schema)) { 
     583                                $retarr[strtoupper($rs->fields[3])]->primary_key = true; 
     584                        } else if (sizeof($retarr)>0) 
     585                                break; 
     586                        $rs->MoveNext(); 
     587                } 
     588                $rs->Close();  
     589                 
     590                if (empty($retarr)) $retarr = false; 
     591                return $retarr; 
     592        } 
     593         
     594        function Prepare($sql) 
     595        { 
     596                if (! $this->_bindInputArray) return $sql; // no binding 
     597                $stmt = db2_prepare($this->_connectionID,$sql); 
     598                if (!$stmt) { 
     599                        // we don't know whether db2 driver is parsing prepared stmts, so just return sql 
     600                        return $sql; 
     601                } 
     602                return array($sql,$stmt,false); 
     603        } 
     604 
     605        /* returns queryID or false */ 
     606        function _query($sql,$inputarr=false)  
     607        { 
     608        GLOBAL $php_errormsg; 
     609                if (isset($php_errormsg)) $php_errormsg = ''; 
     610                $this->_error = ''; 
     611                 
     612                if ($inputarr) { 
     613                        if (is_array($sql)) { 
     614                                $stmtid = $sql[1]; 
     615                        } else { 
     616                                $stmtid = db2_prepare($this->_connectionID,$sql); 
     617         
     618                                if ($stmtid == false) { 
     619                                        $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 
     620                                        return false; 
     621                                } 
     622                        } 
     623                         
     624                        if (! db2_execute($stmtid,$inputarr)) { 
     625                                if ($this->_haserrorfunctions) { 
     626                                        $this->_errorMsg = db2_stmt_errormsg(); 
     627                                        $this->_errorCode = db2_stmt_error(); 
     628                                } 
     629                                return false; 
     630                        } 
     631                 
     632                } else if (is_array($sql)) { 
     633                        $stmtid = $sql[1]; 
     634                        if (!db2_execute($stmtid)) { 
     635                                if ($this->_haserrorfunctions) { 
     636                                        $this->_errorMsg = db2_stmt_errormsg(); 
     637                                        $this->_errorCode = db2_stmt_error(); 
     638                                } 
     639                                return false; 
     640                        } 
     641                } else 
     642                        $stmtid = @db2_exec($this->_connectionID,$sql); 
     643                 
     644                $this->_lastAffectedRows = 0; 
     645                if ($stmtid) { 
     646                        if (@db2_num_fields($stmtid) == 0) { 
     647                                $this->_lastAffectedRows = db2_num_rows($stmtid); 
     648                                $stmtid = true; 
     649                        } else { 
     650                                $this->_lastAffectedRows = 0; 
     651                        } 
     652                         
     653                        if ($this->_haserrorfunctions) { 
     654                                $this->_errorMsg = ''; 
     655                                $this->_errorCode = 0; 
     656                        } else 
     657                                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 
     658                } else { 
     659                        if ($this->_haserrorfunctions) { 
     660                                $this->_errorMsg = db2_stmt_errormsg(); 
     661                                $this->_errorCode = db2_stmt_error(); 
     662                        } else 
     663                                $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : ''; 
     664 
     665                } 
     666                return $stmtid; 
     667        } 
     668 
     669        /* 
     670                Insert a null into the blob field of the table first. 
     671                Then use UpdateBlob to store the blob. 
     672                 
     673                Usage: 
     674                  
     675                $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)'); 
     676                $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1'); 
     677        */ 
     678        function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') 
     679        { 
     680                return $this->Execute("UPDATE $table SET $column=? WHERE $where",array($val)) != false; 
     681        } 
     682         
     683        // returns true or false 
     684        function _close() 
     685        { 
     686                $ret = @db2_close($this->_connectionID); 
     687                $this->_connectionID = false; 
     688                return $ret; 
     689        } 
     690 
     691        function _affectedrows() 
     692        { 
     693                return $this->_lastAffectedRows; 
     694        } 
     695         
    313696} 
    314  
    315 } //define 
     697         
     698/*-------------------------------------------------------------------------------------- 
     699         Class Name: Recordset 
     700--------------------------------------------------------------------------------------*/ 
     701 
     702class ADORecordSet_db2 extends ADORecordSet {    
     703         
     704        var $bind = false; 
     705        var $databaseType = "db2";               
     706        var $dataProvider = "db2"; 
     707        var $useFetchArray; 
     708         
     709        function ADORecordSet_db2($id,$mode=false) 
     710        { 
     711                if ($mode === false) {   
     712                        global $ADODB_FETCH_MODE; 
     713                        $mode = $ADODB_FETCH_MODE; 
     714                } 
     715                $this->fetchMode = $mode; 
     716                 
     717                $this->_queryID = $id; 
     718        } 
     719 
     720 
     721        // returns the field object 
     722        function &FetchField($offset = -1)  
     723        { 
     724                $o= new ADOFieldObject(); 
     725                $o->name = @db2_field_name($this->_queryID,$offset); 
     726                $o->type = @db2_field_type($this->_queryID,$offset); 
     727                $o->max_length = db2_field_width($this->_queryID,$offset); 
     728                if (ADODB_ASSOC_CASE == 0) $o->name = strtolower($o->name); 
     729                else if (ADODB_ASSOC_CASE == 1) $o->name = strtoupper($o->name); 
     730                return $o; 
     731        } 
     732         
     733        /* Use associative array to get fields array */ 
     734        function Fields($colname) 
     735        { 
     736                if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname]; 
     737                if (!$this->bind) { 
     738                        $this->bind = array(); 
     739                        for ($i=0; $i < $this->_numOfFields; $i++) { 
     740                                $o = $this->FetchField($i); 
     741                                $this->bind[strtoupper($o->name)] = $i; 
     742                        } 
     743                } 
     744 
     745                 return $this->fields[$this->bind[strtoupper($colname)]]; 
     746        } 
     747         
     748                 
     749        function _initrs() 
     750        { 
     751        global $ADODB_COUNTRECS; 
     752                $this->_numOfRows = ($ADODB_COUNTRECS) ? @db2_num_rows($this->_queryID) : -1; 
     753                $this->_numOfFields = @db2_num_fields($this->_queryID); 
     754                // some silly drivers such as db2 as/400 and intersystems cache return _numOfRows = 0 
     755                if ($this->_numOfRows == 0) $this->_numOfRows = -1; 
     756        }        
     757         
     758        function _seek($row) 
     759        { 
     760                return false; 
     761        } 
     762         
     763        // speed up SelectLimit() by switching to ADODB_FETCH_NUM as ADODB_FETCH_ASSOC is emulated 
     764        function &GetArrayLimit($nrows,$offset=-1)  
     765        { 
     766                if ($offset <= 0) { 
     767                        $rs =& $this->GetArray($nrows); 
     768                        return $rs; 
     769                } 
     770                $savem = $this->fetchMode; 
     771                $this->fetchMode = ADODB_FETCH_NUM; 
     772                $this->Move($offset); 
     773                $this->fetchMode = $savem; 
     774                 
     775                if ($this->fetchMode & ADODB_FETCH_ASSOC) { 
     776                        $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE); 
     777                } 
     778                 
     779                $results = array(); 
     780                $cnt = 0; 
     781                while (!$this->EOF && $nrows != $cnt) { 
     782                        $results[$cnt++] = $this->fields; 
     783                        $this->MoveNext(); 
     784                } 
     785                 
     786                return $results; 
     787        } 
     788         
     789         
     790        function MoveNext()  
     791        { 
     792                if ($this->_numOfRows != 0 && !$this->EOF) {             
     793                        $this->_currentRow++; 
     794                         
     795                        $this->fields = @db2_fetch_array($this->_queryID); 
     796                        if ($this->fields) { 
     797                                if ($this->fetchMode & ADODB_FETCH_ASSOC) { 
     798                                        $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE); 
     799                                } 
     800                                return true; 
     801                        } 
     802                } 
     803                $this->fields = false; 
     804                $this->EOF = true; 
     805                return false; 
     806        }        
     807         
     808        function _fetch() 
     809        { 
     810 
     811                $this->fields = db2_fetch_array($this->_queryID); 
     812                if ($this->fields) { 
     813                        if ($this->fetchMode & ADODB_FETCH_ASSOC) { 
     814                                $this->fields =& $this->GetRowAssoc(ADODB_ASSOC_CASE); 
     815                        } 
     816                        return true; 
     817                } 
     818                $this->fields = false; 
     819                return false; 
     820        } 
     821         
     822        function _close()  
     823        { 
     824                return @db2_free_result($this->_queryID);                
     825        } 
     826 
     827} 
    316828?> 
Note: See TracChangeset for help on using the changeset viewer.