Source for file adodb-ibase.inc.php
Documentation is available at adodb-ibase.inc.php
V4.97 22 Jan 2008 (c) 2000-2008 John Lim (jlim#natsoft.com.my). All rights reserved.
Released under both BSD license and Lesser GPL library license.
Whenever there is any discrepancy between the two licenses,
the BSD license will take precedence.
Latest version is available at http://adodb.sourceforge.net
Interbase data driver. Requires interbase client. Works on Windows and Unix.
3 Jan 2002 -- suggestions by Hans-Peter Oeri <kampfcaspar75@oeri.ch>
changed transaction handling and added experimental blob stuff
Docs to interbase at the website
http://www.synectics.co.za/php3/tutorial/IB_PHP3_API.html
http://www.volny.cz/iprenosil/interbase/ip_ib_code.htm#_code_creategen
$rs = $conn->Execute('select gen_id(adodb,1) from rdb$database');
$conn->Execute("insert into table (id, col1,...) values ($id, $val1,...)");
var $ibase_datefmt = '%Y-%m-%d'; // For hours,mins,secs change to '%Y-%m-%d %H:%M:%S';
var $metaTablesSQL = "select rdb\$relation_name from rdb\$relations where rdb\$relation_name not like 'RDB\$%'";
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";
var $sysDate = "cast('TODAY' as timestamp)";
var $sysTimeStamp = "CURRENT_TIMESTAMP"; //"cast('NOW' as timestamp)";
function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$persist= false)
if ($argDatabasename) $argHostname .= ':'. $argDatabasename;
$fn = ($persist) ? 'ibase_pconnect': 'ibase_connect';
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
$this->_connectionID = $fn($argHostname,$argUsername,$argPassword,
if ($this->dialect != 1) { // http://www.ibphoenix.com/ibp_60_del_id_ds.html
function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename,true);
if ($internalKey) return array('RDB$DB_KEY');
$sql = 'SELECT S.RDB$FIELD_NAME AFIELDNAME
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON I.RDB$INDEX_NAME=S.RDB$INDEX_NAME
WHERE I.RDB$RELATION_NAME=\''. $table. '\' and I.RDB$INDEX_NAME like \'RDB$PRIMARY%\'
ORDER BY I.RDB$INDEX_NAME,S.RDB$FIELD_POSITION';
if ($a && sizeof($a)> 0) return $a;
switch($arr['dialect']) {
case '1': $s = 'Interbase 5.5 or earlier'; break;
case '2': $s = 'Interbase 5.6'; break;
case '3': $s = 'Interbase 6.0'; break;
$arr['description'] = $s;
// there are some compat problems with ADODB_COUNTRECS=false and $this->_logsql currently.
// it appears that ibase extension cannot support multiple concurrent queryid's
function &_Execute($sql,$inputarr= false)
$savecrecs = $ADODB_COUNTRECS;
$ADODB_COUNTRECS = true; // force countrecs
$ADODB_COUNTRECS = $savecrecs;
function &MetaIndexes ($table, $primary = FALSE, $owner= false)
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$sql = "SELECT * FROM RDB\$INDICES WHERE RDB\$RELATION_NAME = '". $table. "'";
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$%'";
$sql .= " AND RDB\$INDEX_NAME NOT LIKE 'RDB\$FOREIGN%'";
$ADODB_FETCH_MODE = $save;
while ($row = $rs->FetchRow()) {
if (!isset ($indexes[$index])) {
if (is_null($row[3])) {$row[3] = 0;}
$indexes[$index] = array(
'unique' => ($row[3] == 1),
$sql = "SELECT * FROM RDB\$INDEX_SEGMENTS WHERE RDB\$INDEX_NAME = '". $index. "' ORDER BY RDB\$FIELD_POSITION ASC";
while ($row1 = $rs1->FetchRow()) {
$indexes[$index]['columns'][$row1[2]] = $row1[1];
$ADODB_FETCH_MODE = $save;
// See http://community.borland.com/article/0,1410,25844,00.html
function RowLock($tables,$where,$col)
$this->Execute("UPDATE $table SET $col=$col WHERE $where "); // is this correct - jlim?
$ok = $this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
return $this->Execute("SET GENERATOR $seqname TO ". ($startID- 1). ';');
$this->Execute("delete from RDB\$GENERATORS where RDB\$GENERATOR_NAME='$seqname'");
function GenID($seqname= 'adodbseq',$startID= 1)
$getnext = ("SELECT Gen_ID($seqname,1) FROM RDB\$DATABASE");
$this->Execute(("INSERT INTO RDB\$GENERATORS (RDB\$GENERATOR_NAME) VALUES (UPPER('$seqname'))" ));
$this->Execute("SET GENERATOR $seqname TO ". ($startID- 1). ';');
if ($rs && !$rs->EOF) $this->genID = (integer) reset($rs->fields);
else $this->genID = 0; // false
if (!$stmt) return false;
return array($sql,$stmt);
// returns query ID if successful, otherwise false
// there have been reports of problems with nested queries - the code is probably not re-entrant?
function _query($sql,$iarr= false)
if ( !isset ($iarr[0]) ) $iarr[0] = ''; // PHP5 compat hack
case 1: $ret = $fn($sql,$iarr[0]); break;
case 2: $ret = $fn($sql,$iarr[0],$iarr[1]); break;
case 3: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2]); break;
case 4: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
case 5: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
case 6: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
case 7: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
case 8: $ret = $fn($sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
if (sizeof($iarr) == 0) $iarr[0] = ''; // PHP5 compat hack
case 1: $ret = $fn($conn,$sql,$iarr[0]); break;
case 2: $ret = $fn($conn,$sql,$iarr[0],$iarr[1]); break;
case 3: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2]); break;
case 4: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3]); break;
case 5: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4]); break;
case 6: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5]); break;
case 7: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6]); break;
case 8: $ret = $fn($conn,$sql,$iarr[0],$iarr[1],$iarr[2],$iarr[3],$iarr[4],$iarr[5],$iarr[6],$iarr[7]); break;
} else $ret = $fn($conn,$sql);
function _ConvertFieldType(&$fld, $ftype, $flen, $fscale, $fsubtype, $fprecision, $dialect3)
$fld->max_length = $flen;
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
$fld->max_length = $fprecision;
$fld->max_length = $fprecision;
$fld->max_length = ($ftype == 7 ? 4 : 9);
$fld->type = ($ftype == 7 ? 'smallint' : 'integer');
$fld->max_length = $fprecision;
$fld->max_length = $fprecision;
$fld->type = 'timestamp';
// returns array of ADOFieldObjects for current table
global $ADODB_FETCH_MODE;
$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = $save;
while (!$rs->EOF) { //print_r($rs->fields);
$fld->name = trim($rs->fields[0]);
$this->_ConvertFieldType($fld, $rs->fields[7], $rs->fields[3], $rs->fields[4], $rs->fields[5], $rs->fields[6], $dialect3);
if (isset ($rs->fields[1]) && $rs->fields[1]) {
if (isset ($rs->fields[2])) {
$fld->has_default = true;
case 'integer': $fld->default_value = (int) $d; break;
case 'varchar': $fld->default_value = (string) substr($d,1,strlen($d)- 2); break;
case 'float': $fld->default_value = (float) $d; break;
default: $fld->default_value = $d; break;
// case 35:$tt = 'TIMESTAMP'; break;
if ((isset ($rs->fields[5])) && ($fld->type == 'blob')) {
$fld->sub_type = $rs->fields[5];
if ( empty($retarr)) return $false;
ibase_blob_add( $blobid, $blob );
return ibase_blob_close( $blobid );
// since we auto-decode all blob's since 2.42,
// BlobDecode should not do any transforms
// old blobdecode function
// still used to auto-decode all blob's
$realblob = ibase_blob_get( $blobid,$this->maxblobsize); // 2nd param is max size of blob -- Kevin Boillet <kevinboillet@yahoo.fr>
while($string = ibase_blob_get($blobid, 8192)){
ibase_blob_close( $blobid );
$blob_data = ibase_blob_info( $blob );
$blobid = ibase_blob_open( $blob );
$realblob = ibase_blob_get($blobid, $this->maxblobsize);
while($string = ibase_blob_get($blobid, 8192)){
$realblob = ibase_blob_get($blobid, $blob_data[0]);
ibase_blob_close( $blobid );
while ($val = fread($fd,32768)){
ibase_blob_add($blob_id, $val);
/* close and get $blob_id_str for inserting into table */
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
Insert a null into the blob field of the table first.
Then use UpdateBlob to store the blob.
$conn->Execute('INSERT INTO blobtable (id, blobcol) VALUES (1, null)');
$conn->UpdateBlob('blobtable','blobcol',$blob,'id=1');
function UpdateBlob($table,$column,$val,$where,$blobtype= 'BLOB')
// ibase_blob_add($blob_id, $val);
// replacement that solves the problem by which only the first modulus 64K /
// of $val are stored at the blob field ////////////////////////////////////
// Thx Abel Berenstein aberenstein#afip.gov.ar
$tail_size = $len % $chunk_size;
$n_chunks = ($len - $tail_size) / $chunk_size;
for ($n = 0; $n < $n_chunks; $n++ ) {
$start = $n * $chunk_size;
$data = substr($val, $start, $chunk_size);
ibase_blob_add($blob_id, $data);
$start = $n_chunks * $chunk_size;
$data = substr($val, $start, $tail_size);
ibase_blob_add($blob_id, $data);
// end replacement /////////////////////////////////////////////////////////
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
function OldUpdateBlob($table,$column,$val,$where,$blobtype= 'BLOB')
ibase_blob_add($blob_id, $val);
$blob_id_str = ibase_blob_close($blob_id);
return $this->Execute("UPDATE $table SET $column=(?) WHERE $where",array($blob_id_str)) != false;
// Format date column in sql string given an input format that understands Y M D
// Only since Interbase 6.0 - uses EXTRACT
// problem - does not zero-fill the day and month yet
for ($i= 0; $i < $len; $i++ ) {
$s .= "extract(year from $col)";
$s .= "extract(month from $col)";
$s .= "cast(((extract(month from $col)+2) / 3) as integer)";
$s .= "(extract(day from $col))";
$s .= "(extract(hour from $col))";
$s .= "(extract(minute from $col))";
$s .= "CAST((extract(second from $col)) AS INTEGER)";
/*--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------*/
global $ADODB_FETCH_MODE;
$this->fetchMode = ($mode === false) ? $ADODB_FETCH_MODE : $mode;
/* Returns: an object containing field information.
Get column information in the Recordset object. fetchField() can be used in order to obtain information about
fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
fetchField() is retrieved. */
$ibf = ibase_field_info($this->_queryID,$fieldOffset);
switch (ADODB_ASSOC_CASE) {
$fld->name = ($ibf['alias']);
if (empty($fld->name)) $fld->name = ($ibf['name']);
if (empty($fld->name)) $fld->name = strtoupper($ibf['name']);
if (empty($fld->name)) $fld->name = strtolower($ibf['name']);
$fld->type = $ibf['type'];
$fld->max_length = $ibf['length'];
/* This needs to be populated from the metadata */
$fld->has_default = false;
$fld->default_value = 'null';
// cache types for blob decode check
// OPN stuff start - optimized
// fix missing nulls and decode blobs automatically
global $ADODB_ANSI_PADDING_OFF;
//$ADODB_ANSI_PADDING_OFF=1;
$rtrim = !empty($ADODB_ANSI_PADDING_OFF);
/* Use associative array to get fields array */
return @ibase_free_result($this->_queryID);
function MetaType($t,$len=- 1,$fieldobj= false)
$len = $fieldobj->max_length;
if ($len <= $this->blobSize) return 'C';
case 'INTEGER': return 'I';
|