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

Last change on this file since 1331 was 1331, checked in by jrpelegrina, 3 years ago

Updated to moodle 3.0.3

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