Merge "DatabaseMssql: Don't duplicate body of makeList()"
[mediawiki.git] / includes / db / DatabaseUtility.php
blob4e5ed08cf832bb5205bc668e3de2d67df00127e5
1 <?php
2 /**
3 * This file contains database-related utility classes.
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.
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.
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
20 * @file
21 * @ingroup Database
24 /**
25 * Utility class.
26 * @ingroup Database
28 class DBObject {
29 public $mData;
31 function __construct( $data ) {
32 $this->mData = $data;
35 /**
36 * @return bool
38 function isLOB() {
39 return false;
42 function data() {
43 return $this->mData;
47 /**
48 * Utility class
49 * @ingroup Database
51 * This allows us to distinguish a blob from a normal string and an array of strings
53 class Blob {
54 /** @var string */
55 protected $mData;
57 function __construct( $data ) {
58 $this->mData = $data;
61 function fetch() {
62 return $this->mData;
66 /**
67 * Base for all database-specific classes representing information about database fields
68 * @ingroup Database
70 interface Field {
71 /**
72 * Field name
73 * @return string
75 function name();
77 /**
78 * Name of table this field belongs to
79 * @return string
81 function tableName();
83 /**
84 * Database type
85 * @return string
87 function type();
89 /**
90 * Whether this field can store NULL values
91 * @return bool
93 function isNullable();
96 /**
97 * Result wrapper for grabbing data queried by someone else
98 * @ingroup Database
100 class ResultWrapper implements Iterator {
101 /** @var resource */
102 public $result;
104 /** @var DatabaseBase */
105 protected $db;
107 /** @var int */
108 protected $pos = 0;
110 /** @var object|null */
111 protected $currentRow = null;
114 * Create a new result object from a result resource and a Database object
116 * @param DatabaseBase $database
117 * @param resource|ResultWrapper $result
119 function __construct( $database, $result ) {
120 $this->db = $database;
122 if ( $result instanceof ResultWrapper ) {
123 $this->result = $result->result;
124 } else {
125 $this->result = $result;
130 * Get the number of rows in a result object
132 * @return int
134 function numRows() {
135 return $this->db->numRows( $this );
139 * Fetch the next row from the given result object, in object form.
140 * Fields can be retrieved with $row->fieldname, with fields acting like
141 * member variables.
143 * @return stdClass
144 * @throws DBUnexpectedError Thrown if the database returns an error
146 function fetchObject() {
147 return $this->db->fetchObject( $this );
151 * Fetch the next row from the given result object, in associative array
152 * form. Fields are retrieved with $row['fieldname'].
154 * @return array
155 * @throws DBUnexpectedError Thrown if the database returns an error
157 function fetchRow() {
158 return $this->db->fetchRow( $this );
162 * Free a result object
164 function free() {
165 $this->db->freeResult( $this );
166 unset( $this->result );
167 unset( $this->db );
171 * Change the position of the cursor in a result object.
172 * See mysql_data_seek()
174 * @param int $row
176 function seek( $row ) {
177 $this->db->dataSeek( $this, $row );
181 * ======= Iterator functions =======
182 * Note that using these in combination with the non-iterator functions
183 * above may cause rows to be skipped or repeated.
186 function rewind() {
187 if ( $this->numRows() ) {
188 $this->db->dataSeek( $this, 0 );
190 $this->pos = 0;
191 $this->currentRow = null;
195 * @return stdClass|array|bool
197 function current() {
198 if ( is_null( $this->currentRow ) ) {
199 $this->next();
202 return $this->currentRow;
206 * @return int
208 function key() {
209 return $this->pos;
213 * @return stdClass
215 function next() {
216 $this->pos++;
217 $this->currentRow = $this->fetchObject();
219 return $this->currentRow;
223 * @return bool
225 function valid() {
226 return $this->current() !== false;
231 * Overloads the relevant methods of the real ResultsWrapper so it
232 * doesn't go anywhere near an actual database.
234 class FakeResultWrapper extends ResultWrapper {
235 /** @var array */
236 public $result = array();
238 /** @var null And it's going to stay that way :D */
239 protected $db = null;
241 /** @var int */
242 protected $pos = 0;
244 /** @var array|stdClass|bool */
245 protected $currentRow = null;
247 function __construct( $array ) {
248 $this->result = $array;
252 * @return int
254 function numRows() {
255 return count( $this->result );
259 * @return array|bool
261 function fetchRow() {
262 if ( $this->pos < count( $this->result ) ) {
263 $this->currentRow = $this->result[$this->pos];
264 } else {
265 $this->currentRow = false;
267 $this->pos++;
268 if ( is_object( $this->currentRow ) ) {
269 return get_object_vars( $this->currentRow );
270 } else {
271 return $this->currentRow;
275 function seek( $row ) {
276 $this->pos = $row;
279 function free() {
283 * Callers want to be able to access fields with $this->fieldName
284 * @return bool|stdClass
286 function fetchObject() {
287 $this->fetchRow();
288 if ( $this->currentRow ) {
289 return (object)$this->currentRow;
290 } else {
291 return false;
295 function rewind() {
296 $this->pos = 0;
297 $this->currentRow = null;
301 * @return bool|stdClass
303 function next() {
304 return $this->fetchObject();
309 * Used by DatabaseBase::buildLike() to represent characters that have special
310 * meaning in SQL LIKE clauses and thus need no escaping. Don't instantiate it
311 * manually, use DatabaseBase::anyChar() and anyString() instead.
313 class LikeMatch {
314 /** @var string */
315 private $str;
318 * Store a string into a LikeMatch marker object.
320 * @param string $s
322 public function __construct( $s ) {
323 $this->str = $s;
327 * Return the original stored string.
329 * @return string
331 public function toString() {
332 return $this->str;
337 * An object representing a master or slave position in a replicated setup.
339 * The implementation details of this opaque type are up to the database subclass.
341 interface DBMasterPos {
343 * @return float UNIX timestamp
345 public function asOfTime();