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