Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | n/a |
0 / 0 |
n/a |
0 / 0 |
CRAP | n/a |
0 / 0 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | namespace Wikimedia\Rdbms; |
21 | |
22 | use Exception; |
23 | use Wikimedia\ScopedCallback; |
24 | |
25 | /** |
26 | * @defgroup Database Database |
27 | * This group deals with database interface functions |
28 | * and query specifics/optimisations. |
29 | */ |
30 | |
31 | // Very long type annotations :( |
32 | // phpcs:disable Generic.Files.LineLength |
33 | |
34 | /** |
35 | * Basic database interface for live and lazy-loaded relation database handles |
36 | * |
37 | * @ingroup Database |
38 | */ |
39 | interface IDatabase extends IReadableDatabase { |
40 | /** Callback triggered immediately due to no active transaction */ |
41 | public const TRIGGER_IDLE = 1; |
42 | /** Callback triggered by COMMIT */ |
43 | public const TRIGGER_COMMIT = 2; |
44 | /** Callback triggered by ROLLBACK */ |
45 | public const TRIGGER_ROLLBACK = 3; |
46 | /** Callback triggered by atomic section cancel (ROLLBACK TO SAVEPOINT) */ |
47 | public const TRIGGER_CANCEL = 4; |
48 | |
49 | /** Transaction is requested by regular caller outside of the DB layer */ |
50 | public const TRANSACTION_EXPLICIT = ''; |
51 | /** Transaction is requested internally via DBO_TRX/startAtomic() */ |
52 | public const TRANSACTION_INTERNAL = 'implicit'; |
53 | |
54 | /** Atomic section is not cancelable */ |
55 | public const ATOMIC_NOT_CANCELABLE = ''; |
56 | /** Atomic section is cancelable */ |
57 | public const ATOMIC_CANCELABLE = 'cancelable'; |
58 | |
59 | /** Commit/rollback is from outside the IDatabase handle and connection manager */ |
60 | public const FLUSHING_ONE = ''; |
61 | /** Commit/rollback is from the connection manager for the IDatabase handle */ |
62 | public const FLUSHING_ALL_PEERS = 'flush'; |
63 | /** Commit/rollback is from the IDatabase handle internally */ |
64 | public const FLUSHING_INTERNAL = 'flush-internal'; |
65 | |
66 | /** Estimate total time (RTT, scanning, waiting on locks, applying) */ |
67 | public const ESTIMATE_TOTAL = 'total'; |
68 | /** Estimate time to apply (scanning, applying) */ |
69 | public const ESTIMATE_DB_APPLY = 'apply'; |
70 | |
71 | /** Flag to return the lock acquisition timestamp (null if not acquired) */ |
72 | public const LOCK_TIMESTAMP = 1; |
73 | |
74 | /** Field for getLBInfo()/setLBInfo() */ |
75 | public const LB_TRX_ROUND_ID = 'trxRoundId'; |
76 | /** Field for getLBInfo()/setLBInfo() */ |
77 | public const LB_READ_ONLY_REASON = 'readOnlyReason'; |
78 | |
79 | /** Primary server than can stream writes to replica servers */ |
80 | public const ROLE_STREAMING_MASTER = 'streaming-master'; |
81 | /** Replica server that receives writes from a primary server */ |
82 | public const ROLE_STREAMING_REPLICA = 'streaming-replica'; |
83 | /** Replica server within a static dataset */ |
84 | public const ROLE_STATIC_CLONE = 'static-clone'; |
85 | /** Server with unknown topology role */ |
86 | public const ROLE_UNKNOWN = 'unknown'; |
87 | |
88 | /** |
89 | * Gets the current transaction level. |
90 | * |
91 | * Historically, transactions were allowed to be "nested". This is no |
92 | * longer supported, so this function really only returns a boolean. |
93 | * |
94 | * @return int The previous value |
95 | */ |
96 | public function trxLevel(); |
97 | |
98 | /** |
99 | * Get the UNIX timestamp of the time that the transaction was established |
100 | * |
101 | * This can be used to reason about the staleness of SELECT data in REPEATABLE-READ |
102 | * transaction isolation level. Callers can assume that if a view-snapshot isolation |
103 | * is used, then the data read by SQL queries is *at least* up to date to that point |
104 | * (possibly more up-to-date since the first SELECT defines the snapshot). |
105 | * |
106 | * @return float|null Returns null if there is not active transaction |
107 | * @since 1.25 |
108 | */ |
109 | public function trxTimestamp(); |
110 | |
111 | /** |
112 | * Check whether there is a transaction open at the specific request of a caller |
113 | * |
114 | * Explicit transactions are spawned by begin(), startAtomic(), and doAtomicSection(). |
115 | * Note that explicit transactions should not be confused with explicit transaction rounds. |
116 | * |
117 | * @return bool |
118 | * @since 1.28 |
119 | */ |
120 | public function explicitTrxActive(); |
121 | |
122 | /** |
123 | * Get properties passed down from the server info array of the load balancer |
124 | * |
125 | * @internal should not be called outside of rdbms library. |
126 | * |
127 | * @param string|null $name The entry of the info array to get, or null to get the whole array |
128 | * @return array|mixed|null |
129 | */ |
130 | public function getLBInfo( $name = null ); |
131 | |
132 | /** |
133 | * Get the sequence-based ID assigned by the last query method call |
134 | * |
135 | * This method should only be called when all the following hold true: |
136 | * - (a) A method call was made to insert(), upsert(), replace(), or insertSelect() |
137 | * - (b) The method call attempts to insert exactly one row |
138 | * - (c) The method call omits the value of exactly one auto-increment column |
139 | * - (d) The method call succeeded |
140 | * - (e) No subsequent method calls were made, with the exception of affectedRows(), |
141 | * lastErrno(), lastError(), and getType() |
142 | * |
143 | * In all other cases, the return value is unspecified. |
144 | * |
145 | * When the query method is either insert() with "IGNORE", upsert(), or insertSelect(), |
146 | * callers should first check affectedRows() before calling this method, making sure that |
147 | * the query method actually created a row. Otherwise, an ID from a previous insert might |
148 | * be incorrectly assumed to belong to last insert. |
149 | * |
150 | * @return int |
151 | */ |
152 | public function insertId(); |
153 | |
154 | /** |
155 | * Get the number of rows affected by the last query method call |
156 | * |
157 | * This method should only be called when all the following hold true: |
158 | * - (a) A method call was made to insert(), upsert(), replace(), update(), delete(), |
159 | * insertSelect(), query() with a non-SELECT statement, or queryMulti() with a |
160 | * non-SELECT terminal statement |
161 | * - (b) The method call succeeded |
162 | * - (c) No subsequent method calls were made, with the exception of affectedRows(), |
163 | * lastErrno(), lastError(), and getType() |
164 | * |
165 | * In all other cases, the return value is unspecified. |
166 | * |
167 | * UPDATE queries consider rows affected even when all their new column values match |
168 | * the previous values. Such rows can be excluded from the count by changing the WHERE |
169 | * clause to filter them out. |
170 | * |
171 | * If the last query method call was to query() or queryMulti(), then the results |
172 | * are based on the (last) statement provided to that call and are driver-specific. |
173 | * |
174 | * @return int |
175 | */ |
176 | public function affectedRows(); |
177 | |
178 | /** |
179 | * Run an SQL query statement and return the result |
180 | * |
181 | * If a connection loss is detected, then an attempt to reconnect will be made. |
182 | * For queries that involve no larger transactions or locks, they will be re-issued |
183 | * for convenience, provided the connection was re-established. |
184 | * |
185 | * In new code, the query wrappers select(), insert(), update(), delete(), |
186 | * etc. should be used where possible, since they give much better DBMS |
187 | * independence and automatically quote or validate user input in a variety |
188 | * of contexts. This function is generally only useful for queries which are |
189 | * explicitly DBMS-dependent and are unsupported by the query wrappers, such |
190 | * as CREATE TABLE. |
191 | * |
192 | * However, the query wrappers themselves should call this function. |
193 | * |
194 | * Callers should avoid the use of statements like BEGIN, COMMIT, and ROLLBACK. |
195 | * Methods like startAtomic(), endAtomic(), and cancelAtomic() can be used instead. |
196 | * |
197 | * @param string|Query $sql Single-statement SQL query |
198 | * @param-taint $sql exec_sql |
199 | * @param string $fname Caller name; used for profiling/SHOW PROCESSLIST comments |
200 | * @param int $flags Bit field of ISQLPlatform::QUERY_* constants |
201 | * @return bool|IResultWrapper True for a successful write query, IResultWrapper object |
202 | * for a successful read query, or false on failure if QUERY_SILENCE_ERRORS is set |
203 | * @return-taint tainted |
204 | * @throws DBQueryError If the query is issued, fails, and QUERY_SILENCE_ERRORS is not set |
205 | * @throws DBExpectedError If the query is not, and cannot, be issued yet (non-DBQueryError) |
206 | * @throws DBError If the query is inherently not allowed (non-DBExpectedError) |
207 | */ |
208 | public function query( $sql, $fname = __METHOD__, $flags = 0 ); |
209 | |
210 | /** |
211 | * Get an UpdateQueryBuilder bound to this connection. This is overridden by |
212 | * DBConnRef. |
213 | * |
214 | * @note A new query builder must be created per query. Query builders |
215 | * should not be reused since this uses a fluent interface and the state of |
216 | * the builder changes during the query which may cause unexpected results. |
217 | * |
218 | * @return UpdateQueryBuilder |
219 | */ |
220 | public function newUpdateQueryBuilder(): UpdateQueryBuilder; |
221 | |
222 | /** |
223 | * Get an DeleteQueryBuilder bound to this connection. This is overridden by |
224 | * DBConnRef. |
225 | * |
226 | * @note A new query builder must be created per query. Query builders |
227 | * should not be reused since this uses a fluent interface and the state of |
228 | * the builder changes during the query which may cause unexpected results. |
229 | * |
230 | * @return DeleteQueryBuilder |
231 | */ |
232 | public function newDeleteQueryBuilder(): DeleteQueryBuilder; |
233 | |
234 | /** |
235 | * Get an InsertQueryBuilder bound to this connection. This is overridden by |
236 | * DBConnRef. |
237 | * |
238 | * @note A new query builder must be created per query. Query builders |
239 | * should not be reused since this uses a fluent interface and the state of |
240 | * the builder changes during the query which may cause unexpected results. |
241 | * |
242 | * @return InsertQueryBuilder |
243 | */ |
244 | public function newInsertQueryBuilder(): InsertQueryBuilder; |
245 | |
246 | /** |
247 | * Get an ReplaceQueryBuilder bound to this connection. This is overridden by |
248 | * DBConnRef. |
249 | * |
250 | * @note A new query builder must be created per query. Query builders |
251 | * should not be reused since this uses a fluent interface and the state of |
252 | * the builder changes during the query which may cause unexpected results. |
253 | * |
254 | * @return ReplaceQueryBuilder |
255 | */ |
256 | public function newReplaceQueryBuilder(): ReplaceQueryBuilder; |
257 | |
258 | /** |
259 | * Lock all rows meeting the given conditions/options FOR UPDATE |
260 | * |
261 | * @param string|string[] $table The unqualified name of table(s) (use an array for a join) |
262 | * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds |
263 | * Condition in the format of IDatabase::select() conditions |
264 | * @param string $fname Function name for profiling |
265 | * @param array $options Options for select ("FOR UPDATE" is added automatically) |
266 | * @param array $join_conds Join conditions |
267 | * @return int Number of matching rows found (and locked) |
268 | * @throws DBError If an error occurs, {@see query} |
269 | * @since 1.32 |
270 | * @deprecated since 1.43; Use SelectQueryBuilder::acquireRowLocks |
271 | */ |
272 | public function lockForUpdate( |
273 | $table, $conds = '', $fname = __METHOD__, $options = [], $join_conds = [] |
274 | ); |
275 | |
276 | /** |
277 | * Insert row(s) into a table, in the provided order |
278 | * |
279 | * This operation will be seen by affectedRows()/insertId() as one query statement, |
280 | * regardless of how many statements are actually sent by the class implementation. |
281 | * |
282 | * @internal callers outside of rdbms library should use InsertQueryBuilder instead. |
283 | * |
284 | * @param string $table The unqualified name of a table |
285 | * @param array|array[] $rows Row(s) to insert, as either: |
286 | * - A string-keyed map of (column name => value) defining a new row. Values are |
287 | * treated as literals and quoted appropriately; null is interpreted as NULL. |
288 | * - An integer-keyed list of such string-keyed maps, defining a list of new rows. |
289 | * The keys in each map must be identical to each other and in the same order. |
290 | * The rows must not collide with each other. |
291 | * @param string $fname Calling function name (use __METHOD__) for logs/profiling |
292 | * @param string|array $options Combination map/list where each string-keyed entry maps |
293 | * a non-boolean option to the option parameters and each integer-keyed value is the |
294 | * name of a boolean option. Supported options are: |
295 | * - IGNORE: Boolean: skip insertion of rows that would cause unique key conflicts. |
296 | * IDatabase::affectedRows() can be used to determine how many rows were inserted. |
297 | * @return bool Return true if no exception was thrown (deprecated since 1.33) |
298 | * @throws DBError If an error occurs, {@see query} |
299 | */ |
300 | public function insert( $table, $rows, $fname = __METHOD__, $options = [] ); |
301 | |
302 | /** |
303 | * Update all rows in a table that match a given condition |
304 | * |
305 | * This operation will be seen by affectedRows()/insertId() as one query statement, |
306 | * regardless of how many statements are actually sent by the class implementation. |
307 | * |
308 | * @internal callers outside of rdbms library should use UpdateQueryBuilder instead. |
309 | * |
310 | * @param string $table The unqualified name of a table |
311 | * @param-taint $table exec_sql |
312 | * @param array<string,?scalar|RawSQLValue>|array<int,string> $set |
313 | * Combination map/list where each string-keyed entry maps a column |
314 | * to a literal assigned value and each integer-keyed value is a SQL expression in the |
315 | * format of a column assignment within UPDATE...SET. The (column => value) entries are |
316 | * convenient due to automatic value quoting and conversion of null to NULL. The SQL |
317 | * assignment format is useful for updates like "column = column + X". All assignments |
318 | * have no defined execution order, so they should not depend on each other. Do not |
319 | * modify AUTOINCREMENT or UUID columns in assignments. |
320 | * @param-taint $set exec_sql_numkey |
321 | * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds |
322 | * Condition in the format of IDatabase::select() conditions. |
323 | * In order to prevent possible performance or replication issues or damaging a data |
324 | * accidentally, an empty condition for 'update' queries isn't allowed. |
325 | * IDatabase::ALL_ROWS should be passed explicitly in order to update all rows. |
326 | * @param-taint $conds exec_sql_numkey |
327 | * @param string $fname Calling function name (use __METHOD__) for logs/profiling |
328 | * @param-taint $fname exec_sql |
329 | * @param string|array $options Combination map/list where each string-keyed entry maps |
330 | * a non-boolean option to the option parameters and each integer-keyed value is the |
331 | * name of a boolean option. Supported options are: |
332 | * - IGNORE: Boolean: skip update of rows that would cause unique key conflicts. |
333 | * IDatabase::affectedRows() includes all matching rows, |
334 | * that includes also rows not updated due to key conflict. |
335 | * @param-taint $options none |
336 | * @return bool Return true if no exception was thrown (deprecated since 1.33) |
337 | * @return-taint none |
338 | * @throws DBError If an error occurs, {@see query} |
339 | */ |
340 | public function update( $table, $set, $conds, $fname = __METHOD__, $options = [] ); |
341 | |
342 | /** |
343 | * Insert row(s) into a table, in the provided order, while deleting conflicting rows |
344 | * |
345 | * Conflicts are determined by the provided unique indexes. Note that it is possible |
346 | * for the provided rows to conflict even among themselves; it is preferable for the |
347 | * caller to de-duplicate such input beforehand. |
348 | * |
349 | * Note some important implications of the deletion semantics: |
350 | * - If the table has an AUTOINCREMENT column and $rows omit that column, then any |
351 | * conflicting existing rows will be replaced with newer having higher values for |
352 | * that column, even if nothing else changed. |
353 | * - There might be worse contention than upsert() due to the use of gap-locking. |
354 | * This does not apply to RDBMS types that use predicate locking nor those that |
355 | * just lock the whole table or databases anyway. |
356 | * |
357 | * This operation will be seen by affectedRows()/insertId() as one query statement, |
358 | * regardless of how many statements are actually sent by the class implementation. |
359 | * |
360 | * @internal callers outside of rdbms library should use ReplaceQueryBuilder instead. |
361 | * |
362 | * @param string $table The unqualified name of a table |
363 | * @param string|string[]|string[][] $uniqueKeys Column name or non-empty list of column |
364 | * name lists that define all applicable unique keys on the table. There must only be |
365 | * one such key. Each unique key on the table is "applicable" unless either: |
366 | * - It involves an AUTOINCREMENT column for which no values are assigned in $rows |
367 | * - It involves a UUID column for which newly generated UUIDs are assigned in $rows |
368 | * @param array|array[] $rows Row(s) to insert, in the form of either: |
369 | * - A string-keyed map of (column name => value) defining a new row. Values are |
370 | * treated as literals and quoted appropriately; null is interpreted as NULL. |
371 | * Columns belonging to a key in $uniqueKeys must be defined here and non-null. |
372 | * - An integer-keyed list of such string-keyed maps, defining a list of new rows. |
373 | * The keys in each map must be identical to each other and in the same order. |
374 | * The rows must not collide with each other. |
375 | * @param string $fname Calling function name (use __METHOD__) for logs/profiling |
376 | * @throws DBError If an error occurs, {@see query} |
377 | */ |
378 | public function replace( $table, $uniqueKeys, $rows, $fname = __METHOD__ ); |
379 | |
380 | /** |
381 | * Upsert row(s) into a table, in the provided order, while updating conflicting rows |
382 | * |
383 | * Conflicts are determined by the provided unique indexes. Note that it is possible |
384 | * for the provided rows to conflict even among themselves; it is preferable for the |
385 | * caller to de-duplicate such input beforehand. |
386 | * |
387 | * This operation will be seen by affectedRows()/insertId() as one query statement, |
388 | * regardless of how many statements are actually sent by the class implementation. |
389 | * |
390 | * @internal callers outside of rdbms library should use InsertQueryBuilder instead. |
391 | * |
392 | * @param string $table The unqualified name of a table |
393 | * @param array|array[] $rows Row(s) to insert, in the form of either: |
394 | * - A string-keyed map of (column name => value) defining a new row. Values are |
395 | * treated as literals and quoted appropriately; null is interpreted as NULL. |
396 | * Columns belonging to a key in $uniqueKeys must be defined here and non-null. |
397 | * - An integer-keyed list of such string-keyed maps, defining a list of new rows. |
398 | * The keys in each map must be identical to each other and in the same order. |
399 | * The rows must not collide with each other. |
400 | * @param string|string[]|string[][] $uniqueKeys Column name or non-empty list of column |
401 | * name lists that define all applicable unique keys on the table. There must only be |
402 | * one such key. Each unique key on the table is "applicable" unless either: |
403 | * - It involves an AUTOINCREMENT column for which no values are assigned in $rows |
404 | * - It involves a UUID column for which newly generated UUIDs are assigned in $rows |
405 | * @param array<string,?scalar|RawSQLValue>|array<int,string> $set |
406 | * Combination map/list where each string-keyed entry maps a column |
407 | * to a literal assigned value and each integer-keyed value is a SQL assignment expression |
408 | * of the form "<unquoted alphanumeric column> = <SQL expression>". The (column => value) |
409 | * entries are convenient due to automatic value quoting and conversion of null to NULL. |
410 | * The SQL assignment entries are useful for updates like "column = column + X". All of |
411 | * the assignments have no defined execution order, so callers should make sure that they |
412 | * not depend on each other. Do not modify AUTOINCREMENT or UUID columns in assignments, |
413 | * even if they are just "secondary" unique keys. For multi-row upserts, use |
414 | * buildExcludedValue() to reference the value of a column from the corresponding row |
415 | * in $rows that conflicts with the current row. |
416 | * @param string $fname Calling function name (use __METHOD__) for logs/profiling |
417 | * @throws DBError If an error occurs, {@see query} |
418 | * @since 1.22 |
419 | */ |
420 | public function upsert( |
421 | $table, array $rows, $uniqueKeys, array $set, $fname = __METHOD__ |
422 | ); |
423 | |
424 | /** |
425 | * Delete all rows in a table that match a condition which includes a join |
426 | * |
427 | * For safety, an empty $conds will not delete everything. If you want to |
428 | * delete all rows where the join condition matches, set $conds=IDatabase::ALL_ROWS. |
429 | * |
430 | * DO NOT put the join condition in $conds. |
431 | * |
432 | * This operation will be seen by affectedRows()/insertId() as one query statement, |
433 | * regardless of how many statements are actually sent by the class implementation. |
434 | * |
435 | * @param string $delTable The unqualified name of the table to delete rows from. |
436 | * @param string $joinTable The unqualified name of the reference table to join on. |
437 | * @param string $delVar The variable to join on, in the first table. |
438 | * @param string $joinVar The variable to join on, in the second table. |
439 | * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds |
440 | * Condition array of field names mapped to variables, |
441 | * ANDed together in the WHERE clause |
442 | * @param string $fname Calling function name (use __METHOD__) for logs/profiling |
443 | * @throws DBError If an error occurs, {@see query} |
444 | */ |
445 | public function deleteJoin( |
446 | $delTable, |
447 | $joinTable, |
448 | $delVar, |
449 | $joinVar, |
450 | $conds, |
451 | $fname = __METHOD__ |
452 | ); |
453 | |
454 | /** |
455 | * Delete all rows in a table that match a condition |
456 | * |
457 | * This operation will be seen by affectedRows()/insertId() as one query statement, |
458 | * regardless of how many statements are actually sent by the class implementation. |
459 | * |
460 | * @internal callers outside of rdbms library should use DeleteQueryBuilder instead. |
461 | * |
462 | * @param string $table The unqualified name of a table |
463 | * @param-taint $table exec_sql |
464 | * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds |
465 | * Array of conditions. See $conds in IDatabase::select() |
466 | * In order to prevent possible performance or replication issues or damaging a data |
467 | * accidentally, an empty condition for 'delete' queries isn't allowed. |
468 | * IDatabase::ALL_ROWS should be passed explicitly in order to delete all rows. |
469 | * @param-taint $conds exec_sql_numkey |
470 | * @param string $fname Name of the calling function |
471 | * @param-taint $fname exec_sql |
472 | * @return bool Return true if no exception was thrown (deprecated since 1.33) |
473 | * @return-taint none |
474 | * @throws DBError If an error occurs, {@see query} |
475 | */ |
476 | public function delete( $table, $conds, $fname = __METHOD__ ); |
477 | |
478 | /** |
479 | * INSERT SELECT wrapper |
480 | * |
481 | * @warning If the insert will use an auto-increment or sequence to |
482 | * determine the value of a column, this may break replication on |
483 | * databases using statement-based replication if the SELECT is not |
484 | * deterministically ordered. |
485 | * |
486 | * This operation will be seen by affectedRows()/insertId() as one query statement, |
487 | * regardless of how many statements are actually sent by the class implementation. |
488 | * |
489 | * @param string $destTable Unqualified name of destination table |
490 | * @param string|array $srcTable Unqualified name of source table(s) (use an array for a join) |
491 | * @param array $varMap Must be an associative array of the form |
492 | * [ 'dest1' => 'source1', ... ]. Source items may be literals |
493 | * rather than field names, but strings should be quoted with |
494 | * IDatabase::addQuotes() |
495 | * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds |
496 | * Condition array. See $conds in IDatabase::select() for |
497 | * the details of the format of condition arrays. May be "*" to copy the |
498 | * whole table. |
499 | * @param string $fname The function name of the caller, from __METHOD__ |
500 | * @param array $insertOptions Options for the INSERT part of the query, see |
501 | * IDatabase::insert() for details. Also, one additional option is |
502 | * available: pass 'NO_AUTO_COLUMNS' to hint that the query does not use |
503 | * an auto-increment or sequence to determine any column values. |
504 | * @param array $selectOptions Options for the SELECT part of the query, see |
505 | * IDatabase::select() for details. |
506 | * @param array $selectJoinConds Join conditions for the SELECT part of the query, see |
507 | * IDatabase::select() for details. |
508 | * @return bool Return true if no exception was thrown (deprecated since 1.33) |
509 | * @throws DBError If an error occurs, {@see query} |
510 | */ |
511 | public function insertSelect( |
512 | $destTable, |
513 | $srcTable, |
514 | $varMap, |
515 | $conds, |
516 | $fname = __METHOD__, |
517 | $insertOptions = [], |
518 | $selectOptions = [], |
519 | $selectJoinConds = [] |
520 | ); |
521 | |
522 | /** |
523 | * Run a callback when the current transaction commits or rolls back |
524 | * |
525 | * An error is thrown if no transaction is pending. |
526 | * |
527 | * When transaction round mode (DBO_TRX) is set, the callback will run at the end |
528 | * of the round, just after all peer transactions COMMIT/ROLLBACK. |
529 | * |
530 | * This IDatabase instance will start off in auto-commit mode when the callback starts. |
531 | * The use of other IDatabase handles from the callback should be avoided unless they are |
532 | * known to be in auto-commit mode. Callbacks that create transactions via begin() or |
533 | * startAtomic() must have matching calls to commit()/endAtomic(). |
534 | * |
535 | * Use this method only for the following purposes: |
536 | * - (a) Release of cooperative locks on resources |
537 | * - (b) Cancellation of in-process deferred tasks |
538 | * |
539 | * The callback takes the following arguments: |
540 | * - How the current atomic section (if any) or overall transaction (otherwise) ended |
541 | * (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_ROLLBACK) |
542 | * - This IDatabase instance (since 1.32) |
543 | * |
544 | * Callbacks will execute in the order they were enqueued. |
545 | * |
546 | * @note Use onAtomicSectionCancel() to take action as soon as an atomic section is cancelled |
547 | * |
548 | * @param callable $callback |
549 | * @param string $fname Caller name |
550 | * @throws DBError If an error occurs, {@see query} |
551 | * @throws Exception If the callback runs immediately and an error occurs in it |
552 | * @since 1.28 |
553 | */ |
554 | public function onTransactionResolution( callable $callback, $fname = __METHOD__ ); |
555 | |
556 | /** |
557 | * Run a callback when the current transaction commits or now if there is none |
558 | * |
559 | * If there is a transaction and it is rolled back, then the callback is cancelled. |
560 | * |
561 | * When transaction round mode (DBO_TRX) is set, the callback will run at the end |
562 | * of the round, just after all peer transactions COMMIT. If the transaction round |
563 | * is rolled back, then the callback is cancelled. |
564 | * |
565 | * This IDatabase instance will start off in auto-commit mode when the callback starts. |
566 | * The use of other IDatabase handles from the callback should be avoided unless they are |
567 | * known to be in auto-commit mode. Callbacks that create transactions via begin() or |
568 | * startAtomic() must have matching calls to commit()/endAtomic(). |
569 | * |
570 | * Use this method only for the following purposes: |
571 | * - (a) RDBMS updates, prone to lock timeouts/deadlocks, that do not require |
572 | * atomicity with respect to the updates in the current transaction (if any) |
573 | * - (b) Purges to lightweight cache services due to RDBMS updates |
574 | * - (c) Updates to secondary DBs/stores that must only commit once the updates in |
575 | * the current transaction (if any) are committed (e.g. insert user account row |
576 | * to DB1, then, initialize corresponding LDAP account) |
577 | * |
578 | * The callback takes the following arguments: |
579 | * - How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_IDLE) |
580 | * - This IDatabase instance (since 1.32) |
581 | * |
582 | * Callbacks will execute in the order they were enqueued. |
583 | * |
584 | * @param callable $callback |
585 | * @param string $fname Caller name |
586 | * @throws DBError If an error occurs, {@see query} |
587 | * @throws Exception If the callback runs immediately and an error occurs in it |
588 | * @since 1.32 |
589 | */ |
590 | public function onTransactionCommitOrIdle( callable $callback, $fname = __METHOD__ ); |
591 | |
592 | /** |
593 | * Run a callback before the current transaction commits or now if there is none |
594 | * |
595 | * If there is a transaction and it is rolled back, then the callback is cancelled. |
596 | * |
597 | * When transaction round mode (DBO_TRX) is set, the callback will run at the end |
598 | * of the round, just after all peer transactions COMMIT. If the transaction round |
599 | * is rolled back, then the callback is cancelled. |
600 | * |
601 | * If there is no current transaction, one will be created to wrap the callback. |
602 | * Callbacks cannot use begin()/commit() to manage transactions. The use of other |
603 | * IDatabase handles from the callback should be avoided. |
604 | * |
605 | * Use this method only for the following purposes: |
606 | * - a) RDBMS updates, prone to lock timeouts/deadlocks, that require atomicity |
607 | * with respect to the updates in the current transaction (if any) |
608 | * - b) Purges to lightweight cache services due to RDBMS updates |
609 | * |
610 | * The callback takes the one argument: |
611 | * - This IDatabase instance (since 1.32) |
612 | * |
613 | * Callbacks will execute in the order they were enqueued. |
614 | * |
615 | * @param callable $callback |
616 | * @param string $fname Caller name |
617 | * @throws DBError If an error occurs, {@see query} |
618 | * @throws Exception If the callback runs immediately and an error occurs in it |
619 | * @since 1.22 |
620 | */ |
621 | public function onTransactionPreCommitOrIdle( callable $callback, $fname = __METHOD__ ); |
622 | |
623 | /** |
624 | * Run a callback when the atomic section is cancelled |
625 | * |
626 | * The callback is run just after the current atomic section, any outer |
627 | * atomic section, or the whole transaction is rolled back. |
628 | * |
629 | * An error is thrown if no atomic section is pending. The atomic section |
630 | * need not have been created with the ATOMIC_CANCELABLE flag. |
631 | * |
632 | * Queries in the function may be running in the context of an outer |
633 | * transaction or may be running in AUTOCOMMIT mode. The callback should |
634 | * use atomic sections if necessary. |
635 | * |
636 | * @note do not assume that *other* IDatabase instances will be AUTOCOMMIT mode |
637 | * |
638 | * The callback takes the following arguments: |
639 | * - IDatabase::TRIGGER_CANCEL or IDatabase::TRIGGER_ROLLBACK |
640 | * - This IDatabase instance |
641 | * |
642 | * @param callable $callback |
643 | * @param string $fname Caller name |
644 | * @since 1.34 |
645 | */ |
646 | public function onAtomicSectionCancel( callable $callback, $fname = __METHOD__ ); |
647 | |
648 | /** |
649 | * Begin an atomic section of SQL statements |
650 | * |
651 | * Start an implicit transaction if no transaction is already active, set a savepoint |
652 | * (if $cancelable is ATOMIC_CANCELABLE), and track the given section name to enforce |
653 | * that the transaction is not committed prematurely. The end of the section must be |
654 | * signified exactly once, either by endAtomic() or cancelAtomic(). Sections can have |
655 | * have layers of inner sections (sub-sections), but all sections must be ended in order |
656 | * of innermost to outermost. Transactions cannot be started or committed until all |
657 | * atomic sections are closed. |
658 | * |
659 | * ATOMIC_CANCELABLE is useful when the caller needs to handle specific failure cases |
660 | * by discarding the section's writes. This should not be used for failures when: |
661 | * - upsert() could easily be used instead |
662 | * - insert() with IGNORE could easily be used instead |
663 | * - select() with FOR UPDATE could be checked before issuing writes instead |
664 | * - The failure is from code that runs after the first write but doesn't need to |
665 | * - The failures are from contention solvable via onTransactionPreCommitOrIdle() |
666 | * - The failures are deadlocks; the RDBMs usually discard the whole transaction |
667 | * |
668 | * @note callers must use additional measures for situations involving two or more |
669 | * (peer) transactions (e.g. updating two database servers at once). The transaction |
670 | * and savepoint logic of this method only applies to this specific IDatabase instance. |
671 | * |
672 | * Example usage: |
673 | * @code |
674 | * // Start a transaction if there isn't one already |
675 | * $dbw->startAtomic( __METHOD__ ); |
676 | * // Serialize these thread table updates |
677 | * $dbw->select( 'thread', '1', [ 'td_id' => $tid ], __METHOD__, 'FOR UPDATE' ); |
678 | * // Add a new comment for the thread |
679 | * $dbw->insert( 'comment', $row, __METHOD__ ); |
680 | * $cid = $db->insertId(); |
681 | * // Update thread reference to last comment |
682 | * $dbw->update( 'thread', [ 'td_latest' => $cid ], [ 'td_id' => $tid ], __METHOD__ ); |
683 | * // Demark the end of this conceptual unit of updates |
684 | * $dbw->endAtomic( __METHOD__ ); |
685 | * @endcode |
686 | * |
687 | * Example usage (atomic changes that might have to be discarded): |
688 | * @code |
689 | * // Start a transaction if there isn't one already |
690 | * $sectionId = $dbw->startAtomic( __METHOD__, $dbw::ATOMIC_CANCELABLE ); |
691 | * // Create new record metadata row |
692 | * $dbw->insert( 'records', $row, __METHOD__ ); |
693 | * // Figure out where to store the data based on the new row's ID |
694 | * $path = $recordDirectory . '/' . $dbw->insertId(); |
695 | * // Write the record data to the storage system |
696 | * $status = $fileBackend->create( [ 'dst' => $path, 'content' => $data ] ); |
697 | * if ( $status->isOK() ) { |
698 | * // Try to cleanup files orphaned by transaction rollback |
699 | * $dbw->onTransactionResolution( |
700 | * function ( $type ) use ( $fileBackend, $path ) { |
701 | * if ( $type === IDatabase::TRIGGER_ROLLBACK ) { |
702 | * $fileBackend->delete( [ 'src' => $path ] ); |
703 | * } |
704 | * }, |
705 | * __METHOD__ |
706 | * ); |
707 | * // Demark the end of this conceptual unit of updates |
708 | * $dbw->endAtomic( __METHOD__ ); |
709 | * } else { |
710 | * // Discard these writes from the transaction (preserving prior writes) |
711 | * $dbw->cancelAtomic( __METHOD__, $sectionId ); |
712 | * } |
713 | * @endcode |
714 | * |
715 | * @since 1.23 |
716 | * @param string $fname |
717 | * @param string $cancelable Pass self::ATOMIC_CANCELABLE to use a |
718 | * savepoint and enable self::cancelAtomic() for this section. |
719 | * @return AtomicSectionIdentifier section ID token |
720 | * @throws DBError If an error occurs, {@see query} |
721 | */ |
722 | public function startAtomic( $fname = __METHOD__, $cancelable = self::ATOMIC_NOT_CANCELABLE ); |
723 | |
724 | /** |
725 | * Ends an atomic section of SQL statements |
726 | * |
727 | * Ends the next section of atomic SQL statements and commits the transaction |
728 | * if necessary. |
729 | * |
730 | * @since 1.23 |
731 | * @see IDatabase::startAtomic |
732 | * @param string $fname |
733 | * @throws DBError If an error occurs, {@see query} |
734 | */ |
735 | public function endAtomic( $fname = __METHOD__ ); |
736 | |
737 | /** |
738 | * Cancel an atomic section of SQL statements |
739 | * |
740 | * This will roll back only the statements executed since the start of the |
741 | * most recent atomic section, and close that section. If a transaction was |
742 | * open before the corresponding startAtomic() call, any statements before |
743 | * that call are *not* rolled back and the transaction remains open. If the |
744 | * corresponding startAtomic() implicitly started a transaction, that |
745 | * transaction is rolled back. |
746 | * |
747 | * @note callers must use additional measures for situations involving two or more |
748 | * (peer) transactions (e.g. updating two database servers at once). The transaction |
749 | * and savepoint logic of startAtomic() are bound to specific IDatabase instances. |
750 | * |
751 | * Note that a call to IDatabase::rollback() will also roll back any open atomic sections. |
752 | * |
753 | * @note As an optimization to save rountrips, this method may only be called |
754 | * when startAtomic() was called with the ATOMIC_CANCELABLE flag. |
755 | * @since 1.31 |
756 | * @see IDatabase::startAtomic |
757 | * @param string $fname |
758 | * @param AtomicSectionIdentifier|null $sectionId Section ID from startAtomic(); |
759 | * passing this enables cancellation of unclosed nested sections [optional] |
760 | * @throws DBError If an error occurs, {@see query} |
761 | */ |
762 | public function cancelAtomic( $fname = __METHOD__, AtomicSectionIdentifier $sectionId = null ); |
763 | |
764 | /** |
765 | * Perform an atomic section of reversible SQL statements from a callback |
766 | * |
767 | * The $callback takes the following arguments: |
768 | * - This database object |
769 | * - The value of $fname |
770 | * |
771 | * This will execute the callback inside a pair of startAtomic()/endAtomic() calls. |
772 | * If any exception occurs during execution of the callback, it will be handled as follows: |
773 | * - If $cancelable is ATOMIC_CANCELABLE, cancelAtomic() will be called to back out any |
774 | * (and only) statements executed during the atomic section. If that succeeds, then the |
775 | * exception will be re-thrown; if it fails, then a different exception will be thrown |
776 | * and any further query attempts will fail until rollback() is called. |
777 | * - If $cancelable is ATOMIC_NOT_CANCELABLE, cancelAtomic() will be called to mark the |
778 | * end of the section and the error will be re-thrown. Any further query attempts will |
779 | * fail until rollback() is called. |
780 | * |
781 | * This method is convenient for letting calls to the caller of this method be wrapped |
782 | * in a try/catch blocks for exception types that imply that the caller failed but was |
783 | * able to properly discard the changes it made in the transaction. This method can be |
784 | * an alternative to explicit calls to startAtomic()/endAtomic()/cancelAtomic(). |
785 | * |
786 | * Example usage, "RecordStore::save" method: |
787 | * @code |
788 | * $dbw->doAtomicSection( __METHOD__, function ( $dbw ) use ( $record ) { |
789 | * // Create new record metadata row |
790 | * $dbw->insert( 'records', $record->toArray(), __METHOD__ ); |
791 | * // Figure out where to store the data based on the new row's ID |
792 | * $path = $this->recordDirectory . '/' . $dbw->insertId(); |
793 | * // Write the record data to the storage system; |
794 | * // blob store throws StoreFailureException on failure |
795 | * $this->blobStore->create( $path, $record->getJSON() ); |
796 | * // Try to cleanup files orphaned by transaction rollback |
797 | * $dbw->onTransactionResolution( |
798 | * function ( $type ) use ( $path ) { |
799 | * if ( $type === IDatabase::TRIGGER_ROLLBACK ) { |
800 | * $this->blobStore->delete( $path ); |
801 | * } |
802 | * }, |
803 | * __METHOD__ |
804 | * ); |
805 | * }, $dbw::ATOMIC_CANCELABLE ); |
806 | * @endcode |
807 | * |
808 | * Example usage, caller of the "RecordStore::save" method: |
809 | * @code |
810 | * $dbw->startAtomic( __METHOD__ ); |
811 | * // ...various SQL writes happen... |
812 | * try { |
813 | * $recordStore->save( $record ); |
814 | * } catch ( StoreFailureException $e ) { |
815 | * // ...various SQL writes happen... |
816 | * } |
817 | * // ...various SQL writes happen... |
818 | * $dbw->endAtomic( __METHOD__ ); |
819 | * @endcode |
820 | * |
821 | * @see Database::startAtomic |
822 | * @see Database::endAtomic |
823 | * @see Database::cancelAtomic |
824 | * |
825 | * @param string $fname Caller name (usually __METHOD__) |
826 | * @param callable $callback Callback that issues write queries |
827 | * @param string $cancelable Pass self::ATOMIC_CANCELABLE to use a |
828 | * savepoint and enable self::cancelAtomic() for this section. |
829 | * @return mixed Result of the callback (since 1.28) |
830 | * @throws DBError If an error occurs, {@see query} |
831 | * @throws Exception If an error occurs in the callback |
832 | * @since 1.27; prior to 1.31 this did a rollback() instead of |
833 | * cancelAtomic(), and assumed no callers up the stack would ever try to |
834 | * catch the exception. |
835 | */ |
836 | public function doAtomicSection( |
837 | $fname, callable $callback, $cancelable = self::ATOMIC_NOT_CANCELABLE |
838 | ); |
839 | |
840 | /** |
841 | * Begin a transaction |
842 | * |
843 | * Only call this from code with outer transaction scope. |
844 | * See https://www.mediawiki.org/wiki/Database_transactions for details. |
845 | * Nesting of transactions is not supported. |
846 | * |
847 | * Note that when the DBO_TRX flag is set (which is usually the case for web |
848 | * requests, but not for maintenance scripts), any previous database query |
849 | * will have started a transaction automatically. |
850 | * |
851 | * Nesting of transactions is not supported. Attempts to nest transactions |
852 | * will cause a warning, unless the current transaction was started |
853 | * automatically because of the DBO_TRX flag. |
854 | * |
855 | * @param string $fname Calling function name |
856 | * @param string $mode A situationally valid IDatabase::TRANSACTION_* constant [optional] |
857 | * @throws DBError If an error occurs, {@see query} |
858 | */ |
859 | public function begin( $fname = __METHOD__, $mode = self::TRANSACTION_EXPLICIT ); |
860 | |
861 | /** |
862 | * Commits a transaction previously started using begin() |
863 | * |
864 | * If no transaction is in progress, a warning is issued. |
865 | * |
866 | * Only call this from code with outer transaction scope. |
867 | * See https://www.mediawiki.org/wiki/Database_transactions for details. |
868 | * Nesting of transactions is not supported. |
869 | * |
870 | * @param string $fname |
871 | * @param string $flush Flush flag, set to situationally valid IDatabase::FLUSHING_* |
872 | * constant to disable warnings about explicitly committing implicit transactions, |
873 | * or calling commit when no transaction is in progress. |
874 | * This will trigger an exception if there is an ongoing explicit transaction. |
875 | * Only set the flush flag if you are sure that these warnings are not applicable, |
876 | * and no explicit transactions are open. |
877 | * @throws DBError If an error occurs, {@see query} |
878 | */ |
879 | public function commit( $fname = __METHOD__, $flush = self::FLUSHING_ONE ); |
880 | |
881 | /** |
882 | * Rollback a transaction previously started using begin() |
883 | * |
884 | * Only call this from code with outer transaction scope. |
885 | * See https://www.mediawiki.org/wiki/Database_transactions for details. |
886 | * Nesting of transactions is not supported. If a serious unexpected error occurs, |
887 | * throwing an Exception is preferable, using a pre-installed error handler to trigger |
888 | * rollback (in any case, failure to issue COMMIT will cause rollback server-side). |
889 | * |
890 | * Query, connection, and onTransaction* callback errors will be suppressed and logged. |
891 | * |
892 | * @param string $fname Calling function name |
893 | * @param string $flush Flush flag, set to a situationally valid IDatabase::FLUSHING_* |
894 | * constant to disable warnings about explicitly rolling back implicit transactions. |
895 | * This will silently break any ongoing explicit transaction. Only set the flush flag |
896 | * if you are sure that it is safe to ignore these warnings in your context. |
897 | * @throws DBError If an error occurs, {@see query} |
898 | * @since 1.23 Added $flush parameter |
899 | */ |
900 | public function rollback( $fname = __METHOD__, $flush = self::FLUSHING_ONE ); |
901 | |
902 | /** |
903 | * Commit any transaction but error out if writes or callbacks are pending |
904 | * |
905 | * This is intended for clearing out REPEATABLE-READ snapshots so that callers can |
906 | * see a new point-in-time of the database. This is useful when one of many transaction |
907 | * rounds finished and significant time will pass in the script's lifetime. It is also |
908 | * useful to call on a replica server after waiting on replication to catch up to the |
909 | * primary server. |
910 | * |
911 | * @param string $fname Calling function name |
912 | * @param string $flush Flush flag, set to situationally valid IDatabase::FLUSHING_* |
913 | * constant to disable warnings about explicitly committing implicit transactions, |
914 | * or calling commit when no transaction is in progress. |
915 | * This will trigger an exception if there is an ongoing explicit transaction. |
916 | * Only set the flush flag if you are sure that these warnings are not applicable, |
917 | * and no explicit transactions are open. |
918 | * @throws DBError If an error occurs, {@see query} |
919 | * @since 1.28 |
920 | * @since 1.34 Added $flush parameter |
921 | */ |
922 | public function flushSnapshot( $fname = __METHOD__, $flush = self::FLUSHING_ONE ); |
923 | |
924 | /** |
925 | * Override database's default behavior. |
926 | * Not all options are supported on all database backends; |
927 | * unsupported options are silently ignored. |
928 | * |
929 | * $options include: |
930 | * - 'connTimeout': Set the connection timeout value in seconds. |
931 | * May be useful for very long batch queries such as full-wiki dumps, |
932 | * where a single query reads out over hours or days. |
933 | * Only supported on MySQL and MariaDB. |
934 | * - 'groupConcatMaxLen': Maximum length of a GROUP_CONCAT() result. |
935 | * Only supported on MySQL and MariaDB. |
936 | * |
937 | * @param array $options |
938 | * @return void |
939 | * @throws DBError If an error occurs, {@see query} |
940 | */ |
941 | public function setSessionOptions( array $options ); |
942 | |
943 | /** |
944 | * Check to see if a named lock is not locked by any thread (non-blocking) |
945 | * |
946 | * @param string $lockName Name of lock to poll |
947 | * @param string $method Name of method calling us |
948 | * @return bool |
949 | * @throws DBError If an error occurs, {@see query} |
950 | * @since 1.20 |
951 | */ |
952 | public function lockIsFree( $lockName, $method ); |
953 | |
954 | /** |
955 | * Acquire a named lock |
956 | * |
957 | * Named locks are not related to transactions |
958 | * |
959 | * @param string $lockName Name of lock to acquire |
960 | * @param string $method Name of the calling method |
961 | * @param int $timeout Acquisition timeout in seconds (0 means non-blocking) |
962 | * @param int $flags Bit field of IDatabase::LOCK_* constants |
963 | * @return bool|float|null Success (bool); acquisition time (float/null) if LOCK_TIMESTAMP |
964 | * @throws DBError If an error occurs, {@see query} |
965 | */ |
966 | public function lock( $lockName, $method, $timeout = 5, $flags = 0 ); |
967 | |
968 | /** |
969 | * Release a lock |
970 | * |
971 | * Named locks are not related to transactions |
972 | * |
973 | * @param string $lockName Name of lock to release |
974 | * @param string $method Name of the calling method |
975 | * @return bool Success |
976 | * @throws DBError If an error occurs, {@see query} |
977 | */ |
978 | public function unlock( $lockName, $method ); |
979 | |
980 | /** |
981 | * Acquire a named lock, flush any transaction, and return an RAII style unlocker object |
982 | * |
983 | * Only call this from outer transaction scope and when only one DB server will be affected. |
984 | * See https://www.mediawiki.org/wiki/Database_transactions for details. |
985 | * |
986 | * This is suitable for transactions that need to be serialized using cooperative locks, |
987 | * where each transaction can see each others' changes. Any transaction is flushed to clear |
988 | * out stale REPEATABLE-READ snapshot data. Once the returned object falls out of PHP scope, |
989 | * the lock will be released unless a transaction is active. If one is active, then the lock |
990 | * will be released when it either commits or rolls back. |
991 | * |
992 | * If the lock acquisition failed, then no transaction flush happens, and null is returned. |
993 | * |
994 | * @param string $lockKey Name of lock to release |
995 | * @param string $fname Name of the calling method |
996 | * @param int $timeout Acquisition timeout in seconds |
997 | * @return ScopedCallback|null |
998 | * @throws DBError If an error occurs, {@see query} |
999 | * @since 1.27 |
1000 | */ |
1001 | public function getScopedLockAndFlush( $lockKey, $fname, $timeout ); |
1002 | |
1003 | /** |
1004 | * Check if this DB server is marked as read-only according to load balancer info |
1005 | * |
1006 | * @note LoadBalancer checks serverIsReadOnly() when setting the load balancer info array |
1007 | * |
1008 | * @return bool |
1009 | * @since 1.27 |
1010 | */ |
1011 | public function isReadOnly(); |
1012 | } |