1<?php 2/** 3 * Copyright 2013-2017 Horde LLC (http://www.horde.org/) 4 * 5 * @author Jan Schneider <jan@horde.org> 6 * @license http://www.horde.org/licenses/bsd 7 * @category Horde 8 * @package Db 9 * @subpackage Adapter 10 */ 11 12/** 13 * This class represents the result set of a SELECT query. 14 * 15 * @author Jan Schneider <jan@horde.org> 16 * @license http://www.horde.org/licenses/bsd 17 * @category Horde 18 * @package Db 19 * @subpackage Adapter 20 */ 21abstract class Horde_Db_Adapter_Base_Result implements Iterator 22{ 23 /** 24 * @var Horde_Db_Adapter 25 */ 26 protected $_adapter; 27 28 /** 29 * @var string 30 */ 31 protected $_sql; 32 33 /** 34 * @var mixed 35 */ 36 protected $_arg1; 37 38 /** 39 * @var string 40 */ 41 protected $_arg2; 42 43 /** 44 * Result resource. 45 * 46 * @var resource 47 */ 48 protected $_result; 49 50 /** 51 * Current row. 52 * 53 * @var array 54 */ 55 protected $_current; 56 57 /** 58 * Current offset. 59 * 60 * @var integer 61 */ 62 protected $_index; 63 64 /** 65 * Are we at the end of the result? 66 * 67 * @var boolean 68 */ 69 protected $_eof; 70 71 /** 72 * Which kind of keys to use for results. 73 */ 74 protected $_fetchMode = Horde_Db::FETCH_ASSOC; 75 76 /** 77 * Constructor. 78 * 79 * @param Horde_Db_Adapter $adapter A driver instance. 80 * @param string $sql A SQL query. 81 * @param mixed $arg1 Either an array of bound parameters or 82 * a query name. 83 * @param string $arg2 If $arg1 contains bound parameters, 84 * the query name. 85 */ 86 public function __construct($adapter, $sql, $arg1 = null, $arg2 = null) 87 { 88 $this->_adapter = $adapter; 89 $this->_sql = $sql; 90 $this->_arg1 = $arg1; 91 $this->_arg2 = $arg2; 92 } 93 94 /** 95 * Destructor. 96 */ 97 public function __destruct() 98 { 99 if ($this->_result) { 100 unset($this->_result); 101 } 102 } 103 104 /** 105 * Implementation of the rewind() method for iterator. 106 */ 107 public function rewind() 108 { 109 if ($this->_result) { 110 unset($this->_result); 111 } 112 $this->_current = null; 113 $this->_index = null; 114 $this->_eof = true; 115 $this->_result = $this->_adapter->execute( 116 $this->_sql, $this->_arg1, $this->_arg2 117 ); 118 119 $this->next(); 120 } 121 122 /** 123 * Implementation of the current() method for Iterator. 124 * 125 * @return array The current row, or null if no rows. 126 */ 127 public function current() 128 { 129 if (is_null($this->_result)) { 130 $this->rewind(); 131 } 132 return $this->_current; 133 } 134 135 /** 136 * Implementation of the key() method for Iterator. 137 * 138 * @return mixed The current row number (starts at 0), or null if no rows. 139 */ 140 public function key() 141 { 142 if (is_null($this->_result)) { 143 $this->rewind(); 144 } 145 return $this->_index; 146 } 147 148 /** 149 * Implementation of the next() method for Iterator. 150 * 151 * @return array|null The next row in the resultset or null if there are 152 * no more results. 153 */ 154 public function next() 155 { 156 if (is_null($this->_result)) { 157 $this->rewind(); 158 } 159 160 if ($this->_result) { 161 $row = $this->_fetchArray(); 162 if (!$row) { 163 $this->_eof = true; 164 } else { 165 $this->_eof = false; 166 167 if (is_null($this->_index)) { 168 $this->_index = 0; 169 } else { 170 ++$this->_index; 171 } 172 173 $this->_current = $row; 174 } 175 } 176 177 return $this->_current; 178 } 179 180 /** 181 * Implementation of the valid() method for Iterator. 182 * 183 * @return boolean Whether the iteration is valid. 184 */ 185 public function valid() 186 { 187 if (is_null($this->_result)) { 188 $this->rewind(); 189 } 190 return !$this->_eof; 191 } 192 193 /** 194 * Returns the current row and advances the recordset one row. 195 * 196 * @param integer $fetchmode The default fetch mode for this result. One 197 * of the Horde_Db::FETCH_* constants. 198 */ 199 public function fetch($fetchmode = Horde_Db::FETCH_ASSOC) 200 { 201 if (!$this->valid()) { 202 return null; 203 } 204 $this->setFetchMode($fetchmode); 205 $row = $this->current(); 206 $this->next(); 207 return $row; 208 } 209 210 /** 211 * Sets the default fetch mode for this result. 212 * 213 * @param integer $fetchmode One of the Horde_Db::FETCH_* constants. 214 */ 215 public function setFetchMode($fetchmode) 216 { 217 $this->_fetchMode = $fetchmode; 218 } 219 220 /** 221 * Returns the number of columns in the result set. 222 * 223 * @return integer Number of columns. 224 */ 225 public function columnCount() 226 { 227 if (is_null($this->_result)) { 228 $this->rewind(); 229 } 230 return $this->_columnCount(); 231 } 232 233 /** 234 * Returns a row from a resultset. 235 * 236 * @return array|boolean The next row in the resultset or false if there 237 * are no more results. 238 */ 239 abstract protected function _fetchArray(); 240 241 /** 242 * Returns the number of columns in the result set. 243 * 244 * @return integer Number of columns. 245 */ 246 abstract protected function _columnCount(); 247} 248