00001 <?php
00025 require_once 'Zend/Db/Adapter/Pdo/Abstract.php';
00026
00028 require_once 'Zend/Db/Adapter/Pdo/Ibm/Db2.php';
00029
00031 require_once 'Zend/Db/Adapter/Pdo/Ibm/Ids.php';
00032
00034 require_once 'Zend/Db/Statement/Pdo/Ibm.php';
00035
00036
00044 class Zend_Db_Adapter_Pdo_Ibm extends Zend_Db_Adapter_Pdo_Abstract
00045 {
00051 protected $_pdoType = 'ibm';
00052
00058 protected $_serverType = null;
00059
00071 protected $_numericDataTypes = array(
00072 Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
00073 Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
00074 Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
00075 'INTEGER' => Zend_Db::INT_TYPE,
00076 'SMALLINT' => Zend_Db::INT_TYPE,
00077 'BIGINT' => Zend_Db::BIGINT_TYPE,
00078 'DECIMAL' => Zend_Db::FLOAT_TYPE,
00079 'DEC' => Zend_Db::FLOAT_TYPE,
00080 'REAL' => Zend_Db::FLOAT_TYPE,
00081 'NUMERIC' => Zend_Db::FLOAT_TYPE,
00082 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE,
00083 'FLOAT' => Zend_Db::FLOAT_TYPE
00084 );
00085
00096 public function _connect()
00097 {
00098 if ($this->_connection) {
00099 return;
00100 }
00101 parent::_connect();
00102
00103 $this->getConnection()->setAttribute(Zend_Db::ATTR_STRINGIFY_FETCHES, true);
00104
00105 try {
00106 if ($this->_serverType === null) {
00107 $server = substr($this->getConnection()->getAttribute(PDO::ATTR_SERVER_INFO), 0, 3);
00108
00109 switch ($server) {
00110 case 'DB2':
00111 $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Db2($this);
00112
00113
00114 $this->_numericDataTypes['DECFLOAT'] = Zend_Db::FLOAT_TYPE;
00115 $this->_numericDataTypes['DOUBLE'] = Zend_Db::FLOAT_TYPE;
00116 $this->_numericDataTypes['NUM'] = Zend_Db::FLOAT_TYPE;
00117
00118 break;
00119 case 'IDS':
00120 $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Ids($this);
00121
00122
00123 $this->_numericDataTypes['SERIAL'] = Zend_Db::INT_TYPE;
00124 $this->_numericDataTypes['SERIAL8'] = Zend_Db::BIGINT_TYPE;
00125 $this->_numericDataTypes['INT8'] = Zend_Db::BIGINT_TYPE;
00126 $this->_numericDataTypes['SMALLFLOAT'] = Zend_Db::FLOAT_TYPE;
00127 $this->_numericDataTypes['MONEY'] = Zend_Db::FLOAT_TYPE;
00128
00129 break;
00130 }
00131 }
00132 } catch (PDOException $e) {
00134 require_once 'Zend/Db/Adapter/Exception.php';
00135 $error = strpos($e->getMessage(), 'driver does not support that attribute');
00136 if ($error) {
00137 throw new Zend_Db_Adapter_Exception("PDO_IBM driver extension is downlevel. Please use driver release version 1.2.1 or later");
00138 } else {
00139 throw new Zend_Db_Adapter_Exception($e->getMessage());
00140 }
00141 }
00142 }
00143
00149 protected function _dsn()
00150 {
00151 $this->_checkRequiredOptions($this->_config);
00152
00153
00154 if (array_key_exists('host', $this->_config)) {
00155 $dsn = ';DATABASE=' . $this->_config['dbname']
00156 . ';HOSTNAME=' . $this->_config['host']
00157 . ';PORT=' . $this->_config['port']
00158
00159 . ';PROTOCOL=' . 'TCPIP;';
00160 } else {
00161
00162 $dsn = $this->_config['dbname'];
00163 }
00164 return $this->_pdoType . ': ' . $dsn;
00165 }
00166
00174 protected function _checkRequiredOptions(array $config)
00175 {
00176 parent::_checkRequiredOptions($config);
00177
00178 if (array_key_exists('host', $this->_config) &&
00179 !array_key_exists('port', $config)) {
00181 require_once 'Zend/Db/Adapter/Exception.php';
00182 throw new Zend_Db_Adapter_Exception("Configuration must have a key for 'port' when 'host' is specified");
00183 }
00184 }
00185
00193 public function prepare($sql)
00194 {
00195 $this->_connect();
00196 $stmtClass = $this->_defaultStmtClass;
00197 $stmt = new $stmtClass($this, $sql);
00198 $stmt->setFetchMode($this->_fetchMode);
00199 return $stmt;
00200 }
00201
00207 public function listTables()
00208 {
00209 $this->_connect();
00210 return $this->_serverType->listTables();
00211 }
00212
00242 public function describeTable($tableName, $schemaName = null)
00243 {
00244 $this->_connect();
00245 return $this->_serverType->describeTable($tableName, $schemaName);
00246 }
00247
00257 public function insert($table, array $bind)
00258 {
00259 $this->_connect();
00260 $newbind = array();
00261 if (is_array($bind)) {
00262 foreach ($bind as $name => $value) {
00263 if($value !== null) {
00264 $newbind[$name] = $value;
00265 }
00266 }
00267 }
00268
00269 return parent::insert($table, $newbind);
00270 }
00271
00280 public function limit($sql, $count, $offset = 0)
00281 {
00282 $this->_connect();
00283 return $this->_serverType->limit($sql, $count, $offset);
00284 }
00285
00294 public function lastInsertId($tableName = null, $primaryKey = null)
00295 {
00296 $this->_connect();
00297
00298 if ($tableName !== null) {
00299 $sequenceName = $tableName;
00300 if ($primaryKey) {
00301 $sequenceName .= "_$primaryKey";
00302 }
00303 $sequenceName .= '_seq';
00304 return $this->lastSequenceId($sequenceName);
00305 }
00306
00307 $id = $this->getConnection()->lastInsertId();
00308
00309 return $id;
00310 }
00311
00318 public function lastSequenceId($sequenceName)
00319 {
00320 $this->_connect();
00321 return $this->_serverType->lastSequenceId($sequenceName);
00322 }
00323
00331 public function nextSequenceId($sequenceName)
00332 {
00333 $this->_connect();
00334 return $this->_serverType->nextSequenceId($sequenceName);
00335 }
00336
00342 public function getServerVersion()
00343 {
00344 try {
00345 $stmt = $this->query('SELECT service_level, fixpack_num FROM TABLE (sysproc.env_get_inst_info()) as INSTANCEINFO');
00346 $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
00347 if (count($result)) {
00348 $matches = null;
00349 if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $result[0][0], $matches)) {
00350 return $matches[1];
00351 } else {
00352 return null;
00353 }
00354 }
00355 return null;
00356 } catch (PDOException $e) {
00357 return null;
00358 }
00359 }
00360 }