PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/concrete/libraries/3rdparty/Zend/Db/Adapter/Pdo/Ibm.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 360 lines | 161 code | 34 blank | 165 comment | 16 complexity | ca52aa26c5f829863bea19e00f6405c9 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Db
  17. * @subpackage Adapter
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Ibm.php 24593 2012-01-05 20:35:02Z matthew $
  21. */
  22. /** @see Zend_Db_Adapter_Pdo_Abstract */
  23. require_once 'Zend/Db/Adapter/Pdo/Abstract.php';
  24. /** @see Zend_Db_Abstract_Pdo_Ibm_Db2 */
  25. require_once 'Zend/Db/Adapter/Pdo/Ibm/Db2.php';
  26. /** @see Zend_Db_Abstract_Pdo_Ibm_Ids */
  27. require_once 'Zend/Db/Adapter/Pdo/Ibm/Ids.php';
  28. /** @see Zend_Db_Statement_Pdo_Ibm */
  29. require_once 'Zend/Db/Statement/Pdo/Ibm.php';
  30. /**
  31. * @category Zend
  32. * @package Zend_Db
  33. * @subpackage Adapter
  34. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. */
  37. class Zend_Db_Adapter_Pdo_Ibm extends Zend_Db_Adapter_Pdo_Abstract
  38. {
  39. /**
  40. * PDO type.
  41. *
  42. * @var string
  43. */
  44. protected $_pdoType = 'ibm';
  45. /**
  46. * The IBM data server connected to
  47. *
  48. * @var string
  49. */
  50. protected $_serverType = null;
  51. /**
  52. * Keys are UPPERCASE SQL datatypes or the constants
  53. * Zend_Db::INT_TYPE, Zend_Db::BIGINT_TYPE, or Zend_Db::FLOAT_TYPE.
  54. *
  55. * Values are:
  56. * 0 = 32-bit integer
  57. * 1 = 64-bit integer
  58. * 2 = float or decimal
  59. *
  60. * @var array Associative array of datatypes to values 0, 1, or 2.
  61. */
  62. protected $_numericDataTypes = array(
  63. Zend_Db::INT_TYPE => Zend_Db::INT_TYPE,
  64. Zend_Db::BIGINT_TYPE => Zend_Db::BIGINT_TYPE,
  65. Zend_Db::FLOAT_TYPE => Zend_Db::FLOAT_TYPE,
  66. 'INTEGER' => Zend_Db::INT_TYPE,
  67. 'SMALLINT' => Zend_Db::INT_TYPE,
  68. 'BIGINT' => Zend_Db::BIGINT_TYPE,
  69. 'DECIMAL' => Zend_Db::FLOAT_TYPE,
  70. 'DEC' => Zend_Db::FLOAT_TYPE,
  71. 'REAL' => Zend_Db::FLOAT_TYPE,
  72. 'NUMERIC' => Zend_Db::FLOAT_TYPE,
  73. 'DOUBLE PRECISION' => Zend_Db::FLOAT_TYPE,
  74. 'FLOAT' => Zend_Db::FLOAT_TYPE
  75. );
  76. /**
  77. * Creates a PDO object and connects to the database.
  78. *
  79. * The IBM data server is set.
  80. * Current options are DB2 or IDS
  81. * @todo also differentiate between z/OS and i/5
  82. *
  83. * @return void
  84. * @throws Zend_Db_Adapter_Exception
  85. */
  86. public function _connect()
  87. {
  88. if ($this->_connection) {
  89. return;
  90. }
  91. parent::_connect();
  92. $this->getConnection()->setAttribute(Zend_Db::ATTR_STRINGIFY_FETCHES, true);
  93. try {
  94. if ($this->_serverType === null) {
  95. $server = substr($this->getConnection()->getAttribute(PDO::ATTR_SERVER_INFO), 0, 3);
  96. switch ($server) {
  97. case 'DB2':
  98. $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Db2($this);
  99. // Add DB2-specific numeric types
  100. $this->_numericDataTypes['DECFLOAT'] = Zend_Db::FLOAT_TYPE;
  101. $this->_numericDataTypes['DOUBLE'] = Zend_Db::FLOAT_TYPE;
  102. $this->_numericDataTypes['NUM'] = Zend_Db::FLOAT_TYPE;
  103. break;
  104. case 'IDS':
  105. $this->_serverType = new Zend_Db_Adapter_Pdo_Ibm_Ids($this);
  106. // Add IDS-specific numeric types
  107. $this->_numericDataTypes['SERIAL'] = Zend_Db::INT_TYPE;
  108. $this->_numericDataTypes['SERIAL8'] = Zend_Db::BIGINT_TYPE;
  109. $this->_numericDataTypes['INT8'] = Zend_Db::BIGINT_TYPE;
  110. $this->_numericDataTypes['SMALLFLOAT'] = Zend_Db::FLOAT_TYPE;
  111. $this->_numericDataTypes['MONEY'] = Zend_Db::FLOAT_TYPE;
  112. break;
  113. }
  114. }
  115. } catch (PDOException $e) {
  116. /** @see Zend_Db_Adapter_Exception */
  117. require_once 'Zend/Db/Adapter/Exception.php';
  118. $error = strpos($e->getMessage(), 'driver does not support that attribute');
  119. if ($error) {
  120. throw new Zend_Db_Adapter_Exception("PDO_IBM driver extension is downlevel. Please use driver release version 1.2.1 or later", 0, $e);
  121. } else {
  122. throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e);
  123. }
  124. }
  125. }
  126. /**
  127. * Creates a PDO DSN for the adapter from $this->_config settings.
  128. *
  129. * @return string
  130. */
  131. protected function _dsn()
  132. {
  133. $this->_checkRequiredOptions($this->_config);
  134. // check if using full connection string
  135. if (array_key_exists('host', $this->_config)) {
  136. $dsn = ';DATABASE=' . $this->_config['dbname']
  137. . ';HOSTNAME=' . $this->_config['host']
  138. . ';PORT=' . $this->_config['port']
  139. // PDO_IBM supports only DB2 TCPIP protocol
  140. . ';PROTOCOL=' . 'TCPIP;';
  141. } else {
  142. // catalogued connection
  143. $dsn = $this->_config['dbname'];
  144. }
  145. return $this->_pdoType . ': ' . $dsn;
  146. }
  147. /**
  148. * Checks required options
  149. *
  150. * @param array $config
  151. * @throws Zend_Db_Adapter_Exception
  152. * @return void
  153. */
  154. protected function _checkRequiredOptions(array $config)
  155. {
  156. parent::_checkRequiredOptions($config);
  157. if (array_key_exists('host', $this->_config) &&
  158. !array_key_exists('port', $config)) {
  159. /** @see Zend_Db_Adapter_Exception */
  160. require_once 'Zend/Db/Adapter/Exception.php';
  161. throw new Zend_Db_Adapter_Exception("Configuration must have a key for 'port' when 'host' is specified");
  162. }
  163. }
  164. /**
  165. * Prepares an SQL statement.
  166. *
  167. * @param string $sql The SQL statement with placeholders.
  168. * @param array $bind An array of data to bind to the placeholders.
  169. * @return PDOStatement
  170. */
  171. public function prepare($sql)
  172. {
  173. $this->_connect();
  174. $stmtClass = $this->_defaultStmtClass;
  175. $stmt = new $stmtClass($this, $sql);
  176. $stmt->setFetchMode($this->_fetchMode);
  177. return $stmt;
  178. }
  179. /**
  180. * Returns a list of the tables in the database.
  181. *
  182. * @return array
  183. */
  184. public function listTables()
  185. {
  186. $this->_connect();
  187. return $this->_serverType->listTables();
  188. }
  189. /**
  190. * Returns the column descriptions for a table.
  191. *
  192. * The return value is an associative array keyed by the column name,
  193. * as returned by the RDBMS.
  194. *
  195. * The value of each array element is an associative array
  196. * with the following keys:
  197. *
  198. * SCHEMA_NAME => string; name of database or schema
  199. * TABLE_NAME => string;
  200. * COLUMN_NAME => string; column name
  201. * COLUMN_POSITION => number; ordinal position of column in table
  202. * DATA_TYPE => string; SQL datatype name of column
  203. * DEFAULT => string; default expression of column, null if none
  204. * NULLABLE => boolean; true if column can have nulls
  205. * LENGTH => number; length of CHAR/VARCHAR
  206. * SCALE => number; scale of NUMERIC/DECIMAL
  207. * PRECISION => number; precision of NUMERIC/DECIMAL
  208. * UNSIGNED => boolean; unsigned property of an integer type
  209. * PRIMARY => boolean; true if column is part of the primary key
  210. * PRIMARY_POSITION => integer; position of column in primary key
  211. *
  212. * @todo Discover integer unsigned property.
  213. *
  214. * @param string $tableName
  215. * @param string $schemaName OPTIONAL
  216. * @return array
  217. */
  218. public function describeTable($tableName, $schemaName = null)
  219. {
  220. $this->_connect();
  221. return $this->_serverType->describeTable($tableName, $schemaName);
  222. }
  223. /**
  224. * Inserts a table row with specified data.
  225. * Special handling for PDO_IBM
  226. * remove empty slots
  227. *
  228. * @param mixed $table The table to insert data into.
  229. * @param array $bind Column-value pairs.
  230. * @return int The number of affected rows.
  231. */
  232. public function insert($table, array $bind)
  233. {
  234. $this->_connect();
  235. $newbind = array();
  236. if (is_array($bind)) {
  237. foreach ($bind as $name => $value) {
  238. if($value !== null) {
  239. $newbind[$name] = $value;
  240. }
  241. }
  242. }
  243. return parent::insert($table, $newbind);
  244. }
  245. /**
  246. * Adds an adapter-specific LIMIT clause to the SELECT statement.
  247. *
  248. * @param string $sql
  249. * @param integer $count
  250. * @param integer $offset OPTIONAL
  251. * @return string
  252. */
  253. public function limit($sql, $count, $offset = 0)
  254. {
  255. $this->_connect();
  256. return $this->_serverType->limit($sql, $count, $offset);
  257. }
  258. /**
  259. * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT
  260. * column.
  261. *
  262. * @param string $tableName OPTIONAL
  263. * @param string $primaryKey OPTIONAL
  264. * @return integer
  265. */
  266. public function lastInsertId($tableName = null, $primaryKey = null)
  267. {
  268. $this->_connect();
  269. if ($tableName !== null) {
  270. $sequenceName = $tableName;
  271. if ($primaryKey) {
  272. $sequenceName .= "_$primaryKey";
  273. }
  274. $sequenceName .= '_seq';
  275. return $this->lastSequenceId($sequenceName);
  276. }
  277. $id = $this->getConnection()->lastInsertId();
  278. return $id;
  279. }
  280. /**
  281. * Return the most recent value from the specified sequence in the database.
  282. *
  283. * @param string $sequenceName
  284. * @return integer
  285. */
  286. public function lastSequenceId($sequenceName)
  287. {
  288. $this->_connect();
  289. return $this->_serverType->lastSequenceId($sequenceName);
  290. }
  291. /**
  292. * Generate a new value from the specified sequence in the database,
  293. * and return it.
  294. *
  295. * @param string $sequenceName
  296. * @return integer
  297. */
  298. public function nextSequenceId($sequenceName)
  299. {
  300. $this->_connect();
  301. return $this->_serverType->nextSequenceId($sequenceName);
  302. }
  303. /**
  304. * Retrieve server version in PHP style
  305. * Pdo_Idm doesn't support getAttribute(PDO::ATTR_SERVER_VERSION)
  306. * @return string
  307. */
  308. public function getServerVersion()
  309. {
  310. try {
  311. $stmt = $this->query('SELECT service_level, fixpack_num FROM TABLE (sysproc.env_get_inst_info()) as INSTANCEINFO');
  312. $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
  313. if (count($result)) {
  314. $matches = null;
  315. if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $result[0][0], $matches)) {
  316. return $matches[1];
  317. } else {
  318. return null;
  319. }
  320. }
  321. return null;
  322. } catch (PDOException $e) {
  323. return null;
  324. }
  325. }
  326. }