]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/drivers/adodb-db2.inc.php
elseif
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / drivers / adodb-db2.inc.php
1 <?php
2 /*
3 V4.22 15 Apr 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://php.weblogs.com/
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 USING CLI INTERFACE
68 ===================
69
70 I have had reports that the $host and $database params have to be reversed in
71 Connect() when using the CLI interface. From Halmai Csongor csongor.halmai#nexum.hu:
72
73 > The symptom is that if I change the database engine from postgres or any other to DB2 then the following
74 > connection command becomes wrong despite being described this version to be correct in the docs.
75 >
76 > $connection_object->Connect( $DATABASE_HOST, $DATABASE_AUTH_USER_NAME, $DATABASE_AUTH_PASSWORD, $DATABASE_NAME )
77 >
78 > In case of DB2 I had to swap the first and last arguments in order to connect properly.
79
80 */
81
82 if (!defined('_ADODB_ODBC_LAYER')) {
83     include(ADODB_DIR."/drivers/adodb-odbc.inc.php");
84 }
85 if (!defined('ADODB_DB2')){
86 define('ADODB_DB2',1);
87
88 class ADODB_DB2 extends ADODB_odbc {
89     var $databaseType = "db2";
90     var $concat_operator = '||';
91     var $sysDate = 'CURRENT_DATE';
92     var $sysTimeStamp = 'CURRENT TIMESTAMP';
93     // The complete string representation of a timestamp has the form
94     // yyyy-mm-dd-hh.mm.ss.nnnnnn.
95     var $fmtTimeStamp = "'Y-m-d-H.i.s'";
96     var $ansiOuter = true;
97     var $identitySQL = 'values IDENTITY_VAL_LOCAL()';
98     var $_bindInputArray = false;
99     var $upperCase = 'upper';
100
101     function ADODB_DB2()
102     {
103         if (strncmp(PHP_OS,'WIN',3) === 0) $this->curmode = SQL_CUR_USE_ODBC;
104         $this->ADODB_odbc();
105     }
106
107     function IfNull( $field, $ifNull )
108     {
109         return " COALESCE($field, $ifNull) "; // if DB2 UDB
110     }
111
112     function ServerInfo()
113     {
114         //odbc_setoption($this->_connectionID,1,101 /*SQL_ATTR_ACCESS_MODE*/, 1 /*SQL_MODE_READ_ONLY*/);
115         $vers = $this->GetOne('select versionnumber from sysibm.sysversions');
116         //odbc_setoption($this->_connectionID,1,101, 0 /*SQL_MODE_READ_WRITE*/);
117         return array('description'=>'DB2 ODBC driver', 'version'=>$vers);
118     }
119
120     function _insertid()
121     {
122         return $this->GetOne($this->identitySQL);
123     }
124
125     function RowLock($tables,$where)
126     {
127         if ($this->_autocommit) $this->BeginTrans();
128         return $this->GetOne("select 1 as ignore from $tables where $where for update");
129     }
130
131     function &MetaTables($ttype=false,$showSchema=false)
132     {
133     global $ADODB_FETCH_MODE;
134
135         $savem = $ADODB_FETCH_MODE;
136         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
137         $qid = odbc_tables($this->_connectionID);
138
139         $rs = new ADORecordSet_odbc($qid);
140
141         $ADODB_FETCH_MODE = $savem;
142         if (!$rs) return false;
143
144         $rs->_has_stupid_odbc_fetch_api_change = $this->_has_stupid_odbc_fetch_api_change;
145
146         $arr =& $rs->GetArray();
147         //print_r($arr);
148
149         $rs->Close();
150         $arr2 = array();
151
152         if ($ttype) {
153             $isview = strncmp($ttype,'V',1) === 0;
154         }
155         for ($i=0; $i < sizeof($arr); $i++) {
156
157             if (!$arr[$i][2]) continue;
158             if (strncmp($arr[$i][1],'SYS',3) === 0) continue;
159
160             $type = $arr[$i][3];
161
162             if ($showSchema) $arr[$i][2] = $arr[$i][1].'.'.$arr[$i][2];
163
164             if ($ttype) {
165                 if ($isview) {
166                     if (strncmp($type,'V',1) === 0) $arr2[] = $arr[$i][2];
167                 } elseif (strncmp($type,'T',1) === 0) $arr2[] = $arr[$i][2];
168             } elseif (strncmp($type,'S',1) !== 0) $arr2[] = $arr[$i][2];
169         }
170         return $arr2;
171     }
172
173     // Format date column in sql string given an input format that understands Y M D
174     function SQLDate($fmt, $col=false)
175     {
176     // use right() and replace() ?
177         if (!$col) $col = $this->sysDate;
178         $s = '';
179
180         $len = strlen($fmt);
181         for ($i=0; $i < $len; $i++) {
182             if ($s) $s .= '||';
183             $ch = $fmt[$i];
184             switch($ch) {
185             case 'Y':
186             case 'y':
187                 $s .= "char(year($col))";
188                 break;
189             case 'M':
190                 $s .= "substr(monthname($col),1,3)";
191                 break;
192             case 'm':
193                 $s .= "right(digits(month($col)),2)";
194                 break;
195             case 'D':
196             case 'd':
197                 $s .= "right(digits(day($col)),2)";
198                 break;
199             case 'H':
200             case 'h':
201                 if ($col != $this->sysDate) $s .= "right(digits(hour($col)),2)";
202                 else $s .= "''";
203                 break;
204             case 'i':
205             case 'I':
206                 if ($col != $this->sysDate)
207                     $s .= "right(digits(minute($col)),2)";
208                     else $s .= "''";
209                 break;
210             case 'S':
211             case 's':
212                 if ($col != $this->sysDate)
213                     $s .= "right(digits(second($col)),2)";
214                 else $s .= "''";
215                 break;
216             default:
217                 if ($ch == '\\') {
218                     $i++;
219                     $ch = substr($fmt,$i,1);
220                 }
221                 $s .= $this->qstr($ch);
222             }
223         }
224         return $s;
225     }
226
227     function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputArr=false)
228     {
229         if ($offset <= 0) {
230         // could also use " OPTIMIZE FOR $nrows ROWS "
231             if ($nrows >= 0) $sql .=  " FETCH FIRST $nrows ROWS ONLY ";
232             $rs =& $this->Execute($sql,$inputArr);
233         } else {
234             if ($offset > 0 && $nrows < 0);
235             else {
236                 $nrows += $offset;
237                 $sql .=  " FETCH FIRST $nrows ROWS ONLY ";
238             }
239             $rs =& ADOConnection::SelectLimit($sql,-1,$offset,$inputArr);
240         }
241
242         return $rs;
243     }
244
245 };
246
247 class  ADORecordSet_db2 extends ADORecordSet_odbc {
248
249     var $databaseType = "db2";
250
251     function ADORecordSet_db2($id,$mode=false)
252     {
253         $this->ADORecordSet_odbc($id,$mode);
254     }
255
256     function MetaType($t,$len=-1,$fieldobj=false)
257     {
258         if (is_object($t)) {
259             $fieldobj = $t;
260             $t = $fieldobj->type;
261             $len = $fieldobj->max_length;
262         }
263
264         switch (strtoupper($t)) {
265         case 'VARCHAR':
266         case 'CHAR':
267         case 'CHARACTER':
268             if ($len <= $this->blobSize) return 'C';
269
270         case 'LONGCHAR':
271         case 'TEXT':
272         case 'CLOB':
273         case 'DBCLOB': // double-byte
274             return 'X';
275
276         case 'BLOB':
277         case 'GRAPHIC':
278         case 'VARGRAPHIC':
279             return 'B';
280
281         case 'DATE':
282             return 'D';
283
284         case 'TIME':
285         case 'TIMESTAMP':
286             return 'T';
287
288         //case 'BOOLEAN':
289         //case 'BIT':
290         //      return 'L';
291
292         //case 'COUNTER':
293         //      return 'R';
294
295         case 'INT':
296         case 'INTEGER':
297         case 'BIGINT':
298         case 'SMALLINT':
299             return 'I';
300
301         default: return 'N';
302         }
303     }
304 }
305
306 } //define
307 ?>