PageRenderTime 60ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/libs/Zend/Db/Statement/Oracle.php

https://github.com/quarkness/piwik
PHP | 577 lines | 295 code | 63 blank | 219 comment | 54 complexity | 1bf918c7b7c276847d1afe2e45d8c67e 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 Statement
  18. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Oracle.php 23959 2011-05-03 10:45:47Z yoshida@zend.co.jp $
  21. */
  22. /**
  23. * @see Zend_Db_Statement
  24. */
  25. // require_once 'Zend/Db/Statement.php';
  26. /**
  27. * Extends for Oracle.
  28. *
  29. * @category Zend
  30. * @package Zend_Db
  31. * @subpackage Statement
  32. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  33. * @license http://framework.zend.com/license/new-bsd New BSD License
  34. */
  35. class Zend_Db_Statement_Oracle extends Zend_Db_Statement
  36. {
  37. /**
  38. * Column names.
  39. */
  40. protected $_keys;
  41. /**
  42. * Fetched result values.
  43. */
  44. protected $_values;
  45. /**
  46. * Check if LOB field are returned as string
  47. * instead of OCI-Lob object
  48. *
  49. * @var boolean
  50. */
  51. protected $_lobAsString = false;
  52. /**
  53. * Activate/deactivate return of LOB as string
  54. *
  55. * @param string $lob_as_string
  56. * @return Zend_Db_Statement_Oracle
  57. */
  58. public function setLobAsString($lob_as_string)
  59. {
  60. $this->_lobAsString = (bool) $lob_as_string;
  61. return $this;
  62. }
  63. /**
  64. * Return whether or not LOB are returned as string
  65. *
  66. * @return boolean
  67. */
  68. public function getLobAsString()
  69. {
  70. return $this->_lobAsString;
  71. }
  72. /**
  73. * Prepares statement handle
  74. *
  75. * @param string $sql
  76. * @return void
  77. * @throws Zend_Db_Statement_Oracle_Exception
  78. */
  79. protected function _prepare($sql)
  80. {
  81. $connection = $this->_adapter->getConnection();
  82. $this->_stmt = @oci_parse($connection, $sql);
  83. if (!$this->_stmt) {
  84. /**
  85. * @see Zend_Db_Statement_Oracle_Exception
  86. */
  87. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  88. throw new Zend_Db_Statement_Oracle_Exception(oci_error($connection));
  89. }
  90. }
  91. /**
  92. * Binds a parameter to the specified variable name.
  93. *
  94. * @param mixed $parameter Name the parameter, either integer or string.
  95. * @param mixed $variable Reference to PHP variable containing the value.
  96. * @param mixed $type OPTIONAL Datatype of SQL parameter.
  97. * @param mixed $length OPTIONAL Length of SQL parameter.
  98. * @param mixed $options OPTIONAL Other options.
  99. * @return bool
  100. * @throws Zend_Db_Statement_Exception
  101. */
  102. protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
  103. {
  104. // default value
  105. if ($type === NULL) {
  106. $type = SQLT_CHR;
  107. }
  108. // default value
  109. if ($length === NULL) {
  110. $length = -1;
  111. }
  112. $retval = @oci_bind_by_name($this->_stmt, $parameter, $variable, $length, $type);
  113. if ($retval === false) {
  114. /**
  115. * @see Zend_Db_Adapter_Oracle_Exception
  116. */
  117. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  118. throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
  119. }
  120. return true;
  121. }
  122. /**
  123. * Closes the cursor, allowing the statement to be executed again.
  124. *
  125. * @return bool
  126. */
  127. public function closeCursor()
  128. {
  129. if (!$this->_stmt) {
  130. return false;
  131. }
  132. oci_free_statement($this->_stmt);
  133. $this->_stmt = false;
  134. return true;
  135. }
  136. /**
  137. * Returns the number of columns in the result set.
  138. * Returns null if the statement has no result set metadata.
  139. *
  140. * @return int The number of columns.
  141. */
  142. public function columnCount()
  143. {
  144. if (!$this->_stmt) {
  145. return false;
  146. }
  147. return oci_num_fields($this->_stmt);
  148. }
  149. /**
  150. * Retrieves the error code, if any, associated with the last operation on
  151. * the statement handle.
  152. *
  153. * @return string error code.
  154. */
  155. public function errorCode()
  156. {
  157. if (!$this->_stmt) {
  158. return false;
  159. }
  160. $error = oci_error($this->_stmt);
  161. if (!$error) {
  162. return false;
  163. }
  164. return $error['code'];
  165. }
  166. /**
  167. * Retrieves an array of error information, if any, associated with the
  168. * last operation on the statement handle.
  169. *
  170. * @return array
  171. */
  172. public function errorInfo()
  173. {
  174. if (!$this->_stmt) {
  175. return false;
  176. }
  177. $error = oci_error($this->_stmt);
  178. if (!$error) {
  179. return false;
  180. }
  181. if (isset($error['sqltext'])) {
  182. return array(
  183. $error['code'],
  184. $error['message'],
  185. $error['offset'],
  186. $error['sqltext'],
  187. );
  188. } else {
  189. return array(
  190. $error['code'],
  191. $error['message'],
  192. );
  193. }
  194. }
  195. /**
  196. * Executes a prepared statement.
  197. *
  198. * @param array $params OPTIONAL Values to bind to parameter placeholders.
  199. * @return bool
  200. * @throws Zend_Db_Statement_Exception
  201. */
  202. public function _execute(array $params = null)
  203. {
  204. $connection = $this->_adapter->getConnection();
  205. if (!$this->_stmt) {
  206. return false;
  207. }
  208. if ($params !== null) {
  209. if (!is_array($params)) {
  210. $params = array($params);
  211. }
  212. $error = false;
  213. foreach (array_keys($params) as $name) {
  214. if (!@oci_bind_by_name($this->_stmt, $name, $params[$name], -1)) {
  215. $error = true;
  216. break;
  217. }
  218. }
  219. if ($error) {
  220. /**
  221. * @see Zend_Db_Adapter_Oracle_Exception
  222. */
  223. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  224. throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
  225. }
  226. }
  227. $retval = @oci_execute($this->_stmt, $this->_adapter->_getExecuteMode());
  228. if ($retval === false) {
  229. /**
  230. * @see Zend_Db_Adapter_Oracle_Exception
  231. */
  232. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  233. throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
  234. }
  235. $this->_keys = Array();
  236. if ($field_num = oci_num_fields($this->_stmt)) {
  237. for ($i = 1; $i <= $field_num; $i++) {
  238. $name = oci_field_name($this->_stmt, $i);
  239. $this->_keys[] = $name;
  240. }
  241. }
  242. $this->_values = Array();
  243. if ($this->_keys) {
  244. $this->_values = array_fill(0, count($this->_keys), null);
  245. }
  246. return $retval;
  247. }
  248. /**
  249. * Fetches a row from the result set.
  250. *
  251. * @param int $style OPTIONAL Fetch mode for this fetch operation.
  252. * @param int $cursor OPTIONAL Absolute, relative, or other.
  253. * @param int $offset OPTIONAL Number for absolute or relative cursors.
  254. * @return mixed Array, object, or scalar depending on fetch mode.
  255. * @throws Zend_Db_Statement_Exception
  256. */
  257. public function fetch($style = null, $cursor = null, $offset = null)
  258. {
  259. if (!$this->_stmt) {
  260. return false;
  261. }
  262. if ($style === null) {
  263. $style = $this->_fetchMode;
  264. }
  265. $lob_as_string = $this->getLobAsString() ? OCI_RETURN_LOBS : 0;
  266. switch ($style) {
  267. case Zend_Db::FETCH_NUM:
  268. $row = oci_fetch_array($this->_stmt, OCI_NUM | OCI_RETURN_NULLS | $lob_as_string);
  269. break;
  270. case Zend_Db::FETCH_ASSOC:
  271. $row = oci_fetch_array($this->_stmt, OCI_ASSOC | OCI_RETURN_NULLS | $lob_as_string);
  272. break;
  273. case Zend_Db::FETCH_BOTH:
  274. $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string);
  275. break;
  276. case Zend_Db::FETCH_OBJ:
  277. $row = oci_fetch_object($this->_stmt);
  278. break;
  279. case Zend_Db::FETCH_BOUND:
  280. $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string);
  281. if ($row !== false) {
  282. return $this->_fetchBound($row);
  283. }
  284. break;
  285. default:
  286. /**
  287. * @see Zend_Db_Adapter_Oracle_Exception
  288. */
  289. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  290. throw new Zend_Db_Statement_Oracle_Exception(
  291. array(
  292. 'code' => 'HYC00',
  293. 'message' => "Invalid fetch mode '$style' specified"
  294. )
  295. );
  296. break;
  297. }
  298. if (! $row && $error = oci_error($this->_stmt)) {
  299. /**
  300. * @see Zend_Db_Adapter_Oracle_Exception
  301. */
  302. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  303. throw new Zend_Db_Statement_Oracle_Exception($error);
  304. }
  305. if (is_array($row) && array_key_exists('zend_db_rownum', $row)) {
  306. unset($row['zend_db_rownum']);
  307. }
  308. return $row;
  309. }
  310. /**
  311. * Returns an array containing all of the result set rows.
  312. *
  313. * @param int $style OPTIONAL Fetch mode.
  314. * @param int $col OPTIONAL Column number, if fetch mode is by column.
  315. * @return array Collection of rows, each in a format by the fetch mode.
  316. * @throws Zend_Db_Statement_Exception
  317. */
  318. public function fetchAll($style = null, $col = 0)
  319. {
  320. if (!$this->_stmt) {
  321. return false;
  322. }
  323. // make sure we have a fetch mode
  324. if ($style === null) {
  325. $style = $this->_fetchMode;
  326. }
  327. $flags = OCI_FETCHSTATEMENT_BY_ROW;
  328. switch ($style) {
  329. case Zend_Db::FETCH_BOTH:
  330. /**
  331. * @see Zend_Db_Adapter_Oracle_Exception
  332. */
  333. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  334. throw new Zend_Db_Statement_Oracle_Exception(
  335. array(
  336. 'code' => 'HYC00',
  337. 'message' => "OCI8 driver does not support fetchAll(FETCH_BOTH), use fetch() in a loop instead"
  338. )
  339. );
  340. // notreached
  341. $flags |= OCI_NUM;
  342. $flags |= OCI_ASSOC;
  343. break;
  344. case Zend_Db::FETCH_NUM:
  345. $flags |= OCI_NUM;
  346. break;
  347. case Zend_Db::FETCH_ASSOC:
  348. $flags |= OCI_ASSOC;
  349. break;
  350. case Zend_Db::FETCH_OBJ:
  351. break;
  352. case Zend_Db::FETCH_COLUMN:
  353. $flags = $flags &~ OCI_FETCHSTATEMENT_BY_ROW;
  354. $flags |= OCI_FETCHSTATEMENT_BY_COLUMN;
  355. $flags |= OCI_NUM;
  356. break;
  357. default:
  358. /**
  359. * @see Zend_Db_Adapter_Oracle_Exception
  360. */
  361. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  362. throw new Zend_Db_Statement_Oracle_Exception(
  363. array(
  364. 'code' => 'HYC00',
  365. 'message' => "Invalid fetch mode '$style' specified"
  366. )
  367. );
  368. break;
  369. }
  370. $result = Array();
  371. if ($flags != OCI_FETCHSTATEMENT_BY_ROW) { /* not Zend_Db::FETCH_OBJ */
  372. if (! ($rows = oci_fetch_all($this->_stmt, $result, 0, -1, $flags) )) {
  373. if ($error = oci_error($this->_stmt)) {
  374. /**
  375. * @see Zend_Db_Adapter_Oracle_Exception
  376. */
  377. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  378. throw new Zend_Db_Statement_Oracle_Exception($error);
  379. }
  380. if (!$rows) {
  381. return array();
  382. }
  383. }
  384. if ($style == Zend_Db::FETCH_COLUMN) {
  385. $result = $result[$col];
  386. }
  387. foreach ($result as &$row) {
  388. if (is_array($row) && array_key_exists('zend_db_rownum', $row)) {
  389. unset($row['zend_db_rownum']);
  390. }
  391. }
  392. } else {
  393. while (($row = oci_fetch_object($this->_stmt)) !== false) {
  394. $result [] = $row;
  395. }
  396. if ($error = oci_error($this->_stmt)) {
  397. /**
  398. * @see Zend_Db_Adapter_Oracle_Exception
  399. */
  400. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  401. throw new Zend_Db_Statement_Oracle_Exception($error);
  402. }
  403. }
  404. return $result;
  405. }
  406. /**
  407. * Returns a single column from the next row of a result set.
  408. *
  409. * @param int $col OPTIONAL Position of the column to fetch.
  410. * @return string
  411. * @throws Zend_Db_Statement_Exception
  412. */
  413. public function fetchColumn($col = 0)
  414. {
  415. if (!$this->_stmt) {
  416. return false;
  417. }
  418. if (!oci_fetch($this->_stmt)) {
  419. // if no error, there is simply no record
  420. if (!$error = oci_error($this->_stmt)) {
  421. return false;
  422. }
  423. /**
  424. * @see Zend_Db_Adapter_Oracle_Exception
  425. */
  426. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  427. throw new Zend_Db_Statement_Oracle_Exception($error);
  428. }
  429. $data = oci_result($this->_stmt, $col+1); //1-based
  430. if ($data === false) {
  431. /**
  432. * @see Zend_Db_Adapter_Oracle_Exception
  433. */
  434. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  435. throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
  436. }
  437. if ($this->getLobAsString()) {
  438. // instanceof doesn't allow '-', we must use a temporary string
  439. $type = 'OCI-Lob';
  440. if ($data instanceof $type) {
  441. $data = $data->read($data->size());
  442. }
  443. }
  444. return $data;
  445. }
  446. /**
  447. * Fetches the next row and returns it as an object.
  448. *
  449. * @param string $class OPTIONAL Name of the class to create.
  450. * @param array $config OPTIONAL Constructor arguments for the class.
  451. * @return mixed One object instance of the specified class.
  452. * @throws Zend_Db_Statement_Exception
  453. */
  454. public function fetchObject($class = 'stdClass', array $config = array())
  455. {
  456. if (!$this->_stmt) {
  457. return false;
  458. }
  459. $obj = oci_fetch_object($this->_stmt);
  460. if ($error = oci_error($this->_stmt)) {
  461. /**
  462. * @see Zend_Db_Adapter_Oracle_Exception
  463. */
  464. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  465. throw new Zend_Db_Statement_Oracle_Exception($error);
  466. }
  467. /* @todo XXX handle parameters */
  468. return $obj;
  469. }
  470. /**
  471. * Retrieves the next rowset (result set) for a SQL statement that has
  472. * multiple result sets. An example is a stored procedure that returns
  473. * the results of multiple queries.
  474. *
  475. * @return bool
  476. * @throws Zend_Db_Statement_Exception
  477. */
  478. public function nextRowset()
  479. {
  480. /**
  481. * @see Zend_Db_Statement_Oracle_Exception
  482. */
  483. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  484. throw new Zend_Db_Statement_Oracle_Exception(
  485. array(
  486. 'code' => 'HYC00',
  487. 'message' => 'Optional feature not implemented'
  488. )
  489. );
  490. }
  491. /**
  492. * Returns the number of rows affected by the execution of the
  493. * last INSERT, DELETE, or UPDATE statement executed by this
  494. * statement object.
  495. *
  496. * @return int The number of rows affected.
  497. * @throws Zend_Db_Statement_Exception
  498. */
  499. public function rowCount()
  500. {
  501. if (!$this->_stmt) {
  502. return false;
  503. }
  504. $num_rows = oci_num_rows($this->_stmt);
  505. if ($num_rows === false) {
  506. /**
  507. * @see Zend_Db_Adapter_Oracle_Exception
  508. */
  509. // require_once 'Zend/Db/Statement/Oracle/Exception.php';
  510. throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
  511. }
  512. return $num_rows;
  513. }
  514. }