source: moodle/trunk/fuentes/lib/adodb/drivers/adodb-ibase.inc.php @ 136

Last change on this file since 136 was 136, checked in by mabarracus, 3 years ago

Ported code to xenial

File size: 24.5 KB
Line 
1<?php
2/*
3V5.19  23-Apr-2014  (c) 2000-2014 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
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=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
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}
Note: See TracBrowser for help on using the repository browser.