1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
22:
23: 24: 25:
26: require_once 'Zend/Db/Statement.php';
27:
28: 29: 30: 31: 32: 33: 34: 35: 36:
37: class Zend_Db_Statement_Oracle extends Zend_Db_Statement
38: {
39:
40: 41: 42:
43: protected $_keys;
44:
45: 46: 47:
48: protected $_values;
49:
50: 51: 52: 53: 54: 55:
56: protected $_lobAsString = false;
57:
58: 59: 60: 61: 62: 63:
64: public function setLobAsString($lob_as_string)
65: {
66: $this->_lobAsString = (bool) $lob_as_string;
67: return $this;
68: }
69:
70: 71: 72: 73: 74:
75: public function getLobAsString()
76: {
77: return $this->_lobAsString;
78: }
79:
80: 81: 82: 83: 84: 85: 86:
87: protected function _prepare($sql)
88: {
89: $connection = $this->_adapter->getConnection();
90: $this->_stmt = oci_parse($connection, $sql);
91: if (!$this->_stmt) {
92: 93: 94:
95: require_once 'Zend/Db/Statement/Oracle/Exception.php';
96: throw new Zend_Db_Statement_Oracle_Exception(oci_error($connection));
97: }
98: }
99:
100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110:
111: protected function _bindParam($parameter, &$variable, $type = null, $length = null, $options = null)
112: {
113:
114: if ($type === NULL) {
115: $type = SQLT_CHR;
116: }
117:
118:
119: if ($length === NULL) {
120: $length = -1;
121: }
122:
123: $retval = @oci_bind_by_name($this->_stmt, $parameter, $variable, $length, $type);
124: if ($retval === false) {
125: 126: 127:
128: require_once 'Zend/Db/Statement/Oracle/Exception.php';
129: throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
130: }
131:
132: return true;
133: }
134:
135: 136: 137: 138: 139:
140: public function closeCursor()
141: {
142: if (!$this->_stmt) {
143: return false;
144: }
145:
146: oci_free_statement($this->_stmt);
147: $this->_stmt = false;
148: return true;
149: }
150:
151: 152: 153: 154: 155: 156:
157: public function columnCount()
158: {
159: if (!$this->_stmt) {
160: return false;
161: }
162:
163: return oci_num_fields($this->_stmt);
164: }
165:
166:
167: 168: 169: 170: 171: 172:
173: public function errorCode()
174: {
175: if (!$this->_stmt) {
176: return false;
177: }
178:
179: $error = oci_error($this->_stmt);
180:
181: if (!$error) {
182: return false;
183: }
184:
185: return $error['code'];
186: }
187:
188:
189: 190: 191: 192: 193: 194:
195: public function errorInfo()
196: {
197: if (!$this->_stmt) {
198: return false;
199: }
200:
201: $error = oci_error($this->_stmt);
202: if (!$error) {
203: return false;
204: }
205:
206: if (isset($error['sqltext'])) {
207: return array(
208: $error['code'],
209: $error['message'],
210: $error['offset'],
211: $error['sqltext'],
212: );
213: } else {
214: return array(
215: $error['code'],
216: $error['message'],
217: );
218: }
219: }
220:
221:
222: 223: 224: 225: 226: 227: 228:
229: public function _execute(array $params = null)
230: {
231: $connection = $this->_adapter->getConnection();
232:
233: if (!$this->_stmt) {
234: return false;
235: }
236:
237: if ($params !== null) {
238: if (!is_array($params)) {
239: $params = array($params);
240: }
241: $error = false;
242: foreach (array_keys($params) as $name) {
243: if (!@oci_bind_by_name($this->_stmt, $name, $params[$name], -1)) {
244: $error = true;
245: break;
246: }
247: }
248: if ($error) {
249: 250: 251:
252: require_once 'Zend/Db/Statement/Oracle/Exception.php';
253: throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
254: }
255: }
256:
257: $retval = @oci_execute($this->_stmt, $this->_adapter->_getExecuteMode());
258: if ($retval === false) {
259: 260: 261:
262: require_once 'Zend/Db/Statement/Oracle/Exception.php';
263: throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
264: }
265:
266: $this->_keys = Array();
267: if ($field_num = oci_num_fields($this->_stmt)) {
268: for ($i = 1; $i <= $field_num; $i++) {
269: $name = oci_field_name($this->_stmt, $i);
270: $this->_keys[] = $name;
271: }
272: }
273:
274: $this->_values = Array();
275: if ($this->_keys) {
276: $this->_values = array_fill(0, count($this->_keys), null);
277: }
278:
279: return $retval;
280: }
281:
282: 283: 284: 285: 286: 287: 288: 289: 290:
291: public function fetch($style = null, $cursor = null, $offset = null)
292: {
293: if (!$this->_stmt) {
294: return false;
295: }
296:
297: if ($style === null) {
298: $style = $this->_fetchMode;
299: }
300:
301: $lob_as_string = $this->getLobAsString() ? OCI_RETURN_LOBS : 0;
302:
303: switch ($style) {
304: case Zend_Db::FETCH_NUM:
305: $row = oci_fetch_array($this->_stmt, OCI_NUM | OCI_RETURN_NULLS | $lob_as_string);
306: break;
307: case Zend_Db::FETCH_ASSOC:
308: $row = oci_fetch_array($this->_stmt, OCI_ASSOC | OCI_RETURN_NULLS | $lob_as_string);
309: break;
310: case Zend_Db::FETCH_BOTH:
311: $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string);
312: break;
313: case Zend_Db::FETCH_OBJ:
314: $row = oci_fetch_object($this->_stmt);
315: break;
316: case Zend_Db::FETCH_BOUND:
317: $row = oci_fetch_array($this->_stmt, OCI_BOTH | OCI_RETURN_NULLS | $lob_as_string);
318: if ($row !== false) {
319: return $this->_fetchBound($row);
320: }
321: break;
322: default:
323: 324: 325:
326: require_once 'Zend/Db/Statement/Oracle/Exception.php';
327: throw new Zend_Db_Statement_Oracle_Exception(
328: array(
329: 'code' => 'HYC00',
330: 'message' => "Invalid fetch mode '$style' specified"
331: )
332: );
333: break;
334: }
335:
336: if (! $row && $error = oci_error($this->_stmt)) {
337: 338: 339:
340: require_once 'Zend/Db/Statement/Oracle/Exception.php';
341: throw new Zend_Db_Statement_Oracle_Exception($error);
342: }
343:
344: if (is_array($row) && array_key_exists('zend_db_rownum', $row)) {
345: unset($row['zend_db_rownum']);
346: }
347:
348: return $row;
349: }
350:
351: 352: 353: 354: 355: 356: 357: 358:
359: public function fetchAll($style = null, $col = 0)
360: {
361: if (!$this->_stmt) {
362: return false;
363: }
364:
365:
366: if ($style === null) {
367: $style = $this->_fetchMode;
368: }
369:
370: $flags = OCI_FETCHSTATEMENT_BY_ROW;
371:
372: switch ($style) {
373: case Zend_Db::FETCH_BOTH:
374: 375: 376:
377: require_once 'Zend/Db/Statement/Oracle/Exception.php';
378: throw new Zend_Db_Statement_Oracle_Exception(
379: array(
380: 'code' => 'HYC00',
381: 'message' => "OCI8 driver does not support fetchAll(FETCH_BOTH), use fetch() in a loop instead"
382: )
383: );
384:
385: $flags |= OCI_NUM;
386: $flags |= OCI_ASSOC;
387: break;
388: case Zend_Db::FETCH_NUM:
389: $flags |= OCI_NUM;
390: break;
391: case Zend_Db::FETCH_ASSOC:
392: $flags |= OCI_ASSOC;
393: break;
394: case Zend_Db::FETCH_OBJ:
395: break;
396: case Zend_Db::FETCH_COLUMN:
397: $flags = $flags &~ OCI_FETCHSTATEMENT_BY_ROW;
398: $flags |= OCI_FETCHSTATEMENT_BY_COLUMN;
399: $flags |= OCI_NUM;
400: break;
401: default:
402: 403: 404:
405: require_once 'Zend/Db/Statement/Oracle/Exception.php';
406: throw new Zend_Db_Statement_Oracle_Exception(
407: array(
408: 'code' => 'HYC00',
409: 'message' => "Invalid fetch mode '$style' specified"
410: )
411: );
412: break;
413: }
414:
415: $result = Array();
416: if ($flags != OCI_FETCHSTATEMENT_BY_ROW) {
417: if (! ($rows = oci_fetch_all($this->_stmt, $result, 0, -1, $flags) )) {
418: if ($error = oci_error($this->_stmt)) {
419: 420: 421:
422: require_once 'Zend/Db/Statement/Oracle/Exception.php';
423: throw new Zend_Db_Statement_Oracle_Exception($error);
424: }
425: if (!$rows) {
426: return array();
427: }
428: }
429: if ($style == Zend_Db::FETCH_COLUMN) {
430: $result = $result[$col];
431: }
432: foreach ($result as &$row) {
433: if (is_array($row) && array_key_exists('zend_db_rownum', $row)) {
434: unset($row['zend_db_rownum']);
435: }
436: }
437: } else {
438: while (($row = oci_fetch_object($this->_stmt)) !== false) {
439: $result [] = $row;
440: }
441: if ($error = oci_error($this->_stmt)) {
442: 443: 444:
445: require_once 'Zend/Db/Statement/Oracle/Exception.php';
446: throw new Zend_Db_Statement_Oracle_Exception($error);
447: }
448: }
449:
450: return $result;
451: }
452:
453:
454: 455: 456: 457: 458: 459: 460:
461: public function fetchColumn($col = 0)
462: {
463: if (!$this->_stmt) {
464: return false;
465: }
466:
467: if (!oci_fetch($this->_stmt)) {
468:
469: if (!$error = oci_error($this->_stmt)) {
470: return false;
471: }
472: 473: 474:
475: require_once 'Zend/Db/Statement/Oracle/Exception.php';
476: throw new Zend_Db_Statement_Oracle_Exception($error);
477: }
478:
479: $data = oci_result($this->_stmt, $col+1);
480: if ($data === false) {
481: 482: 483:
484: require_once 'Zend/Db/Statement/Oracle/Exception.php';
485: throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
486: }
487:
488: if ($this->getLobAsString()) {
489:
490: $type = 'OCI-Lob';
491: if ($data instanceof $type) {
492: $data = $data->read($data->size());
493: }
494: }
495:
496: return $data;
497: }
498:
499: 500: 501: 502: 503: 504: 505: 506:
507: public function fetchObject($class = 'stdClass', array $config = array())
508: {
509: if (!$this->_stmt) {
510: return false;
511: }
512:
513: $obj = oci_fetch_object($this->_stmt);
514:
515: if ($error = oci_error($this->_stmt)) {
516: 517: 518:
519: require_once 'Zend/Db/Statement/Oracle/Exception.php';
520: throw new Zend_Db_Statement_Oracle_Exception($error);
521: }
522:
523:
524:
525: return $obj;
526: }
527:
528: 529: 530: 531: 532: 533: 534: 535:
536: public function nextRowset()
537: {
538: 539: 540:
541: require_once 'Zend/Db/Statement/Oracle/Exception.php';
542: throw new Zend_Db_Statement_Oracle_Exception(
543: array(
544: 'code' => 'HYC00',
545: 'message' => 'Optional feature not implemented'
546: )
547: );
548: }
549:
550: 551: 552: 553: 554: 555: 556: 557:
558: public function rowCount()
559: {
560: if (!$this->_stmt) {
561: return false;
562: }
563:
564: $num_rows = oci_num_rows($this->_stmt);
565:
566: if ($num_rows === false) {
567: 568: 569:
570: require_once 'Zend/Db/Statement/Oracle/Exception.php';
571: throw new Zend_Db_Statement_Oracle_Exception(oci_error($this->_stmt));
572: }
573:
574: return $num_rows;
575: }
576:
577: }
578: