2
0

Db2.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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. * @package Zend_Db
  16. * @subpackage Statement
  17. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. */
  20. /**
  21. * @see Zend_Db_Statement
  22. */
  23. require_once 'Zend/Db/Statement.php';
  24. /**
  25. * Extends for DB2 native adapter.
  26. *
  27. * @package Zend_Db
  28. * @subpackage Statement
  29. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. */
  32. class Zend_Db_Statement_Db2 extends Zend_Db_Statement
  33. {
  34. /**
  35. * Statement resource handle.
  36. */
  37. protected $_stmt = null;
  38. /**
  39. * Column names.
  40. */
  41. protected $_keys;
  42. /**
  43. * Fetched result values.
  44. */
  45. protected $_values;
  46. /**
  47. * Prepare a statement handle.
  48. *
  49. * @param string $sql
  50. * @return void
  51. * @throws Zend_Db_Statement_Db2_Exception
  52. */
  53. public function _prepare($sql)
  54. {
  55. $connection = $this->_adapter->getConnection();
  56. // db2_prepare on i5 emits errors, these need to be
  57. // suppressed so that proper exceptions can be thrown
  58. $this->_stmt = @db2_prepare($connection, $sql);
  59. if (!$this->_stmt) {
  60. /**
  61. * @see Zend_Db_Statement_Db2_Exception
  62. */
  63. require_once 'Zend/Db/Statement/Db2/Exception.php';
  64. throw new Zend_Db_Statement_Db2_Exception(
  65. db2_stmt_errormsg(),
  66. db2_stmt_error()
  67. );
  68. }
  69. }
  70. /**
  71. * Binds a parameter to the specified variable name.
  72. *
  73. * @param mixed $parameter Name the parameter, either integer or string.
  74. * @param mixed $variable Reference to PHP variable containing the value.
  75. * @param mixed $type OPTIONAL Datatype of SQL parameter.
  76. * @param mixed $length OPTIONAL Length of SQL parameter.
  77. * @param mixed $options OPTIONAL Other options.
  78. * @return bool
  79. * @throws Zend_Db_Statement_Db2_Exception
  80. */
  81. public function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
  82. {
  83. if ($type === null) {
  84. $type = DB2_PARAM_IN;
  85. }
  86. if (isset($options['data-type'])) {
  87. $datatype = $options['data-type'];
  88. } else {
  89. $datatype = DB2_CHAR;
  90. }
  91. if (!db2_bind_param($this->_stmt, $position, "variable", $type, $datatype)) {
  92. /**
  93. * @see Zend_Db_Statement_Db2_Exception
  94. */
  95. require_once 'Zend/Db/Statement/Db2/Exception.php';
  96. throw new Zend_Db_Statement_Db2_Exception(
  97. db2_stmt_errormsg(),
  98. db2_stmt_error()
  99. );
  100. }
  101. return true;
  102. }
  103. /**
  104. * Closes the cursor, allowing the statement to be executed again.
  105. *
  106. * @return bool
  107. */
  108. public function closeCursor()
  109. {
  110. if (!$this->_stmt) {
  111. return false;
  112. }
  113. db2_free_stmt($this->_stmt);
  114. $this->_stmt = false;
  115. return true;
  116. }
  117. /**
  118. * Returns the number of columns in the result set.
  119. * Returns null if the statement has no result set metadata.
  120. *
  121. * @return int The number of columns.
  122. */
  123. public function columnCount()
  124. {
  125. if (!$this->_stmt) {
  126. return false;
  127. }
  128. return db2_num_fields($this->_stmt);
  129. }
  130. /**
  131. * Retrieves the error code, if any, associated with the last operation on
  132. * the statement handle.
  133. *
  134. * @return string error code.
  135. */
  136. public function errorCode()
  137. {
  138. if (!$this->_stmt) {
  139. return false;
  140. }
  141. $error = db2_stmt_error();
  142. if ($error === '') {
  143. return false;
  144. }
  145. return $error;
  146. }
  147. /**
  148. * Retrieves an array of error information, if any, associated with the
  149. * last operation on the statement handle.
  150. *
  151. * @return array
  152. */
  153. public function errorInfo()
  154. {
  155. $error = $this->errorCode();
  156. if ($error === false){
  157. return false;
  158. }
  159. /*
  160. * Return three-valued array like PDO. But DB2 does not distinguish
  161. * between SQLCODE and native RDBMS error code, so repeat the SQLCODE.
  162. */
  163. return array(
  164. $error,
  165. $error,
  166. db2_stmt_errormsg()
  167. );
  168. }
  169. /**
  170. * Executes a prepared statement.
  171. *
  172. * @param array $params OPTIONAL Values to bind to parameter placeholders.
  173. * @return bool
  174. * @throws Zend_Db_Statement_Db2_Exception
  175. */
  176. public function _execute(array $params = null)
  177. {
  178. if (!$this->_stmt) {
  179. return false;
  180. }
  181. $retval = true;
  182. if ($params !== null) {
  183. $retval = @db2_execute($this->_stmt, $params);
  184. } else {
  185. $retval = @db2_execute($this->_stmt);
  186. }
  187. if ($retval === false) {
  188. /**
  189. * @see Zend_Db_Statement_Db2_Exception
  190. */
  191. require_once 'Zend/Db/Statement/Db2/Exception.php';
  192. throw new Zend_Db_Statement_Db2_Exception(
  193. db2_stmt_errormsg(),
  194. db2_stmt_error());
  195. }
  196. $this->_keys = array();
  197. if ($field_num = $this->columnCount()) {
  198. for ($i = 0; $i < $field_num; $i++) {
  199. $name = db2_field_name($this->_stmt, $i);
  200. $this->_keys[] = $name;
  201. }
  202. }
  203. $this->_values = array();
  204. if ($this->_keys) {
  205. $this->_values = array_fill(0, count($this->_keys), null);
  206. }
  207. return $retval;
  208. }
  209. /**
  210. * Fetches a row from the result set.
  211. *
  212. * @param int $style OPTIONAL Fetch mode for this fetch operation.
  213. * @param int $cursor OPTIONAL Absolute, relative, or other.
  214. * @param int $offset OPTIONAL Number for absolute or relative cursors.
  215. * @return mixed Array, object, or scalar depending on fetch mode.
  216. * @throws Zend_Db_Statement_Db2_Exception
  217. */
  218. public function fetch($style = null, $cursor = null, $offset = null)
  219. {
  220. if (!$this->_stmt) {
  221. return false;
  222. }
  223. if ($style === null) {
  224. $style = $this->_fetchMode;
  225. }
  226. switch ($style) {
  227. case Zend_Db::FETCH_NUM :
  228. $row = db2_fetch_array($this->_stmt);
  229. break;
  230. case Zend_Db::FETCH_ASSOC :
  231. $row = db2_fetch_assoc($this->_stmt);
  232. break;
  233. case Zend_Db::FETCH_BOTH :
  234. $row = db2_fetch_both($this->_stmt);
  235. break;
  236. case Zend_Db::FETCH_OBJ :
  237. $row = db2_fetch_object($this->_stmt);
  238. break;
  239. case Zend_Db::FETCH_BOUND:
  240. $row = db2_fetch_both($this->_stmt);
  241. if ($row !== false) {
  242. return $this->_fetchBound($row);
  243. }
  244. break;
  245. default:
  246. /**
  247. * @see Zend_Db_Statement_Db2_Exception
  248. */
  249. require_once 'Zend/Db/Statement/Db2/Exception.php';
  250. throw new Zend_Db_Statement_Db2_Exception("Invalid fetch mode '$style' specified");
  251. break;
  252. }
  253. return $row;
  254. }
  255. /**
  256. * Fetches the next row and returns it as an object.
  257. *
  258. * @param string $class OPTIONAL Name of the class to create.
  259. * @param array $config OPTIONAL Constructor arguments for the class.
  260. * @return mixed One object instance of the specified class.
  261. */
  262. public function fetchObject($class = 'stdClass', array $config = array())
  263. {
  264. $obj = $this->fetch(Zend_Db::FETCH_OBJ);
  265. return $obj;
  266. }
  267. /**
  268. * Retrieves the next rowset (result set) for a SQL statement that has
  269. * multiple result sets. An example is a stored procedure that returns
  270. * the results of multiple queries.
  271. *
  272. * @return bool
  273. * @throws Zend_Db_Statement_Db2_Exception
  274. */
  275. public function nextRowset()
  276. {
  277. /**
  278. * @see Zend_Db_Statement_Db2_Exception
  279. */
  280. require_once 'Zend/Db/Statement/Db2/Exception.php';
  281. throw new Zend_Db_Statement_Db2_Exception(__FUNCTION__ . '() is not implemented');
  282. }
  283. /**
  284. * Returns the number of rows affected by the execution of the
  285. * last INSERT, DELETE, or UPDATE statement executed by this
  286. * statement object.
  287. *
  288. * @return int The number of rows affected.
  289. */
  290. public function rowCount()
  291. {
  292. if (!$this->_stmt) {
  293. return false;
  294. }
  295. $num = @db2_num_rows($this->_stmt);
  296. if ($num === false) {
  297. return 0;
  298. }
  299. return $num;
  300. }
  301. /**
  302. * Returns an array containing all of the result set rows.
  303. *
  304. * @param int $style OPTIONAL Fetch mode.
  305. * @param int $col OPTIONAL Column number, if fetch mode is by column.
  306. * @return array Collection of rows, each in a format by the fetch mode.
  307. *
  308. * Behaves like parent, but if limit()
  309. * is used, the final result removes the extra column
  310. * 'zend_db_rownum'
  311. */
  312. public function fetchAll($style = null, $col = null)
  313. {
  314. $data = parent::fetchAll($style, $col);
  315. $results = array();
  316. $remove = $this->_adapter->foldCase('ZEND_DB_ROWNUM');
  317. foreach ($data as $row) {
  318. if (is_array($row) && array_key_exists($remove, $row)) {
  319. unset($row[$remove]);
  320. }
  321. $results[] = $row;
  322. }
  323. return $results;
  324. }
  325. }