style: normalize end of files
[lhc/web/wiklou.git] / includes / db / DatabaseUtility.php
1 <?php
2 /**
3 * This file contains database-related utiliy 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 return $this->currentRow;
191 }
192
193 /**
194 * @return int
195 */
196 function key() {
197 return $this->pos;
198 }
199
200 /**
201 * @return int
202 */
203 function next() {
204 $this->pos++;
205 $this->currentRow = $this->fetchObject();
206 return $this->currentRow;
207 }
208
209 /**
210 * @return bool
211 */
212 function valid() {
213 return $this->current() !== false;
214 }
215 }
216
217 /**
218 * Overloads the relevant methods of the real ResultsWrapper so it
219 * doesn't go anywhere near an actual database.
220 */
221 class FakeResultWrapper extends ResultWrapper {
222 var $result = array();
223 var $db = null; // And it's going to stay that way :D
224 var $pos = 0;
225 var $currentRow = null;
226
227 function __construct( $array ) {
228 $this->result = $array;
229 }
230
231 /**
232 * @return int
233 */
234 function numRows() {
235 return count( $this->result );
236 }
237
238 function fetchRow() {
239 if ( $this->pos < count( $this->result ) ) {
240 $this->currentRow = $this->result[$this->pos];
241 } else {
242 $this->currentRow = false;
243 }
244 $this->pos++;
245 if ( is_object( $this->currentRow ) ) {
246 return get_object_vars( $this->currentRow );
247 } else {
248 return $this->currentRow;
249 }
250 }
251
252 function seek( $row ) {
253 $this->pos = $row;
254 }
255
256 function free() {}
257
258 // Callers want to be able to access fields with $this->fieldName
259 function fetchObject() {
260 $this->fetchRow();
261 if ( $this->currentRow ) {
262 return (object)$this->currentRow;
263 } else {
264 return false;
265 }
266 }
267
268 function rewind() {
269 $this->pos = 0;
270 $this->currentRow = null;
271 }
272
273 function next() {
274 return $this->fetchObject();
275 }
276 }
277
278 /**
279 * Used by DatabaseBase::buildLike() to represent characters that have special meaning in SQL LIKE clauses
280 * and thus need no escaping. Don't instantiate it manually, use DatabaseBase::anyChar() and anyString() instead.
281 */
282 class LikeMatch {
283 private $str;
284
285 /**
286 * Store a string into a LikeMatch marker object.
287 *
288 * @param String $s
289 */
290 public function __construct( $s ) {
291 $this->str = $s;
292 }
293
294 /**
295 * Return the original stored string.
296 *
297 * @return String
298 */
299 public function toString() {
300 return $this->str;
301 }
302 }
303
304 /**
305 * An object representing a master or slave position in a replicated setup.
306 */
307 interface DBMasterPos {
308 }