home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2005 June / PCpro_2005_06.ISO / files / opensource / xamp / xampp-win32.exe / xampp / adodb-ibase.inc.php < prev    next >
Encoding:
PHP Script  |  2005-01-24  |  24.6 KB  |  855 lines

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