source: Dev/trunk/rdfapi/util/adodb/drivers/adodb-ibase.inc.php @ 12

Last change on this file since 12 was 12, checked in by basvannuland, 14 years ago

Added RAP RDF API
Added RDF reader writer for save and load survey

File size: 25.6 KB
Line 
1<?php
2/*
3V4.94 23 Jan 2007  (c) 2000-2007 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
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
27if (!defined('ADODB_DIR')) die();
28
29class 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)
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)
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
726class 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?>
Note: See TracBrowser for help on using the repository browser.