- <?php defined('SYSPATH') or die('No direct script access.');
- // candidate to extend Kohana_Database_Result
- // statement wrapper
- /*
- The following methods are inherited:
- cached()
- get()
- count()
- offsetExists()
- offsetGet()
- offsetSet()
- offsetUnset()
- key()
- */
- class Musterdb_Database_Result_PDO extends Database_Result
- {
- protected $_sql;
- protected $_statement;
- protected $_cursor_scroll; // Boolean
- protected $_emulate_cursor; // Boolean
- protected $_fetch_style; // pdo constant
- protected $_parameters; // save for rewind
- // currency
- protected $_total_rows = 0;
- protected $_current_row = 0;
- // protected $_internal_row = -1;
- protected $_BOF = TRUE;
- protected $_row_data; // current row data
- public function __construct($statement, $sql, $as_object, $config = array())
- {
- $config = $config + array(
- 'cursorscroll' => FALSE,
- 'emulatecursor' => FALSE,
- );
- $this->_cursor_scroll = $config['cursorscroll'];
- $this->_emulate_cursor = $config['emulatecursor'];
- // Store the statement locally
- $this->_statement = $this->_result = $statement; // _result = Kohana legacy
- // Store the SQL locally
- $this->_sql = $this->_query = $sql; // _query = Kohana legacy
- if (is_object($as_object))
- {
- // Get the object class name
- $as_object = get_class($as_object);
- }
- // Results as objects or associative arrays
- $this->_as_object = $as_object;
- $this->_total_rows = $statement->rowCount();
- $this->_fetch_style = ($this->_as_object === FALSE)? PDO::FETCH_ASSOC : PDO::FETCH_CLASS;
- }
- public function __destruct()
- {
- $this->_statement = NULL;
- }
- // note that rewind not called at end.
- public function as_array($key = NULL, $value = NULL)
- {
- $rows = $this->_statement->fetchAll($this->_fetch_style);
- $results = array();
- if ($key === NULL AND $value === NULL)
- {
- // Indexed rows
- $results = $rows;
- }
- elseif ($key === NULL)
- {
- // Indexed columns
- if ($this->_as_object)
- {
- foreach ($rows as $row)
- {
- $results[] = $row->$value;
- }
- }
- else
- {
- foreach ($rows as $row)
- {
- $results[] = $row[$value];
- }
- }
- }
- elseif ($value === NULL)
- {
- // Associative rows
- if ($this->_as_object)
- {
- foreach ($rows as $row)
- {
- $results[$row->$key] = $row;
- }
- }
- else
- {
- foreach ($rows as $row)
- {
- $results[$row[$key]] = $row;
- }
- }
- }
- else
- {
- // Associative columns
- if ($this->_as_object)
- {
- foreach ($rows as $row)
- {
- $results[$row->$key] = $row->$value;
- }
- }
- else
- {
- foreach ($rows as $row)
- {
- $results[$row[$key]] = $row[$value];
- }
- }
- }
- if ($this->_cursor_scroll or $this->_emulate_cursor)
- $this->rewind();
- return $results;
- }
- public function seek($offset)
- {
- if (!$this->offsetExists($offset))
- return FALSE;
- if ($this->_cursor_scroll)
- {
- if ($this->_BOF) $this_BOF = FALSE;
- $this->_current_row = $offet; // $this->_internal_row = $offset;
- return TRUE;
- }
- elseif ($offset < $this->_current_row)
- {
- if ($this->_emulate_cursor)
- {
- $this->rewind();
- }
- else
- throw new Kohana_Exception('Database statement is forward moving only, cannot seek backwards');
- }
- // increment next to offset
- while ($this->_current_row < $offset)
- $this->next();
- return TRUE;
- }
- public function current()
- {
- if ($this->_cursor_scroll)
- {
- return $this->_statement->fetch($this->_fetch_style,PDO::FETCH_ORI_ABS,$this->_current_row);
- }
- else
- {
- if ($this->_BOF) // get first
- $this->next();
- return $this->_row_data;
- }
- }
- public function next()
- {
- if ($this->_BOF)
- $this->_BOF = FALSE;
- else
- {
- $this->_current_row++;
- }
- if (!$this->_cursor_scroll)
- {
- if ($this->_current_row < $this->_total_rows)
- {
- $this->_row_data = $this->_statement->fetch($this->_fetch_style,PDO::FETCH_ORI_NEXT);
- }
- else
- {
- $this->_row_data = NULL;
- }
- }
- return $this;
- }
- public function prev()
- {
- if ($this->_BOF) return $this;
- if ($this->_cursor_scroll)
- {
- if ($this->_current_row == 0)
- $this->_BOF = TRUE;
- elseif ($this->_current_row > 0)
- $this->_current_row--;
- }
- elseif ($this->_emulate_cursor)
- {
- if ($this->_current_row == 0)
- $this->_BOF = TRUE;
- else
- $this->seek($this->_current_row - 1);
- }
- else
- {
- throw new Kohana_Exception('Database statement is forward moving only, cannot go to previous');
- }
- return $this;
- }
- // fetch next
- public function fetch()
- {
- return $this->next()->current();
- }
- public function rewind()
- {
- if ($this->_BOF) return $this;
- $this->_BOF = TRUE;
- $this->_current_row = 0;
- if ($this->_emulate_cursor)
- {
- $this->_statement->closeCursor();
- if (empty($this->_parameters))
- $this->_statement->execute();
- else
- $this->_statement->execute($this->_parameters);
- }
- else
- throw new Kohana_Exception('Database statement is forward moving only, cannot rewind');
- return $this;
- }
- public function execute($parameters = array()) // for prepare
- {
- $statement = $this->_statement;
- if (empty($parameters))
- $statement->execute();
- else
- $statement->execute($parameters);
- $this->_total_rows = $statement->rowCount();
- $this->_parameters = $parameters;
- return $this;
- }
- public function errorCode()
- {
- return $this->_statement->errorCode(); // SQLSTATE
- }
- public function errorInfo()
- {
- return $this->_statement->errorInfo(); // array(0=>SQLSTATE,1=>drivererrorcode,2=>errormessage)
- }
- public function statement()
- {
- return $this->_statement;
- }
- public function sql()
- {
- return $this->_sql;
- }
- public function valid()
- {
- return (boolean) (($this->_current_row >= 0) and ($this->_current_row < $this->_total_rows));
- }
- public function row_count()
- {
- return $this->_total_rows;
- }
- }