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