]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/drivers/adodb-ibase.inc.php
new ADODB library 4.22 with multiple drivers (not only mysql as before), major change...
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / drivers / adodb-ibase.inc.php
1 <?php\r
2 /*\r
3 V4.22 15 Apr 2004  (c) 2000-2004 John Lim (jlim@natsoft.com.my). All rights reserved.  \r
4   Released under both BSD license and Lesser GPL library license. \r
5   Whenever there is any discrepancy between the two licenses, \r
6   the BSD license will take precedence.\r
7 \r
8   Latest version is available at http://php.weblogs.com/\r
9   \r
10   Interbase data driver. Requires interbase client. Works on Windows and Unix.\r
11 \r
12   3 Jan 2002 -- suggestions by Hans-Peter Oeri <kampfcaspar75@oeri.ch>\r
13         changed transaction handling and added experimental blob stuff\r
14   \r
15   Docs to interbase at the website\r
16    http://www.synectics.co.za/php3/tutorial/IB_PHP3_API.html\r
17    \r
18   To use gen_id(), see\r
19    http://www.volny.cz/iprenosil/interbase/ip_ib_code.htm#_code_creategen\r
20    \r
21    $rs = $conn->Execute('select gen_id(adodb,1) from rdb$database');\r
22    $id = $rs->fields[0];\r
23    $conn->Execute("insert into table (id, col1,...) values ($id, $val1,...)");\r
24 */\r
25 \r
26 \r
27 class ADODB_ibase extends ADOConnection {\r
28         var $databaseType = "ibase";\r
29         var $dataProvider = "ibase";\r
30         var $replaceQuote = "''"; // string to use to replace quotes\r
31         var $ibase_timefmt = '%Y-%m-%d'; // For hours,mins,secs change to '%Y-%m-%d %H:%M:%S';\r
32         var $fmtDate = "'Y-m-d'";\r
33         var $fmtTimeStamp = "'Y-m-d, H:i:s'";\r
34         var $concat_operator='||';\r
35         var $_transactionID;\r
36         var $metaTablesSQL = "select rdb\$relation_name from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";\r
37         //OPN STUFF start\r
38         var $metaColumnsSQL = "select a.rdb\$field_name, a.rdb\$null_flag, a.rdb\$default_source, b.rdb\$field_length, b.rdb\$field_scale, b.rdb\$field_sub_type, b.rdb\$field_precision, b.rdb\$field_type from rdb\$relation_fields a, rdb\$fields b where a.rdb\$field_source = b.rdb\$field_name and a.rdb\$relation_name = '%s' order by a.rdb\$field_position asc";\r
39         //OPN STUFF end\r
40         var $ibasetrans;\r
41         var $hasGenID = true;\r
42         var $_bindInputArray = true;\r
43         var $buffers = 0;\r
44         var $dialect = 1;\r
45         var $sysDate = "cast('TODAY' as date)";\r
46         var $sysTimeStamp = "cast('NOW' as timestamp)";\r
47         var $ansiOuter = true;\r
48         var $hasAffectedRows = false;\r
49         var $poorAffectedRows = true;\r
50         var $blobEncodeType = 'C';\r
51         \r
52         function ADODB_ibase() \r
53         {\r
54                  if (defined('IBASE_DEFAULT')) $this->ibasetrans = IBASE_DEFAULT;\r
55         }\r
56         \r
57         function MetaPrimaryKeys($table,$owner_notused=false,$internalKey=false)\r
58         {       \r
59                 if ($internalKey) return array('RDB$DB_KEY');\r
60                 \r
61                 $table = strtoupper($table);\r
62                 \r
63                 $sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME\r
64         FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME  \r
65         WHERE I.RDB$RELATION_NAME=\''.$table.'\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'\r
66         ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';\r
67 \r
68                 $a = $this->GetCol($sql,false,true);\r
69                 if ($a && sizeof($a)>0) return $a;\r
70                 return false;     \r
71         }\r
72         \r
73         function ServerInfo()\r
74         {\r
75                 $arr['dialect'] = $this->dialect;\r
76                 switch($arr['dialect']) {\r
77                 case '': \r
78                 case '1': $s = 'Interbase 5.5 or earlier'; break;\r
79                 case '2': $s = 'Interbase 5.6'; break;\r
80                 default:\r
81                 case '3': $s = 'Interbase 6.0'; break;\r
82                 }\r
83                 $arr['version'] = ADOConnection::_findvers($s);\r
84                 $arr['description'] = $s;\r
85                 return $arr;\r
86         }\r
87 \r
88         function BeginTrans()\r
89         {        \r
90                 if ($this->transOff) return true;\r
91                 $this->transCnt += 1;\r
92                 $this->autoCommit = false;\r
93                 $this->_transactionID = $this->_connectionID;//ibase_trans($this->ibasetrans, $this->_connectionID);\r
94                 return $this->_transactionID;\r
95         }\r
96         \r
97         function CommitTrans($ok=true) \r
98         { \r
99                 if (!$ok) return $this->RollbackTrans();\r
100                 if ($this->transOff) return true;\r
101                 if ($this->transCnt) $this->transCnt -= 1;\r
102                 $ret = false;\r
103                 $this->autoCommit = true;\r
104                 if ($this->_transactionID) {\r
105                                         //print ' commit ';\r
106                         $ret = ibase_commit($this->_transactionID);\r
107                 }\r
108                 $this->_transactionID = false;\r
109                 return $ret;\r
110         }\r
111         \r
112         function RollbackTrans()\r
113         {\r
114                 if ($this->transOff) return true;\r
115                 if ($this->transCnt) $this->transCnt -= 1;\r
116                 $ret = false;\r
117                 $this->autoCommit = true;\r
118                 if ($this->_transactionID) \r
119                                   $ret = ibase_rollback($this->_transactionID);\r
120                 $this->_transactionID = false;   \r
121                 \r
122                 return $ret;\r
123         }\r
124         \r
125         function &MetaIndexes ($table, $primary = FALSE, $owner=false)\r
126         {\r
127         // save old fetch mode\r
128         global $ADODB_FETCH_MODE;\r
129         \r
130         $save = $ADODB_FETCH_MODE;\r
131         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;\r
132         if ($this->fetchMode !== FALSE) {\r
133                $savem = $this->SetFetchMode(FALSE);\r
134         }\r
135         $table = strtoupper($table);\r
136         $sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '".$table."'";\r
137         if (!$primary) {\r
138                 $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";\r
139         } else {\r
140                 $sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";\r
141         }\r
142         // get index details\r
143         $rs = $this->Execute($sql);\r
144         if (!is_object($rs)) {\r
145                 // restore fetchmode\r
146                 if (isset($savem)) {\r
147                     $this->SetFetchMode($savem);\r
148                 }\r
149                 $ADODB_FETCH_MODE = $save;\r
150             return FALSE;\r
151         }\r
152         \r
153         $indexes = array ();\r
154                 while ($row = $rs->FetchRow()) {\r
155                         $index = $row[0];\r
156              if (!isset($indexes[$index])) {\r
157                         if (is_null($row[3])) {$row[3] = 0;}\r
158                      $indexes[$index] = array(\r
159                              'unique' => ($row[3] == 1),\r
160                              'columns' => array()\r
161                      );\r
162              }\r
163                         $sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '".$name."' ORDER BY RDB\$FIELD_POSITION ASC";\r
164                         $rs1 = $this->Execute($sql);\r
165             while ($row1 = $rs1->FetchRow()) {\r
166                 $indexes[$index]['columns'][$row1[2]] = $row1[1];\r
167                 }\r
168                 }\r
169         // restore fetchmode\r
170         if (isset($savem)) {\r
171             $this->SetFetchMode($savem);\r
172         }\r
173         $ADODB_FETCH_MODE = $save;\r
174         \r
175         return $indexes;\r
176         }\r
177 \r
178         \r
179         // See http://community.borland.com/article/0,1410,25844,00.html\r
180         function RowLock($tables,$where,$col)\r
181         {\r
182                 if ($this->autoCommit) $this->BeginTrans();\r
183                 $this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?\r
184                 return 1;\r
185         }\r
186         \r
187         \r
188         function CreateSequence($seqname,$startID=1)\r
189         {\r
190                 $ok = $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));\r
191                 if (!$ok) return false;\r
192                 return $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');\r
193         }\r
194         \r
195         function DropSequence($seqname)\r
196         {\r
197                 $seqname = strtoupper($seqname);\r
198                 $this->Execute("delete from RDB\$GENERATORS where RDB\$GENERATOR_NAME='$seqname'");\r
199         }\r
200         \r
201         function GenID($seqname='adodbseq',$startID=1)\r
202         {\r
203                 $getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");\r
204                 $rs = @$this->Execute($getnext);\r
205                 if (!$rs) {\r
206                         $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));\r
207                         $this->Execute("SET GENERATOR $seqname TO ".($startID-1).';');\r
208                         $rs = $this->Execute($getnext);\r
209                 }\r
210                 if ($rs && !$rs->EOF) $this->genID = (integer) reset($rs->fields);\r
211                 else $this->genID = 0; // false\r
212                 \r
213                 if ($rs) $rs->Close();\r
214                 \r
215                 return $this->genID;\r
216         }\r
217 \r
218         function SelectDB($dbName) \r
219         {\r
220                    return false;\r
221         }\r
222 \r
223         function _handleerror()\r
224         {\r
225                 $this->_errorMsg = ibase_errmsg();\r
226         }\r
227 \r
228         function ErrorNo() \r
229         {\r
230                 if (preg_match('/error code = ([\-0-9]*)/i', $this->_errorMsg,$arr)) return (integer) $arr[1];\r
231                 else return 0;\r
232         }\r
233 \r
234         function ErrorMsg() \r
235         {\r
236                         return $this->_errorMsg;\r
237         }\r
238 \r
239            // returns true or false\r
240         function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)\r
241         {  \r
242                 if (!function_exists('ibase_pconnect')) return false;\r
243                 if ($argDatabasename) $argHostname .= ':'.$argDatabasename;\r
244                 $this->_connectionID = ibase_connect($argHostname,$argUsername,$argPassword,$this->charSet,$this->buffers,$this->dialect);\r
245                 if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html\r
246                         $this->replaceQuote = "''";\r
247                 }\r
248                 if ($this->_connectionID === false) {\r
249                         $this->_handleerror();\r
250                         return false;\r
251                 }\r
252                 \r
253                 ibase_timefmt($this->ibase_timefmt);    \r
254                 return true;\r
255         }\r
256            // returns true or false\r
257         function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)\r
258         {\r
259                 if (!function_exists('ibase_pconnect')) return false;\r
260                 if ($argDatabasename) $argHostname .= ':'.$argDatabasename;\r
261                 $this->_connectionID = ibase_pconnect($argHostname,$argUsername,$argPassword,$this->charSet,$this->buffers,$this->dialect);\r
262                 if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html\r
263                         $this->replaceQuote = "''";\r
264                 }\r
265                 if ($this->_connectionID === false) {\r
266                         $this->_handleerror();\r
267                         return false;\r
268                 }\r
269                 \r
270                 ibase_timefmt($this->ibase_timefmt);\r
271                 return true;\r
272         }       \r
273         \r
274         function Prepare($sql)\r
275         {\r
276                 $stmt = ibase_prepare($this->_connectionID,$sql);\r
277                 if (!$stmt) return false;\r
278                 return array($sql,$stmt);\r
279         }\r
280 \r
281            // returns query ID if successful, otherwise false\r
282            // there have been reports of problems with nested queries - the code is probably not re-entrant?\r
283         function _query($sql,$iarr=false)\r
284         { \r
285 \r
286                 if (!$this->autoCommit && $this->_transactionID) {\r
287                         $conn = $this->_transactionID;\r
288                         $docommit = false;\r
289                 } else {\r
290                         $conn = $this->_connectionID;\r
291                         $docommit = true;\r
292                 }\r
293                 if (is_array($sql)) {\r
294                         $fn = 'ibase_execute';\r
295                         $sql = $sql[1];\r
296                         \r
297                         if (is_array($iarr)) {\r
298                                 if  (ADODB_PHPVER >= 0x4050) { // actually 4.0.4\r
299                                         if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack\r
300                                         $fnarr =& array_merge( array($sql) , $iarr);\r
301                                         $ret = call_user_func_array($fn,$fnarr);\r
302                                 } else {\r
303                                         switch(sizeof($iarr)) {\r
304                                         case 1: $ret = $fn($sql,$iarr[0]); break;\r
305                                         case 2: $ret = $fn($sql,$iarr[0],$iarr[1]); break;\r
306                                         case 3: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;\r
307                                         case 4: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;\r
308                                         case 5: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;\r
309                                         case 6: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;\r
310                                         case 7: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;\r
311                                         default: ADOConnection::outp( "Too many parameters to ibase query $sql");\r
312                                         case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;\r
313                                         }\r
314                                 }\r
315                         } else $ret = $fn($sql); \r
316                 } else {\r
317                         $fn = 'ibase_query';\r
318                 \r
319                         if (is_array($iarr)) {  \r
320                                 if (ADODB_PHPVER >= 0x4050) { // actually 4.0.4\r
321                                         if ( !isset($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack\r
322                                         $fnarr =& array_merge( array($conn,$sql) , $iarr);\r
323                                         $ret = call_user_func_array($fn,$fnarr);\r
324                                 } else {\r
325                                         switch(sizeof($iarr)) {\r
326                                         case 1: $ret = $fn($conn,$sql,$iarr[0]); break;\r
327                                         case 2: $ret = $fn($conn,$sql,$iarr[0],$iarr[1]); break;\r
328                                         case 3: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;\r
329                                         case 4: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;\r
330                                         case 5: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;\r
331                                         case 6: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;\r
332                                         case 7: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;\r
333                                         default: ADOConnection::outp( "Too many parameters to ibase query $sql");\r
334                                         case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;\r
335                                         }\r
336                                 }\r
337                         } else $ret = $fn($conn,$sql); \r
338                 }\r
339                 if ($docommit && $ret === true) ibase_commit($this->_connectionID);\r
340 \r
341                 $this->_handleerror();\r
342                 return $ret;\r
343         }\r
344 \r
345          // returns true or false\r
346          function _close()\r
347          {         \r
348                 if (!$this->autoCommit) @ibase_rollback($this->_connectionID);\r
349                 return @ibase_close($this->_connectionID);\r
350          }\r
351         \r
352         //OPN STUFF start\r
353         function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $isInterbase6)\r
354         {\r
355                 $fscale = abs($fscale);\r
356                 $fld->max_length = $flen;\r
357                 $fld->scale = null;\r
358                 switch($ftype){\r
359                         case 7: \r
360                         case 8:\r
361                                 if ($isInterbase6) {\r
362                                     switch($fsubtype){\r
363                                         case 0: \r
364                                                 $fld->type = ($ftype == 7 ? 'smallint' : 'integer');\r
365                                                 break;\r
366                                         case 1: \r
367                                                 $fld->type = 'numeric';\r
368                                                         $fld->max_length = $fprecision;\r
369                                                         $fld->scale = $fscale;\r
370                                                 break;\r
371                                         case 2:\r
372                                                 $fld->type = 'decimal';\r
373                                                         $fld->max_length = $fprecision;\r
374                                                         $fld->scale = $fscale;\r
375                                                 break;\r
376                                     } // switch\r
377                                 } else {\r
378                                         if ($fscale !=0) {\r
379                                             $fld->type = 'decimal';\r
380                                                 $fld->scale = $fscale;\r
381                                                 $fld->max_length = ($ftype == 7 ? 4 : 9);\r
382                                         } else {\r
383                                                 $fld->type = ($ftype == 7 ? 'smallint' : 'integer');\r
384                                         }\r
385                                 }\r
386                                 break;\r
387                         case 16: \r
388                                 if ($isInterbase6) {\r
389                                     switch($fsubtype){\r
390                                         case 0: \r
391                                                 $fld->type = 'decimal';\r
392                                                         $fld->max_length = 18;\r
393                                                         $fld->scale = 0;\r
394                                                 break;\r
395                                         case 1: \r
396                                                 $fld->type = 'numeric';\r
397                                                         $fld->max_length = $fprecision;\r
398                                                         $fld->scale = $fscale;\r
399                                                 break;\r
400                                         case 2:\r
401                                                 $fld->type = 'decimal';\r
402                                                         $fld->max_length = $fprecision;\r
403                                                         $fld->scale = $fscale;\r
404                                                 break;\r
405                                     } // switch\r
406                                 }\r
407                                 break;\r
408                         case 10:\r
409                                 $fld->type = 'float';\r
410                                 break;\r
411                         case 14:\r
412                                 $fld->type = 'char';\r
413                                 break;\r
414                         case 27:\r
415                                 if ($fscale !=0) {\r
416                                     $fld->type = 'decimal';\r
417                                         $fld->max_length = 15;\r
418                                         $fld->scale = 5;\r
419                                 } else {\r
420                                         $fld->type = 'double';\r
421                                 }\r
422                                 break;\r
423                         case 35:\r
424                                 if ($isInterbase6) {\r
425                                     $fld->type = 'timestamp';\r
426                                 } else {\r
427                                         $fld->type = 'date';\r
428                                 }\r
429                                 break;\r
430                         case 12:\r
431                         case 13:\r
432                                 $fld->type = 'date';\r
433                                 break;\r
434                         case 37:\r
435                                 $fld->type = 'varchar';\r
436                                 break;\r
437                         case 40:\r
438                                 $fld->type = 'cstring';\r
439                                 break;\r
440                         case 261:\r
441                                 $fld->type = 'blob';\r
442                                 $fld->max_length = -1;\r
443                                 break;\r
444                 } // switch\r
445         }\r
446         //OPN STUFF end\r
447                 // returns array of ADOFieldObjects for current table\r
448         function &MetaColumns($table) \r
449         {\r
450         global $ADODB_FETCH_MODE;\r
451                 \r
452                 if ($this->metaColumnsSQL) {\r
453                 \r
454                         $save = $ADODB_FETCH_MODE;\r
455                         $ADODB_FETCH_MODE = ADODB_FETCH_NUM;\r
456                 \r
457                         $rs = $this->Execute(sprintf($this->metaColumnsSQL,strtoupper($table)));\r
458                 \r
459                         $ADODB_FETCH_MODE = $save;\r
460                         if ($rs === false) return false;\r
461 \r
462                         $retarr = array();\r
463                         //OPN STUFF start\r
464                         $isInterbase6 = ($this->dialect==3 ? true : false);\r
465                         //OPN STUFF end\r
466                         while (!$rs->EOF) { //print_r($rs->fields);\r
467                                 $fld = new ADOFieldObject();\r
468                                 $fld->name = trim($rs->fields[0]);\r
469                                 //OPN STUFF start\r
470                                 $this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $isInterbase6);\r
471                                 if (isset($rs->fields[1]) && $rs->fields[1]) {\r
472                                         $fld->not_null = true;\r
473                                 }                               \r
474                                 if (isset($rs->fields[2])) {\r
475                                         \r
476                                         $fld->has_default = true;\r
477                                         $d = substr($rs->fields[2],strlen('default '));\r
478                                         switch ($fld->type)\r
479                                         {\r
480                                         case 'smallint':\r
481                                         case 'integer': $fld->default_value = (int) $d; break;\r
482                                         case 'char': \r
483                                         case 'blob':\r
484                                         case 'text':\r
485                                         case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)-2); break;\r
486                                         case 'double':\r
487                                         case 'float': $fld->default_value = (float) $d; break;\r
488                                         default: $fld->default_value = $d; break;\r
489                                         }\r
490                         //      case 35:$tt = 'TIMESTAMP'; break;\r
491                                 }\r
492                                 if ((isset($rs->fields[5])) && ($fld->type == 'blob')) {\r
493                                         $fld->sub_type = $rs->fields[5];\r
494                                 } else {\r
495                                         $fld->sub_type = null;\r
496                                 }\r
497                                 //OPN STUFF end\r
498                                 if ($ADODB_FETCH_MODE == ADODB_FETCH_NUM) $retarr[] = $fld;     \r
499                                 else $retarr[strtoupper($fld->name)] = $fld;\r
500                                 \r
501                                 $rs->MoveNext();\r
502                         }\r
503                         $rs->Close();\r
504                         return $retarr; \r
505                 }\r
506                 return false;\r
507         }\r
508         \r
509         function BlobEncode( $blob ) \r
510         {\r
511                 $blobid = ibase_blob_create( $this->_connectionID);\r
512                 ibase_blob_add( $blobid, $blob );\r
513                 return ibase_blob_close( $blobid );\r
514         }\r
515         \r
516         // since we auto-decode all blob's since 2.42, \r
517         // BlobDecode should not do any transforms\r
518         function BlobDecode($blob)\r
519         {\r
520                 return $blob; \r
521         }\r
522         \r
523         \r
524         \r
525         \r
526         // old blobdecode function\r
527         // still used to auto-decode all blob's\r
528         function _BlobDecode( $blob ) \r
529         {\r
530                 $blobid = ibase_blob_open( $blob );\r
531                 $realblob = ibase_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet <kevinboillet@yahoo.fr>\r
532                 while($string = ibase_blob_get($blobid, 8192)){ \r
533                         $realblob .= $string; \r
534                 }\r
535                 ibase_blob_close( $blobid );\r
536 \r
537                 return( $realblob );\r
538         } \r
539         \r
540         function UpdateBlobFile($table,$column,$path,$where,$blobtype='BLOB') \r
541         { \r
542                 $fd = fopen($path,'rb'); \r
543                 if ($fd === false) return false; \r
544                 $blob_id = ibase_blob_create($this->_connectionID); \r
545                 \r
546                 /* fill with data */ \r
547                 \r
548                 while ($val = fread($fd,32768)){ \r
549                         ibase_blob_add($blob_id, $val); \r
550                 } \r
551                 \r
552                 /* close and get $blob_id_str for inserting into table */ \r
553                 $blob_id_str = ibase_blob_close($blob_id); \r
554                 \r
555                 fclose($fd); \r
556                 return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false; \r
557         } \r
558         \r
559         /*\r
560                 Insert a null into the blob field of the table first.\r
561                 Then use UpdateBlob to store the blob.\r
562                 \r
563                 Usage:\r
564                  \r
565                 $conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');\r
566                 $conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');\r
567         */\r
568         function UpdateBlob($table,$column,$val,$where,$blobtype='BLOB') \r
569         { \r
570         $blob_id = ibase_blob_create($this->_connectionID); \r
571         \r
572         // ibase_blob_add($blob_id, $val); \r
573         \r
574         // replacement that solves the problem by which only the first modulus 64K / \r
575         // of $val are stored at the blob field //////////////////////////////////// \r
576         // Thx Abel Berenstein  aberenstein#afip.gov.ar\r
577         $len = strlen($val); \r
578         $chunk_size = 32768; \r
579         $tail_size = $len % $chunk_size; \r
580         $n_chunks = ($len - $tail_size) / $chunk_size; \r
581         \r
582         for ($n = 0; $n < $n_chunks; $n++) { \r
583                 $start = $n * $chunk_size; \r
584                 $data = substr($val, $start, $chunk_size); \r
585                 ibase_blob_add($blob_id, $data); \r
586         } \r
587         \r
588         if ($tail_size) {\r
589                 $start = $n_chunks * $chunk_size; \r
590                 $data = substr($val, $start, $tail_size); \r
591                 ibase_blob_add($blob_id, $data); \r
592         }\r
593         // end replacement ///////////////////////////////////////////////////////// \r
594         \r
595         $blob_id_str = ibase_blob_close($blob_id); \r
596         \r
597         return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false; \r
598         \r
599         } \r
600         \r
601         \r
602         function OldUpdateBlob($table,$column,$val,$where,$blobtype='BLOB')\r
603         {\r
604                 $blob_id = ibase_blob_create($this->_connectionID);\r
605                 ibase_blob_add($blob_id, $val);\r
606                 $blob_id_str = ibase_blob_close($blob_id);\r
607                 return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;\r
608         }\r
609         \r
610         // Format date column in sql string given an input format that understands Y M D\r
611         // Only since Interbase 6.0 - uses EXTRACT\r
612         // problem - does not zero-fill the day and month yet\r
613         function SQLDate($fmt, $col=false)\r
614         {       \r
615                 if (!$col) $col = $this->sysDate;\r
616                 $s = '';\r
617                 \r
618                 $len = strlen($fmt);\r
619                 for ($i=0; $i < $len; $i++) {\r
620                         if ($s) $s .= '||';\r
621                         $ch = $fmt[$i];\r
622                         switch($ch) {\r
623                         case 'Y':\r
624                         case 'y':\r
625                                 $s .= "extract(year from $col)";\r
626                                 break;\r
627                         case 'M':\r
628                         case 'm':\r
629                                 $s .= "extract(month from $col)";\r
630                                 break;\r
631                         case 'Q':\r
632                         case 'q':\r
633                                 $s .= "cast(((extract(month from $col)+2) / 3) as integer)";\r
634                                 break;\r
635                         case 'D':\r
636                         case 'd':\r
637                                 $s .= "(extract(day from $col))";\r
638                                 break;\r
639                         case 'H':\r
640                         case 'h':\r
641                           $s .= "(extract(hour from $col))";\r
642                           break;                        \r
643                         case 'I':\r
644                         case 'i':\r
645                           $s .= "(extract(minute from $col))";\r
646                           break;                \r
647                         case 'S':\r
648                         case 's':\r
649                           $s .= "CAST((extract(second from $col)) AS INTEGER)";\r
650                           break;        \r
651 \r
652                         default:\r
653                                 if ($ch == '\\') {\r
654                                         $i++;\r
655                                         $ch = substr($fmt,$i,1);\r
656                                 }\r
657                                 $s .= $this->qstr($ch);\r
658                                 break;\r
659                         }\r
660                 }\r
661                 return $s;\r
662         }\r
663 }\r
664 \r
665 /*--------------------------------------------------------------------------------------\r
666                  Class Name: Recordset\r
667 --------------------------------------------------------------------------------------*/\r
668 \r
669 class ADORecordset_ibase extends ADORecordSet \r
670 {\r
671 \r
672         var $databaseType = "ibase";\r
673         var $bind=false;\r
674         var $_cacheType;\r
675         \r
676         function ADORecordset_ibase($id,$mode=false)\r
677         {\r
678         global $ADODB_FETCH_MODE;\r
679         \r
680                         $this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;\r
681                         return $this->ADORecordSet($id);\r
682         }\r
683 \r
684         /*              Returns: an object containing field information.\r
685                         Get column information in the Recordset object. fetchField() can be used in order to obtain information about\r
686                         fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by\r
687                         fetchField() is retrieved.              */\r
688 \r
689         function &FetchField($fieldOffset = -1)\r
690         {\r
691                          $fld = new ADOFieldObject;\r
692                          $ibf = ibase_field_info($this->_queryID,$fieldOffset);\r
693                          $fld->name = strtolower($ibf['alias']);\r
694                          if (empty($fld->name)) $fld->name = strtolower($ibf['name']);\r
695                          $fld->type = $ibf['type'];\r
696                          $fld->max_length = $ibf['length'];\r
697                          return $fld;\r
698         }\r
699 \r
700         function _initrs()\r
701         {\r
702                         $this->_numOfRows = -1;\r
703                         $this->_numOfFields = @ibase_num_fields($this->_queryID);\r
704                         \r
705                         // cache types for blob decode check\r
706                         for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) { \r
707                                 $f1 = $this->FetchField($i); \r
708                                 $this->_cacheType[] = $f1->type;\r
709                         }                               \r
710         }\r
711 \r
712         function _seek($row)\r
713         {\r
714                 return false;\r
715         }\r
716 \r
717         \r
718         \r
719         function _fetch() \r
720         {\r
721                 $f = @ibase_fetch_row($this->_queryID); \r
722                 if ($f === false) {\r
723                         $this->fields = false;\r
724                         return false;\r
725                 }\r
726                 // OPN stuff start - optimized\r
727                 // fix missing nulls and decode blobs automatically\r
728         \r
729                 global $ADODB_ANSI_PADDING_OFF;\r
730                 //$ADODB_ANSI_PADDING_OFF=1;\r
731                 $rtrim = !empty($ADODB_ANSI_PADDING_OFF);\r
732                 \r
733                 for ($i=0, $max = $this->_numOfFields; $i < $max; $i++) { \r
734                         if ($this->_cacheType[$i]=="BLOB") {\r
735                                 if (isset($f[$i])) { \r
736                                         $f[$i] = $this->connection->_BlobDecode($f[$i]); \r
737                                 } else { \r
738                                         $f[$i] = null; \r
739                                 } \r
740                         } else { \r
741                                 if (!isset($f[$i])) { \r
742                                         $f[$i] = null; \r
743                                 } else if ($rtrim && is_string($f[$i])) {\r
744                                         $f[$i] = rtrim($f[$i]);\r
745                                 }\r
746                         } \r
747                 } \r
748                 // OPN stuff end \r
749                 \r
750                 $this->fields = $f;\r
751                 if ($this->fetchMode == ADODB_FETCH_ASSOC) {\r
752                         $this->fields = &$this->GetRowAssoc(ADODB_ASSOC_CASE);\r
753                 } else if ($this->fetchMode == ADODB_FETCH_BOTH) {\r
754                         $this->fields =& array_merge($this->fields,$this->GetRowAssoc(ADODB_ASSOC_CASE));\r
755                 }\r
756                 return true;\r
757         }\r
758 \r
759         /* Use associative array to get fields array */\r
760         function Fields($colname)\r
761         {\r
762                 if ($this->fetchMode & ADODB_FETCH_ASSOC) return $this->fields[$colname];\r
763                 if (!$this->bind) {\r
764                         $this->bind = array();\r
765                         for ($i=0; $i < $this->_numOfFields; $i++) {\r
766                                 $o = $this->FetchField($i);\r
767                                 $this->bind[strtoupper($o->name)] = $i;\r
768                         }\r
769                 }\r
770                 \r
771                  return $this->fields[$this->bind[strtoupper($colname)]];\r
772                 \r
773         }\r
774         \r
775 \r
776         function _close() \r
777         {\r
778                         return @ibase_free_result($this->_queryID);\r
779         }\r
780 \r
781         function MetaType($t,$len=-1,$fieldobj=false)\r
782         {\r
783                 if (is_object($t)) {\r
784                         $fieldobj = $t;\r
785                         $t = $fieldobj->type;\r
786                         $len = $fieldobj->max_length;\r
787                 }\r
788                 switch (strtoupper($t)) {\r
789                 case 'CHAR':\r
790                         return 'C';\r
791                         \r
792                 case 'TEXT':\r
793                 case 'VARCHAR':\r
794                 case 'VARYING':\r
795                 if ($len <= $this->blobSize) return 'C';\r
796                         return 'X';\r
797                 case 'BLOB':\r
798                         return 'B';\r
799                            \r
800                 case 'TIMESTAMP':\r
801                 case 'DATE': return 'D';\r
802                                 \r
803                                 //case 'T': return 'T';\r
804 \r
805                                 //case 'L': return 'L';\r
806                 case 'INT': \r
807                 case 'SHORT':\r
808                 case 'INTEGER': return 'I';\r
809                 default: return 'N';\r
810                 }\r
811         }\r
812 \r
813 }\r
814 ?>