blob: f168131e64de99ae4cfb4ef9991ecea3cd1ed584 [file] [log] [blame]
Andrey Andreev24abcb92012-01-05 20:40:15 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev24abcb92012-01-05 20:40:15 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev24abcb92012-01-05 20:40:15 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
Andrey Andreev342a4662012-01-24 15:24:00 +020012 * bundled with this package in the files license.txt / license.rst. It is
Derek Jonesf4a4bd82011-10-20 12:18:42 -050013 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Barry Mienydd671972010-10-04 16:33:58 +020019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
Barry Mienydd671972010-10-04 16:33:58 +020024 * @since Version 1.0
Derek Allard2067d1a2008-11-13 22:59:24 +000025 * @filesource
26 */
27
Derek Allard2067d1a2008-11-13 22:59:24 +000028/**
29 * oci8 Result Class
30 *
31 * This class extends the parent result class: CI_DB_result
32 *
33 * @category Database
Derek Jonesf4a4bd82011-10-20 12:18:42 -050034 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000035 * @link http://codeigniter.com/user_guide/database/
Andrey Andreev5ca05132012-07-05 12:06:34 +030036 * @since 1.4.1
Derek Allard2067d1a2008-11-13 22:59:24 +000037 */
38class CI_DB_oci8_result extends CI_DB_result {
39
Andrey Andreev24abcb92012-01-05 20:40:15 +020040 public $stmt_id;
41 public $curs_id;
42 public $limit_used;
Andrey Andreev99013ed2012-03-05 16:17:32 +020043 public $commit_mode;
Andrey Andreev24abcb92012-01-05 20:40:15 +020044
Andrey Andreev5ca05132012-07-05 12:06:34 +030045 /**
46 * Constructor
47 *
48 * @param object
49 * @return void
Andrey Andreev24abcb92012-01-05 20:40:15 +020050 */
Andrey Andreev57bdeb62012-03-05 15:59:16 +020051 public function __construct(&$driver_object)
52 {
53 parent::__construct($driver_object);
Andrey Andreev5ca05132012-07-05 12:06:34 +030054
Andrey Andreev57bdeb62012-03-05 15:59:16 +020055 $this->stmt_id = $driver_object->stmt_id;
56 $this->curs_id = $driver_object->curs_id;
57 $this->limit_used = $driver_object->limit_used;
Andrey Andreev99013ed2012-03-05 16:17:32 +020058 $this->commit_mode =& $driver_object->commit_mode;
Andrey Andreev57bdeb62012-03-05 15:59:16 +020059 $driver_object->stmt_id = FALSE;
60 }
Derek Allard2067d1a2008-11-13 22:59:24 +000061
Andrey Andreev5ca05132012-07-05 12:06:34 +030062 // --------------------------------------------------------------------
63
Derek Allard2067d1a2008-11-13 22:59:24 +000064 /**
65 * Number of rows in the result set.
66 *
Andrey Andreev24abcb92012-01-05 20:40:15 +020067 * Oracle doesn't have a graceful way to return the number of rows
Derek Allard2067d1a2008-11-13 22:59:24 +000068 * so we have to use what amounts to a hack.
Barry Mienydd671972010-10-04 16:33:58 +020069 *
Andrey Andreevaa786c92012-01-16 12:14:45 +020070 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +000071 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +030072 public function num_rows()
Derek Allard2067d1a2008-11-13 22:59:24 +000073 {
Andrey Andreev24abcb92012-01-05 20:40:15 +020074 if ( ! is_int($this->num_rows))
Derek Allard2067d1a2008-11-13 22:59:24 +000075 {
Andrey Andreev24abcb92012-01-05 20:40:15 +020076 if (count($this->result_array) > 0)
Andrey Andreevef3e2402011-09-21 14:39:29 +030077 {
Andrey Andreev24abcb92012-01-05 20:40:15 +020078 return $this->num_rows = count($this->result_array);
Andrey Andreevef3e2402011-09-21 14:39:29 +030079 }
Andrey Andreev24abcb92012-01-05 20:40:15 +020080 elseif (count($this->result_object) > 0)
81 {
Andrey Andreevb5e6f112012-01-16 13:25:07 +020082 return $this->num_rows = count($this->result_object);
Andrey Andreev24abcb92012-01-05 20:40:15 +020083 }
84
85 return $this->num_rows = count($this->result_array());
Derek Allard2067d1a2008-11-13 22:59:24 +000086 }
87
Andrey Andreevef3e2402011-09-21 14:39:29 +030088 return $this->num_rows;
Derek Allard2067d1a2008-11-13 22:59:24 +000089 }
90
91 // --------------------------------------------------------------------
92
93 /**
94 * Number of fields in the result set
95 *
Andrey Andreevaa786c92012-01-16 12:14:45 +020096 * @return int
Derek Allard2067d1a2008-11-13 22:59:24 +000097 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +030098 public function num_fields()
Derek Allard2067d1a2008-11-13 22:59:24 +000099 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300100 $count = @oci_num_fields($this->stmt_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000101
102 // if we used a limit we subtract it
Andrey Andreevaa786c92012-01-16 12:14:45 +0200103 return ($this->limit_used) ? $count - 1 : $count;
Derek Allard2067d1a2008-11-13 22:59:24 +0000104 }
105
106 // --------------------------------------------------------------------
107
108 /**
109 * Fetch Field Names
110 *
111 * Generates an array of column names
112 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000113 * @return array
114 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300115 public function list_fields()
Derek Allard2067d1a2008-11-13 22:59:24 +0000116 {
117 $field_names = array();
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300118 for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000119 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300120 $field_names[] = oci_field_name($this->stmt_id, $c);
Derek Allard2067d1a2008-11-13 22:59:24 +0000121 }
122 return $field_names;
123 }
124
125 // --------------------------------------------------------------------
126
127 /**
128 * Field data
129 *
130 * Generates an array of objects containing field meta-data
131 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200132 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300134 public function field_data()
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 {
136 $retval = array();
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300137 for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200139 $F = new stdClass();
140 $F->name = oci_field_name($this->stmt_id, $c);
141 $F->type = oci_field_type($this->stmt_id, $c);
142 $F->max_length = oci_field_size($this->stmt_id, $c);
Derek Allard2067d1a2008-11-13 22:59:24 +0000143
144 $retval[] = $F;
145 }
146
147 return $retval;
148 }
149
150 // --------------------------------------------------------------------
151
152 /**
153 * Free the result
154 *
Andrey Andreev24abcb92012-01-05 20:40:15 +0200155 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200156 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300157 public function free_result()
Derek Allard2067d1a2008-11-13 22:59:24 +0000158 {
159 if (is_resource($this->result_id))
160 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300161 oci_free_statement($this->result_id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000162 $this->result_id = FALSE;
163 }
Andrey Andreev24abcb92012-01-05 20:40:15 +0200164
165 if (is_resource($this->stmt_id))
166 {
167 oci_free_statement($this->stmt_id);
168 }
169
170 if (is_resource($this->curs_id))
171 {
172 oci_cancel($this->curs_id);
173 $this->curs_id = NULL;
174 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 }
176
177 // --------------------------------------------------------------------
178
179 /**
180 * Result - associative array
181 *
182 * Returns the result set as an array
183 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200184 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300186 protected function _fetch_assoc()
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 {
188 $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300189 return oci_fetch_assoc($id);
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 }
191
192 // --------------------------------------------------------------------
193
194 /**
195 * Result - object
196 *
197 * Returns the result set as an object
198 *
Andrey Andreevaa786c92012-01-16 12:14:45 +0200199 * @return object
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 */
Andrey Andreevbc95e472011-10-20 09:44:48 +0300201 protected function _fetch_object()
Barry Mienydd671972010-10-04 16:33:58 +0200202 {
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300203 $id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200204 return oci_fetch_object($id);
205 }
206
207 // --------------------------------------------------------------------
208
Derek Allard2067d1a2008-11-13 22:59:24 +0000209 /**
Andrey Andreeve35d7782012-01-19 15:56:20 +0200210 * Query result. Array version.
Derek Allard2067d1a2008-11-13 22:59:24 +0000211 *
Andrey Andreev24abcb92012-01-05 20:40:15 +0200212 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000213 */
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300214 public function result_array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000215 {
216 if (count($this->result_array) > 0)
217 {
218 return $this->result_array;
219 }
Andrey Andreev24abcb92012-01-05 20:40:15 +0200220 elseif (count($this->result_object) > 0)
221 {
222 for ($i = 0, $c = count($this->result_object); $i < $c; $i++)
223 {
224 $this->result_array[$i] = (array) $this->result_object[$i];
225 }
226
227 return $this->result_array;
228 }
229 elseif (is_array($this->row_data))
230 {
231 if (count($this->row_data) === 0)
232 {
233 return $this->result_array;
234 }
235 else
236 {
237 $row_index = count($this->row_data);
238 }
239 }
240 else
241 {
242 $row_index = 0;
243 $this->row_data = array();
244 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000245
Derek Allard2067d1a2008-11-13 22:59:24 +0000246 $row = NULL;
Andrey Andreev5c3a2022011-10-07 21:04:58 +0300247 while ($row = $this->_fetch_assoc())
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200249 $this->row_data[$row_index++] = $row;
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 }
251
Andrey Andreev24abcb92012-01-05 20:40:15 +0200252 return $this->result_array = $this->row_data;
253 }
254
255 // --------------------------------------------------------------------
256
257 /**
258 * Query result. "object" version.
259 *
260 * @return array
261 */
262 public function result_object()
263 {
264 if (count($this->result_object) > 0)
265 {
266 return $this->result_object;
267 }
268 elseif (count($this->result_array) > 0)
269 {
270 for ($i = 0, $c = count($this->result_array); $i < $c; $i++)
271 {
272 $this->result_object[] = (object) $this->result_array[$i];
273 }
274
275 return $this->result_object;
276 }
277 elseif (is_array($this->row_data))
278 {
279 if (count($this->row_data) === 0)
280 {
281 return $this->result_object;
282 }
283 else
284 {
285 $row_index = count($this->row_data);
286 for ($i = 0; $i < $row_index; $i++)
287 {
288 $this->result_object[$i] = (object) $this->row_data[$i];
289 }
290 }
291 }
292 else
293 {
294 $row_index = 0;
295 $this->row_data = array();
296 }
297
298 $row = NULL;
299 while ($row = $this->_fetch_object())
300 {
301 $this->row_data[$row_index] = (array) $row;
302 $this->result_object[$row_index++] = $row;
303 }
304
Andrey Andreev24abcb92012-01-05 20:40:15 +0200305 return $this->result_object;
306 }
307
308 // --------------------------------------------------------------------
309
310 /**
311 * Query result. Custom object version.
312 *
313 * @param string class name used to instantiate rows to
314 * @return array
315 */
316 public function custom_result_object($class_name)
317 {
Andrey Andreev574c85d2012-02-12 20:40:53 +0200318 if (isset($this->custom_result_object[$class_name]))
Andrey Andreev24abcb92012-01-05 20:40:15 +0200319 {
320 return $this->custom_result_object[$class_name];
321 }
322
323 if ( ! class_exists($class_name) OR $this->result_id === FALSE OR $this->num_rows() === 0)
324 {
325 return array();
326 }
327
Andrey Andreevb5e6f112012-01-16 13:25:07 +0200328 /* Even if we didn't have result_array or result_object
329 * set prior to custom_result_object() being called,
330 * num_rows() has already done so.
331 * Pass by reference, as we don't know how
Andrey Andreev24abcb92012-01-05 20:40:15 +0200332 * large it might be and we don't want 1000 row
333 * sets being copied.
334 */
335 if (count($this->result_array) > 0)
336 {
337 $data = &$this->result_array;
338 }
339 elseif (count($this->result_object) > 0)
340 {
341 $data = &$this->result_object;
342 }
343
Andrey Andreev574c85d2012-02-12 20:40:53 +0200344 $this->custom_result_object[$class_name] = array();
Andrey Andreevb5e6f112012-01-16 13:25:07 +0200345 for ($i = 0, $c = count($data); $i < $c; $i++)
Andrey Andreev24abcb92012-01-05 20:40:15 +0200346 {
Andrey Andreev574c85d2012-02-12 20:40:53 +0200347 $this->custom_result_object[$class_name][$i] = new $class_name();
Andrey Andreevb5e6f112012-01-16 13:25:07 +0200348 foreach ($data[$i] as $key => $value)
Andrey Andreev24abcb92012-01-05 20:40:15 +0200349 {
Andrey Andreev574c85d2012-02-12 20:40:53 +0200350 $this->custom_result_object[$class_name][$i]->$key = $value;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200351 }
352 }
Andrey Andreev24abcb92012-01-05 20:40:15 +0200353
Andrey Andreev574c85d2012-02-12 20:40:53 +0200354 return $this->custom_result_object[$class_name];
Andrey Andreev74e50982012-02-12 20:46:10 +0200355 }
Andrey Andreev24abcb92012-01-05 20:40:15 +0200356
357 // --------------------------------------------------------------------
358
359 /* Single row result.
360 *
361 * Acts as a wrapper for row_object(), row_array()
362 * and custom_row_object(). Also used by first_row(), next_row()
363 * and previous_row().
364 *
365 * @param int row index
366 * @param string ('object', 'array' or a custom class name)
367 * @return mixed whatever was passed to the second parameter
368 */
Andrey Andreev24abcb92012-01-05 20:40:15 +0200369 public function row($n = 0, $type = 'object')
370 {
Andrey Andreevaa786c92012-01-16 12:14:45 +0200371 if ($type === 'object')
372 {
373 return $this->row_object($n);
374 }
375 elseif ($type === 'array')
376 {
377 return $this->row_array($n);
378 }
379
380 return $this->custom_row_object($n, $type);
Andrey Andreev24abcb92012-01-05 20:40:15 +0200381 }
382
383 // --------------------------------------------------------------------
384
385 /* Single row result. Array version.
386 *
387 * @param int row index
388 * @return array
389 */
Andrey Andreev24abcb92012-01-05 20:40:15 +0200390 public function row_array($n = 0)
391 {
392 // Make sure $n is not a string
393 if ( ! is_int($n))
394 {
395 $n = (int) $n;
396 }
397
398 /* If row_data is initialized, it means that we've already tried
399 * (at least) to fetch some data, so ... check if we already have
400 * this row.
401 */
402 if (is_array($this->row_data))
403 {
404 /* If we already have row_data[$n] - return it.
405 *
406 * If we enter the elseif, there's a number of reasons to
407 * return an empty array:
408 *
409 * - count($this->row_data) === 0 means there are no results
410 * - num_rows being set, result_array and/or result_object
411 * having count() > 0 means that we've already fetched all
412 * data and $n is greater than our highest row index available
413 * - $n < $this->current_row means that if such row existed,
414 * we would've already returned it, therefore $n is an
415 * invalid index
416 */
417 if (isset($this->row_data[$n])) // We already have this row
418 {
419 $this->current_row = $n;
420 return $this->row_data[$n];
421 }
422 elseif (count($this->row_data) === 0 OR is_int($this->num_rows)
423 OR count($this->result_array) > 0 OR count($this->result_object) > 0
424 OR $n < $this->current_row)
425 {
426 // No such row exists
Andrey Andreev55d3ad42012-05-24 22:13:06 +0300427 return NULL;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200428 }
429
430 // Get the next row index that would actually need to be fetched
431 $current_row = ($this->current_row < count($this->row_data)) ? count($this->row_data) : $this->current_row + 1;
432 }
433 else
434 {
435 $current_row = $this->current_row = 0;
436 $this->row_data = array();
437 }
438
439 /* Fetch more data, if available
440 *
441 * NOTE: Operator precedence is important here, if you change
442 * 'AND' with '&&' - it WILL BREAK the results, as
443 * $row will be assigned the scalar value of both
444 * expressions!
445 */
446 while ($row = $this->_fetch_assoc() AND $current_row <= $n)
447 {
448 $this->row_data[$current_row++] = $row;
449 }
450
451 // This would mean that there's no (more) data to fetch
452 if ( ! is_array($this->row_data) OR ! isset($this->row_data[$n]))
453 {
454 // Cache what we already have
455 if (is_array($this->row_data))
456 {
457 $this->num_rows = count($this->row_data);
458 /* Usually, row_data could have less elements than result_array,
459 * but at this point - they should be exactly the same.
460 */
461 $this->result_array = $this->row_data;
462 }
463 else
464 {
465 $this->num_rows = 0;
466 }
467
Andrey Andreev55d3ad42012-05-24 22:13:06 +0300468 return NULL;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200469 }
470
471 $this->current_row = $n;
472 return $this->row_data[$n];
473 }
474
475 // --------------------------------------------------------------------
476
477 /* Single row result. Object version.
478 *
479 * @param int row index
480 * @return mixed object if row found; empty array if not
481 */
482 public function row_object($n = 0)
483 {
484 // Make sure $n is not a string
485 if ( ! is_int($n))
486 {
487 $n = (int) $n;
488 }
489 /* Logic here is exactly the same as in row_array,
490 * except we have to cast row_data[$n] to an object.
491 *
492 * If we already have result_object though - we can
493 * directly return from it.
494 */
495 if (isset($this->result_object[$n]))
496 {
497 $this->current_row = $n;
498 // Set this, if not already done.
499 if ( ! is_int($this->num_rows))
500 {
501 $this->num_rows = count($this->result_object);
502 }
503
504 return $this->result_object[$n];
505 }
506
507 $row = $this->row_array($n);
508 // Cast only if the row exists
509 if (count($row) > 0)
510 {
511 $this->current_row = $n;
512 return (object) $row;
513 }
514
Andrey Andreev55d3ad42012-05-24 22:13:06 +0300515 return NULL;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200516 }
517
518 // --------------------------------------------------------------------
519
520 /* Single row result. Custom object version.
521 *
522 * @param int row index
523 * @param string custom class name
524 * @return mixed custom object if row found; empty array otherwise
525 */
Andrey Andreev24abcb92012-01-05 20:40:15 +0200526 public function custom_row_object($n = 0, $class_name)
527 {
528 // Make sure $n is not a string
529 if ( ! is_int($n))
530 {
531 $n = (int) $n;
532 }
533
534 if (array_key_exists($class_name, $this->custom_result_object))
535 {
536 /* We already have a the whole result set with this class_name,
537 * return the specified row if it exists, and an empty array if
538 * it doesn't.
539 */
540 if (isset($this->custom_result_object[$class_name][$n]))
541 {
542 $this->current_row = $n;
543 return $this->custom_result_object[$class_name][$n];
544 }
545 else
546 {
Andrey Andreev55d3ad42012-05-24 22:13:06 +0300547 return NULL;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200548 }
549 }
550 elseif ( ! class_exists($class_name)) // No such class exists
551 {
Andrey Andreev55d3ad42012-05-24 22:13:06 +0300552 return NULL;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200553 }
554
555 $row = $this->row_array($n);
Andrey Andreev55d3ad42012-05-24 22:13:06 +0300556 // A non-array would mean that the row doesn't exist
557 if ( ! is_array($row))
Andrey Andreev24abcb92012-01-05 20:40:15 +0200558 {
Andrey Andreev55d3ad42012-05-24 22:13:06 +0300559 return NULL;
Andrey Andreev24abcb92012-01-05 20:40:15 +0200560 }
561
562 // Convert to the desired class and return
563 $row_object = new $class_name();
564 foreach ($row as $key => $value)
565 {
566 $row_object->$key = $value;
567 }
568
569 $this->current_row = $n;
570 return $row_object;
571 }
572
573 // --------------------------------------------------------------------
574
575 /* First row result.
576 *
577 * @param string ('object', 'array' or a custom class name)
578 * @return mixed whatever was passed to the second parameter
579 */
Andrey Andreev24abcb92012-01-05 20:40:15 +0200580 public function first_row($type = 'object')
581 {
582 return $this->row(0, $type);
583 }
584
585 // --------------------------------------------------------------------
586
587 /* Last row result.
588 *
589 * @param string ('object', 'array' or a custom class name)
590 * @return mixed whatever was passed to the second parameter
591 */
592 public function last_row($type = 'object')
593 {
594 $result = &$this->result($type);
595 if ( ! isset($this->num_rows))
596 {
597 $this->num_rows = count($result);
598 }
599 $this->current_row = $this->num_rows - 1;
600 return $result[$this->current_row];
601 }
602
603 // --------------------------------------------------------------------
604
605 /* Next row result.
606 *
607 * @param string ('object', 'array' or a custom class name)
608 * @return mixed whatever was passed to the second parameter
609 */
610 public function next_row($type = 'object')
611 {
612 if (is_array($this->row_data))
613 {
614 $count = count($this->row_data);
615 if ($this->current_row > $count OR ($this->current_row === 0 && $count === 0))
616 {
617 $n = $count;
618 }
619 else
620 {
621 $n = $this->current_row + 1;
622 }
623 }
624 else
625 {
626 $n = 0;
627 }
628
629 return $this->row($n, $type);
630 }
631
632 // --------------------------------------------------------------------
633
634 /* Previous row result.
635 *
636 * @param string ('object', 'array' or a custom class name)
637 * @return mixed whatever was passed to the second parameter
638 */
639 public function previous_row($type = 'object')
640 {
641 $n = ($this->current_row !== 0) ? $this->current_row - 1 : 0;
642 return $this->row($n, $type);
Derek Allard2067d1a2008-11-13 22:59:24 +0000643 }
644
645 // --------------------------------------------------------------------
646
647 /**
648 * Data Seek
649 *
Andrey Andreev24abcb92012-01-05 20:40:15 +0200650 * Moves the internal pointer to the desired offset. We call
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 * this internally before fetching results to make sure the
Andrey Andreev24abcb92012-01-05 20:40:15 +0200652 * result set starts at zero.
Derek Allard2067d1a2008-11-13 22:59:24 +0000653 *
Andrey Andreev24abcb92012-01-05 20:40:15 +0200654 * Oracle's PHP extension doesn't have an easy way of doing this
655 * and the only workaround is to (re)execute the statement or cursor
656 * in order to go to the first (zero) index of the result set.
657 * Then, we would need to "dummy" fetch ($n - 1) rows to get to the
658 * right one.
659 *
660 * This is as ridiculous as it sounds and it's the reason why every
661 * other method that is fetching data tries to use an already "cached"
662 * result set. Keeping this just in case it becomes needed at
663 * some point in the future, but it will only work for resetting the
664 * pointer to zero.
665 *
666 * @return bool
Derek Allard2067d1a2008-11-13 22:59:24 +0000667 */
Andrey Andreev24abcb92012-01-05 20:40:15 +0200668 protected function _data_seek()
Derek Allard2067d1a2008-11-13 22:59:24 +0000669 {
Andrey Andreev24abcb92012-01-05 20:40:15 +0200670 /* The PHP manual says that if OCI_NO_AUTO_COMMIT mode
671 * is used, and oci_rollback() and/or oci_commit() are
672 * not subsequently called - this will cause an unnecessary
673 * rollback to be triggered at the end of the script execution.
674 *
675 * Therefore we'll try to avoid using that mode flag
676 * if we're not currently in the middle of a transaction.
677 */
678 if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
679 {
680 $result = @oci_execute($this->stmt_id, $this->commit_mode);
681 }
682 else
683 {
684 $result = @oci_execute($this->stmt_id);
685 }
686
687 if ($result && $this->curs_id)
688 {
689 if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
690 {
691 return @oci_execute($this->curs_id, $this->commit_mode);
692 }
693 else
694 {
695 return @oci_execute($this->curs_id);
696 }
697 }
698
699 return $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000700 }
701
702}
703
Derek Allard2067d1a2008-11-13 22:59:24 +0000704/* End of file oci8_result.php */
Timothy Warren215890b2012-03-20 09:38:16 -0400705/* Location: ./system/database/drivers/oci8/oci8_result.php */