Break long lines and formatting updates for includes/db/
[lhc/web/wiklou.git] / includes / db / DatabaseUtility.php
1 <?php
2 /**
3 * This file contains database-related utility classes.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Database
22 */
23
24 /**
25 * Utility class.
26 * @ingroup Database
27 */
28 class DBObject {
29 public $mData;
30
31 function __construct( $data ) {
32 $this->mData = $data;
33 }
34
35 /**
36 * @return bool
37 */
38 function isLOB() {
39 return false;
40 }
41
42 function data() {
43 return $this->mData;
44 }
45 }
46
47 /**
48 * Utility class
49 * @ingroup Database
50 *
51 * This allows us to distinguish a blob from a normal string and an array of strings
52 */
53 class Blob {
54 private $mData;
55
56 function __construct( $data ) {
57 $this->mData = $data;
58 }
59
60 function fetch() {
61 return $this->mData;
62 }
63 }
64
65 /**
66 * Base for all database-specific classes representing information about database fields
67 * @ingroup Database
68 */
69 interface Field {
70 /**
71 * Field name
72 * @return string
73 */
74 function name();
75
76 /**
77 * Name of table this field belongs to
78 * @return string
79 */
80 function tableName();
81
82 /**
83 * Database type
84 * @return string
85 */
86 function type();
87
88 /**
89 * Whether this field can store NULL values
90 * @return bool
91 */
92 function isNullable();
93 }
94
95 /**
96 * Result wrapper for grabbing data queried by someone else
97 * @ingroup Database
98 */
99 class ResultWrapper implements Iterator {
100 var $db, $result, $pos = 0, $currentRow = null;
101
102 /**
103 * Create a new result object from a result resource and a Database object
104 *
105 * @param DatabaseBase $database
106 * @param resource $result
107 */
108 function __construct( $database, $result ) {
109 $this->db = $database;
110
111 if ( $result instanceof ResultWrapper ) {
112 $this->result = $result->result;
113 } else {
114 $this->result = $result;
115 }
116 }
117
118 /**
119 * Get the number of rows in a result object
120 *
121 * @return integer
122 */
123 function numRows() {
124 return $this->db->numRows( $this );
125 }
126
127 /**
128 * Fetch the next row from the given result object, in object form.
129 * Fields can be retrieved with $row->fieldname, with fields acting like
130 * member variables.
131 *
132 * @return object
133 * @throws DBUnexpectedError Thrown if the database returns an error
134 */
135 function fetchObject() {
136 return $this->db->fetchObject( $this );
137 }
138
139 /**
140 * Fetch the next row from the given result object, in associative array
141 * form. Fields are retrieved with $row['fieldname'].
142 *
143 * @return Array
144 * @throws DBUnexpectedError Thrown if the database returns an error
145 */
146 function fetchRow() {
147 return $this->db->fetchRow( $this );
148 }
149
150 /**
151 * Free a result object
152 */
153 function free() {
154 $this->db->freeResult( $this );
155 unset( $this->result );
156 unset( $this->db );
157 }
158
159 /**
160 * Change the position of the cursor in a result object.
161 * See mysql_data_seek()
162 *
163 * @param $row integer
164 */
165 function seek( $row ) {
166 $this->db->dataSeek( $this, $row );
167 }
168
169 /*********************
170 * Iterator functions
171 * Note that using these in combination with the non-iterator functions
172 * above may cause rows to be skipped or repeated.
173 */
174
175 function rewind() {
176 if ( $this->numRows() ) {
177 $this->db->dataSeek( $this, 0 );
178 }
179 $this->pos = 0;
180 $this->currentRow = null;
181 }
182
183 /**
184 * @return int
185 */
186 function current() {
187 if ( is_null( $this->currentRow ) ) {
188 $this->next();
189 }
190
191 return $this->currentRow;
192 }
193
194 /**
195 * @return int
196 */
197 function key() {
198 return $this->pos;
199 }
200
201 /**
202 * @return int
203 */
204 function next() {
205 $this->pos++;
206 $this->currentRow = $this->fetchObject();
207
208 return $this->currentRow;
209 }
210
211 /**
212 * @return bool
213 */
214 function valid() {
215 return $this->current() !== false;
216 }
217 }
218
219 /**
220 * Overloads the relevant methods of the real ResultsWrapper so it
221 * doesn't go anywhere near an actual database.
222 */
223 class FakeResultWrapper extends ResultWrapper {
224 var $result = array();
225 var $db = null; // And it's going to stay that way :D
226 var $pos = 0;
227 var $currentRow = null;
228
229 function __construct( $array ) {
230 $this->result = $array;
231 }
232
233 /**
234 * @return int
235 */
236 function numRows() {
237 return count( $this->result );
238 }
239
240 function fetchRow() {
241 if ( $this->pos < count( $this->result ) ) {
242 $this->currentRow = $this->result[$this->pos];
243 } else {
244 $this->currentRow = false;
245 }
246 $this->pos++;
247 if ( is_object( $this->currentRow ) ) {
248 return get_object_vars( $this->currentRow );
249 } else {
250 return $this->currentRow;
251 }
252 }
253
254 function seek( $row ) {
255 $this->pos = $row;
256 }
257
258 function free() {
259 }
260
261 // Callers want to be able to access fields with $this->fieldName
262 function fetchObject() {
263 $this->fetchRow();
264 if ( $this->currentRow ) {
265 return (object)$this->currentRow;
266 } else {
267 return false;
268 }
269 }
270
271 function rewind() {
272 $this->pos = 0;
273 $this->currentRow = null;
274 }
275
276 function next() {
277 return $this->fetchObject();
278 }
279 }
280
281 /**
282 * Used by DatabaseBase::buildLike() to represent characters that have special
283 * meaning in SQL LIKE clauses and thus need no escaping. Don't instantiate it
284 * manually, use DatabaseBase::anyChar() and anyString() instead.
285 */
286 class LikeMatch {
287 private $str;
288
289 /**
290 * Store a string into a LikeMatch marker object.
291 *
292 * @param string $s
293 */
294 public function __construct( $s ) {
295 $this->str = $s;
296 }
297
298 /**
299 * Return the original stored string.
300 *
301 * @return String
302 */
303 public function toString() {
304 return $this->str;
305 }
306 }
307
308 /**
309 * An object representing a master or slave position in a replicated setup.
310 */
311 interface DBMasterPos {
312 }