• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List

E:/E/GEAMP/www/openbiz/openbiz/others/ZendX/Db/Adapter/Firebird.php

00001 <?php
00026 require_once 'Zend/Db/Adapter/Abstract.php';
00027 
00031 require_once 'Zend/Db/Profiler.php';
00032 
00036 require_once 'Zend/Db/Select.php';
00037 
00041 require_once 'ZendX/Db/Statement/Firebird.php';
00042 
00043 
00051 class ZendX_Db_Adapter_Firebird extends Zend_Db_Adapter_Abstract
00052 {
00062     protected $_autoQuoteIdentifiers = true;
00063 
00069     protected $_transResource = null;
00070 
00076     public function getTransaction()
00077     {
00078         return (is_resource($this->_transResource) ? $this->_transResource : null);
00079     }
00080 
00092     protected $_numericDataTypes = array(
00093         Zend_Db::INT_TYPE    => Zend_Db::INT_TYPE,
00094         Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
00095         Zend_Db::FLOAT_TYPE  => Zend_Db::FLOAT_TYPE,
00096         'SMALLINT'           => Zend_Db::INT_TYPE,
00097         'INT'                => Zend_Db::INT_TYPE,
00098         'INTEGER'            => Zend_Db::INT_TYPE,
00099         'BIGINT'             => Zend_Db::BIGINT_TYPE,
00100         'INT64'              => Zend_Db::BIGINT_TYPE,
00101         'DECIMAL'            => Zend_Db::FLOAT_TYPE,
00102         'DOUBLE PRECISION'   => Zend_Db::FLOAT_TYPE,
00103         'DOUBLE'             => Zend_Db::FLOAT_TYPE,
00104         'NUMERIC'            => Zend_Db::FLOAT_TYPE,
00105         'FLOAT'              => Zend_Db::FLOAT_TYPE
00106     );
00107 
00114     protected function _quote($value)
00115     {
00116         if (is_int($value) || is_float($value)) {
00117             return $value;
00118         }
00119         $value = str_replace("'", "''", $value);
00120         return "'" . $value . "'";
00121     }
00122 
00128     public function listTables()
00129     {
00130         $data = $this->fetchCol('SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$SYSTEM_FLAG = 0');
00131         foreach($data as &$v)
00132             $v = trim($v);
00133         return $data;
00134     }
00135 
00164     public function describeTable($tableName, $schemaName = null)
00165     {
00166         $fieldMaps = array(
00167             'TEXT'      => 'CHAR',
00168             'VARYING'   => 'VARCHAR',
00169             'SHORT'     => 'SMALLINT',
00170             'LONG'      => 'INTEGER',
00171             'FLOAT'     => 'FLOAT',
00172             'INT64'     => array(0 => 'BIGINT', 'NUMERIC', 'DECIMAL'),
00173             'DATE'      => 'DATE',
00174             'TIME'      => 'TIME',
00175             'BLOB'      => 'BLOB',
00176             'DOUBLE'    => 'DOUBLE PRECISION',
00177             'TIMESTAMP' => 'TIMESTAMP'
00178         );
00179 
00180         $sql = 'select
00181                     RF.RDB$RELATION_NAME, \'\', RF.RDB$FIELD_NAME, T.RDB$TYPE_NAME,
00182                     RF.RDB$DEFAULT_VALUE, RF.RDB$NULL_FLAG, RF.RDB$FIELD_POSITION,
00183                     F.RDB$CHARACTER_LENGTH, F.RDB$FIELD_SCALE, F.RDB$FIELD_PRECISION,
00184                     IXS.RDB$FIELD_POSITION, IXS.RDB$FIELD_POSITION, F.RDB$FIELD_SUB_TYPE
00185                 from RDB$RELATION_FIELDS RF
00186                 left join RDB$RELATION_CONSTRAINTS RC
00187                     on (RF.RDB$RELATION_NAME = RC.RDB$RELATION_NAME and RC.RDB$CONSTRAINT_TYPE = \'PRIMARY KEY\')
00188                 left join RDB$INDEX_SEGMENTS IXS
00189                     on (IXS.RDB$FIELD_NAME = RF.RDB$FIELD_NAME and RC.RDB$INDEX_NAME = IXS.RDB$INDEX_NAME)
00190                 inner join RDB$FIELDS F on (RF.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME)
00191                 inner join RDB$TYPES T on (T.RDB$TYPE = F.RDB$FIELD_TYPE and T.RDB$FIELD_NAME = \'RDB$FIELD_TYPE\')
00192                 where ' . $this->quoteInto('(UPPER(RF.RDB$RELATION_NAME) = UPPER(?)) ', $tableName) . '
00193                 order by RF.RDB$FIELD_POSITION';
00194 
00195         $stmt = $this->query($sql);
00196 
00200         $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
00201 
00202         $table_name      = 0;
00203         $owner           = 1;
00204         $column_name     = 2;
00205         $data_type       = 3;
00206         $data_default    = 4;
00207         $nullable        = 5;
00208         $column_id       = 6;
00209         $data_length     = 7;
00210         $data_scale      = 8;
00211         $data_precision  = 9;
00212         $constraint_type = 10;
00213         $position        = 11;
00214         $sub_type        = 12;
00215 
00216         $desc = array();
00217         foreach ($result as $key => $row) {
00218             list ($primary, $primaryPosition, $identity) = array(false, null, false);
00219             if (strlen($row[$constraint_type])) {
00220                 $primary = true;
00221                 $primaryPosition = $row[$position];
00225                 $identity = false;
00226             }
00227 
00228             $dataType = trim($row[$data_type]);
00229             $newType = $fieldMaps[$dataType];
00230             if (is_array($newType) && $dataType == 'INT64')
00231                 $newType = $newType[$row[$sub_type]];
00232             $row[$data_type] = $newType;
00233 
00234             $desc[trim($row[$column_name])] = array(
00235                 'SCHEMA_NAME'      => '',
00236                 'TABLE_NAME'       => trim($row[$table_name]),
00237                 'COLUMN_NAME'      => trim($row[$column_name]),
00238                 'COLUMN_POSITION'  => $row[$column_id] +1,
00239                 'DATA_TYPE'        => $row[$data_type],
00240                 'DEFAULT'          => $row[$data_default],
00241                 'NULLABLE'         => (bool) ($row[$nullable] != '1'),
00242                 'LENGTH'           => $row[$data_length],
00243                 'SCALE'            => ($row[$data_scale] == 0 ? null : $row[$data_scale]),
00244                 'PRECISION'        => ($row[$data_precision] == 0 ? null : $row[$data_precision]),
00245                 'UNSIGNED'         => false,
00246                 'PRIMARY'          => $primary,
00247                 'PRIMARY_POSITION' => ($primary ? $primaryPosition+1 : null),
00248                 'IDENTITY'         => $identity
00249             );
00250         }
00251         return $desc;
00252     }
00253 
00254 
00260     protected function _formatDbConnString($host, $port, $dbname)
00261     {
00262         if (is_numeric($port))
00263             $port = '/' . (integer) $port;
00264         if ($dbname)
00265             $dbname = ':' . $dbname;
00266 
00267         return $host . $port . $dbname;
00268 
00269     }
00270 
00277     protected function _connect()
00278     {
00279         if (isset($this->_connection) && is_resource($this->_connection)) {
00280             return;
00281         }
00282 
00283         if (!extension_loaded('interbase')) {
00287             require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
00288             throw new ZendX_Db_Adapter_Firebird_Exception('The Interbase extension is required for this adapter but the extension is not loaded');
00289         }
00290 
00291 
00292         // Suppress connection warnings here.
00293         // Throw an exception instead.
00294         $this->_connection = @ibase_connect(
00295                                 $this->_formatDbConnString($this->_config['host'],$this->_config['port'] ,$this->_config['dbname']),
00296                                 $this->_config['username'],
00297                                 $this->_config['password'],
00298                                 $this->_config['charset'],
00299                                 $this->_config['buffers'],
00300                                 $this->_config['dialect'],
00301                                 $this->_config['role']
00302                               );
00303 
00304         if ($this->_connection === false) {
00308             require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
00309             throw new ZendX_Db_Adapter_Firebird_Exception(ibase_errmsg());
00310         }
00311     }
00312 
00318     public function closeConnection()
00319     {
00320         if (is_resource($this->_transResource)) {
00321             ibase_rollback($this->_transResource);
00322         }
00323         $this->_transResource = null;
00324 
00325         if (is_resource($this->_connection)) {
00326             unset($this->_connection);
00327         }
00328         //$this->_connection = false;
00329     }
00330 
00337     public function prepare($sql)
00338     {
00339         $this->_connect();
00340 
00341         $stmt = new ZendX_Db_Statement_Firebird($this, $sql);
00342         if ($stmt === false) {
00343             return false;
00344         }
00345         $stmt->setFetchMode($this->_fetchMode);
00346         return $stmt;
00347     }
00348 
00367     public function lastInsertId($tableName = null, $primaryKey = null)
00368     {
00369         if ($tableName !== null) {
00370             $sequenceName = $tableName;
00371             if ($primaryKey) {
00372                 $sequenceName .= "_$primaryKey";
00373             }
00374             $sequenceName .= '_seq';
00375             return $this->lastSequenceId($sequenceName);
00376         }
00377 
00378         // No support for IDENTITY columns; return null
00379         return null;
00380     }
00381 
00387     protected function _beginTransaction()
00388     {
00389         $this->_connect();
00390         if (is_resource($this->_transResource)){
00391             return;
00392         }
00393 
00394         $this->_transResource = ibase_trans(IBASE_DEFAULT, $this->_connection);
00395     }
00396 
00402     protected function _commit()
00403     {
00404         if (false === ibase_commit(is_resource($this->_transResource) ? $this->_transResource : $this->_connection)) {
00408             require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
00409             throw new ZendX_Db_Adapter_Firebird_Exception(ibase_errmsg());
00410         }
00411         $this->_transResource = null;
00412     }
00413 
00419     protected function _rollBack()
00420     {
00421         if (false === ibase_rollback(is_resource($this->_transResource) ? $this->_transResource : $this->_connection)) {
00425             require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
00426             throw new ZendX_Db_Adapter_Firebird_Exception(ibase_errmsg());
00427         }
00428         $this->_transResource = null;
00429     }
00430 
00437     public function setFetchMode($mode)
00438     {
00439         switch ($mode) {
00440             case Zend_Db::FETCH_LAZY:
00441             case Zend_Db::FETCH_ASSOC:
00442             case Zend_Db::FETCH_NUM:
00443             case Zend_Db::FETCH_BOTH:
00444             case Zend_Db::FETCH_NAMED:
00445             case Zend_Db::FETCH_OBJ:
00446             case Zend_Db::FETCH_BOUND: // bound to PHP variable
00447                 $this->_fetchMode = $mode;
00448                 break;
00449             default:
00453                 require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
00454                 throw new ZendX_Db_Adapter_Firebird_Exception("Invalid fetch mode '$mode' specified");
00455         }
00456     }
00457 
00467     public function limit($sql, $count, $offset = 0)
00468     {
00469         $count = intval($count);
00470         if ($count <= 0) {
00474             require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
00475             throw new ZendX_Db_Adapter_Firebird_Exception("LIMIT argument count=$count is not valid");
00476         }
00477 
00478         $offset = intval($offset);
00479         if ($offset < 0) {
00483             require_once 'ZendX/Db/Adapter/Firebird/Exception.php';
00484             throw new ZendX_Db_Adapter_Firebird_Exception("LIMIT argument offset=$offset is not valid");
00485         }
00486 
00487         if (trim($sql) == ''){
00488             //Only compatible with FB 2.0 or newer
00489             //ZF 1.5.0 don't support limit sql syntax that don't only append texto to sql, fixed in 1.5.1
00490             $sql .= " rows $count";
00491             if ($offset > 0)
00492                 $sql .= " to $offset";
00493         }
00494         else
00495             $sql = substr_replace($sql, "select first $count skip $offset ", stripos($sql, 'select'), 6);
00496 
00497         return $sql;
00498     }
00499 
00508     public function quoteTableAs($ident, $alias = null, $auto=false)
00509     {
00510         // Firebird doesn't allow the 'AS' keyword between the table identifier/expression and alias.
00511         return $this->_quoteIdentifierAs($ident, $alias, $auto, ' ');
00512     }
00513 
00522     public function lastSequenceId($sequenceName)
00523     {
00524         $this->_connect();
00525         $sql = 'SELECT GEN_ID('.$this->quoteIdentifier($sequenceName).', 0) FROM RDB$DATABASE';
00526         $value = $this->fetchOne($sql);
00527         return $value;
00528     }
00529 
00538     public function nextSequenceId($sequenceName)
00539     {
00540         $this->_connect();
00541         $sql = 'SELECT GEN_ID('.$this->quoteIdentifier($sequenceName).', 1) FROM RDB$DATABASE';
00542         $value = $this->fetchOne($sql);
00543         return $value;
00544     }
00545 
00552     public function supportsParameters($type)
00553     {
00554         switch ($type) {
00555             case 'positional':
00556                 return true;
00557             case 'named':
00558             default:
00559                 return false;
00560         }
00561     }
00562 
00568     public function isConnected()
00569     {
00570         return ((bool) (is_resource($this->_connection)
00571                      && get_resource_type($this->_connection) == 'Firebird/InterBase link'));
00572     }
00573 
00579     public function getServerVersion()
00580     {
00581         $this->_connect();
00582         $service = ibase_service_attach($this->_formatDbConnString($this->_config['host'], $this->_config['port'], ''), $this->_config['username'], $this->_config['password']);
00583 
00584         if ($service != FALSE) {
00585             $server_info  = ibase_server_info($service, IBASE_SVC_SERVER_VERSION);
00586             ibase_service_detach($service);
00587             $matches = null;
00588             if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $server_info, $matches)) {
00589                 return $matches[1];
00590             } else {
00591                 return null;
00592             }
00593         } else {
00594             return null;
00595         }
00596     }
00597 }

Generated on Thu Apr 19 2012 17:01:18 for openbiz by  doxygen 1.7.2