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 */
20namespace Wikimedia\Rdbms;
21
22use stdClass;
23use Stringable;
24use Wikimedia\Rdbms\Database\DbQuoter;
25use Wikimedia\Rdbms\Database\IDatabaseFlags;
26use Wikimedia\Rdbms\Platform\ISQLPlatform;
27
28/**
29 * A database connection without write operations.
30 *
31 * @since 1.40
32 * @ingroup Database
33 */
34interface IReadableDatabase extends Stringable, ISQLPlatform, DbQuoter, IDatabaseFlags {
35
36    /** Parameter to unionQueries() for UNION ALL */
37    public const UNION_ALL = true;
38    /** Parameter to unionQueries() for UNION DISTINCT */
39    public const UNION_DISTINCT = false;
40
41    /**
42     * Get a human-readable string describing the current software version
43     *
44     * Use getServerVersion() to get machine-friendly information.
45     *
46     * @return string Version information from the database server
47     */
48    public function getServerInfo();
49
50    /**
51     * Get/set the table prefix
52     *
53     * @param string|null $prefix The table prefix to set, or omitted to leave it unchanged
54     * @return string The previous table prefix
55     */
56    public function tablePrefix( $prefix = null );
57
58    /**
59     * Get/set the db schema
60     *
61     * @param string|null $schema The database schema to set, or omitted to leave it unchanged
62     * @return string The previous db schema
63     */
64    public function dbSchema( $schema = null );
65
66    /**
67     * @return bool Whether a connection to the database open
68     */
69    public function isOpen();
70
71    /**
72     * Return the currently selected domain ID
73     *
74     * Null components (database/schema) might change once a connection is established
75     *
76     * @return string
77     */
78    public function getDomainID();
79
80    /**
81     * Get the RDBMS type of the server (e.g. "mysql", "sqlite")
82     *
83     * @return string
84     */
85    public function getType();
86
87    /**
88     * Get the RDBMS-specific error code from the last attempted query statement
89     *
90     * @return int|string Error code (integer or hexadecimal depending on RDBMS type)
91     */
92    public function lastErrno();
93
94    /**
95     * Get the RDBMS-specific error description from the last attempted query statement
96     *
97     * @return string
98     */
99    public function lastError();
100
101    /**
102     * Returns a wikitext style link to the DB's website (e.g. "[https://www.mysql.com/ MySQL]")
103     *
104     * Should at least contain plain text, if for some reason your database has no website.
105     *
106     * @return string Wikitext of a link to the server software's web site
107     */
108    public function getSoftwareLink();
109
110    /**
111     * A string describing the current software version
112     *
113     * @return string Version information from the database server.
114     */
115    public function getServerVersion();
116
117    /**
118     * Close the database connection
119     *
120     * This should only be called after any transactions have been resolved,
121     * aside from read-only automatic transactions (assuming no callbacks are registered).
122     * If a transaction is still open anyway, it will be rolled back.
123     *
124     * @internal Only for use by LoadBalancer
125     *
126     * @param string $fname Caller name @phan-mandatory-param
127     * @return bool Success
128     * @throws DBError
129     */
130    public function close( $fname = __METHOD__ );
131
132    /**
133     * Create an empty SelectQueryBuilder which can be used to run queries
134     * against this connection.
135     *
136     * @note A new query builder must be created per query. Query builders
137     *   should not be reused since this uses a fluent interface and the state of
138     *   the builder changes during the query which may cause unexpected results.
139     *
140     * @return SelectQueryBuilder
141     */
142    public function newSelectQueryBuilder(): SelectQueryBuilder;
143
144    /**
145     * Create an empty UnionQueryBuilder which can be used to run queries
146     * against this connection.
147     *
148     * @note A new query builder must be created per query. Query builders
149     *   should not be reused since this uses a fluent interface and the state of
150     *   the builder changes during the query which may cause unexpected results.
151     *
152     * @since 1.41
153     * @return UnionQueryBuilder
154     */
155    public function newUnionQueryBuilder(): UnionQueryBuilder;
156
157    /**
158     * A SELECT wrapper which returns a single field from a single result row
159     *
160     * If no result rows are returned from the query, false is returned.
161     *
162     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchField}
163     * instead, which is more readable and less error-prone.
164     *
165     * @internal callers outside of rdbms library should use SelectQueryBuilder instead.
166     *
167     * @param string|array $tables Table reference(s), using the unqualified name of tables
168     *  or of the form "information_schema.<identifier>". {@see select} for details.
169     * @param-taint $tables exec_sql
170     * @param string|array $var The field name to select. This must be a valid SQL fragment: do not
171     *  use unvalidated user input. Can be an array, but must contain exactly 1 element then.
172     *  {@see select} for details.
173     * @param-taint $var exec_sql
174     * @phpcs:ignore Generic.Files.LineLength
175     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $cond
176     *  The condition array. {@see select} for details.
177     * @param-taint $cond exec_sql_numkey
178     * @param string $fname The function name of the caller. @phan-mandatory-param
179     * @param-taint $fname exec_sql
180     * @param string|array $options The query options. {@see select} for details.
181     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
182     * @param string|array $join_conds The query join conditions. {@see select} for details.
183     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
184     * @return mixed|false The value from the field, or false if nothing was found
185     * @return-taint tainted
186     * @throws DBError If an error occurs, {@see query}
187     */
188    public function selectField(
189        $tables, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
190    );
191
192    /**
193     * A SELECT wrapper which returns a list of single field values from result rows
194     *
195     * If no result rows are returned from the query, an empty array is returned.
196     *
197     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchFieldValues}
198     * instead, which is more readable and less error-prone.
199     *
200     * @internal callers outside of rdbms library should use SelectQueryBuilder instead.
201     *
202     * @param string|array $tables Table reference(s), using the unqualified name of tables
203     *   or of the form "information_schema.<identifier>". {@see select} for details.
204     * @param-taint $tables exec_sql
205     * @param string $var The field name to select. This must be a valid SQL
206     *   fragment: do not use unvalidated user input.
207     * @param-taint $var exec_sql
208     * @phpcs:ignore Generic.Files.LineLength
209     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $cond
210     *   The condition array. {@see select} for details.
211     * @param-taint $cond exec_sql_numkey
212     * @param string $fname The function name of the caller. @phan-mandatory-param
213     * @param-taint $fname exec_sql
214     * @param string|array $options The query options. {@see select} for details.
215     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
216     * @param string|array $join_conds The query join conditions. {@see select} for details.
217     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
218     *
219     * @return array The values from the field in the order they were returned from the DB
220     * @return-taint tainted
221     * @throws DBError If an error occurs, {@see query}
222     * @since 1.25
223     */
224    public function selectFieldValues(
225        $tables, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
226    ): array;
227
228    /**
229     * Execute a SELECT query constructed using the various parameters provided
230     *
231     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchResultSet}
232     * instead, which is more readable and less error-prone.
233     *
234     * @param string|array $tables Table reference(s), using the unqualified name of tables
235     *   or of the form "information_schema.<identifier>".
236     * @param-taint $tables exec_sql
237     *
238     * Each table reference assigns a table name to a specified collection of rows
239     * for the context of the query (e.g. field expressions, WHERE clause, GROUP BY
240     * clause, HAVING clause, ect...). Use of multiple table references implies a JOIN.
241     *
242     * If a string is given, it must hold the name of the table having the specified
243     * collection of rows. If an array is given, each entry must be one of the following:
244     *   - A string holding the name of the existing table which has the collection
245     *     of rows. If keyed by a string, the key will be the assigned table name.
246     *   - A Subquery instance which specifies the collection of rows derived from
247     *     a subquery. If keyed by a string, the key will be the assigned table name.
248     *     Otherwise, the SQL text of the subquery will be the assigned table name.
249     *   - An array specifying the collection of rows derived from a parenthesized
250     *     JOIN. It must be keyed by a string, which will be used as the assigned
251     *     table name.
252     *
253     * String keys allow table aliases to be specified, for example:
254     *
255     *    [ 'a' => 'user' ]
256     *
257     * This includes the user table in the query, with the alias "a" available
258     * for use in field names (e.g. a.user_name).
259     *
260     * A derived table, defined by the result of selectSQLText(), requires an alias
261     * key and a Subquery instance value which wraps the SQL query, for example:
262     *
263     *    [ 'c' => new Subquery( 'SELECT ...' ) ]
264     *
265     * Joins using parentheses for grouping (since MediaWiki 1.31) may be
266     * constructed using nested arrays. For example,
267     *
268     *    [ 'tableA', 'nestedB' => [ 'tableB', 'b2' => 'tableB2' ] ]
269     *
270     * along with `$join_conds` like
271     *
272     *    [ 'b2' => [ 'JOIN', 'b_id = b2_id' ], 'nestedB' => [ 'LEFT JOIN', 'b_a = a_id' ] ]
273     *
274     * will produce SQL something like
275     *
276     *    FROM tableA LEFT JOIN (tableB JOIN tableB2 AS b2 ON (b_id = b2_id)) ON (b_a = a_id)
277     *
278     * All of the table names given here are automatically run through
279     * Database::tableName(), which causes the table prefix (if any) to be
280     * added, and various other table name mappings to be performed.
281     *
282     * Do not use untrusted user input as a table name. Alias names should
283     * not have characters outside of the Basic multilingual plane.
284     *
285     * @param string|array $vars Field name(s)
286     * @param-taint $vars exec_sql
287     *
288     * May be either a field name or an array of field names. The field names
289     * can be complete fragments of SQL, for direct inclusion into the SELECT
290     * query. If an array is given, field aliases can be specified, for example:
291     *
292     *   [ 'maxrev' => 'MAX(rev_id)' ]
293     *
294     * This includes an expression with the alias "maxrev" in the query.
295     *
296     * If an expression is given, care must be taken to ensure that it is
297     * DBMS-independent.
298     *
299     * Untrusted user input must not be passed to this parameter.
300     *
301     * @phpcs:ignore Generic.Files.LineLength
302     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
303     * @param-taint $conds exec_sql_numkey
304     *
305     * May be either a string containing a single condition, or an array of
306     * conditions. If an array is given, the conditions constructed from each
307     * element are combined with AND.
308     *
309     * Array elements may take one of two forms:
310     *
311     *   - Elements with a numeric key are interpreted as raw SQL fragments.
312     *   - Elements with a string key are interpreted as equality conditions,
313     *     where the key is the field name.
314     *     - If the value of such an array element is a scalar (such as a
315     *       string), it will be treated as data and thus quoted appropriately.
316     *       If it is null, an IS NULL clause will be added.
317     *     - If the value is an array, an IN (...) clause will be constructed
318     *       from its non-null elements, and an IS NULL clause will be added
319     *       if null is present, such that the field may match any of the
320     *       elements in the array. The non-null elements will be quoted.
321     *
322     * Note that expressions are often DBMS-dependent in their syntax.
323     * DBMS-independent wrappers are provided for constructing several types of
324     * expression commonly used in condition queries. See:
325     *    - IDatabase::buildLike()
326     *    - IDatabase::conditional()
327     *
328     * Untrusted user input is safe in the values of string keys, however untrusted
329     * input must not be used in the array key names or in the values of numeric keys.
330     * Escaping of untrusted input used in values of numeric keys should be done via
331     * IDatabase::addQuotes()
332     *
333     * Use an empty array, string, or IDatabase::ALL_ROWS to select all rows.
334     *
335     * You *can* put simple join conditions here, but this is strongly discouraged.
336     * Instead of
337     *
338     *     // $conds...
339     *     'rev_actor = actor_id',
340     *
341     * use (see below for $join_conds):
342     *
343     *     // $join_conds...
344     *     'actor' => [ 'JOIN', 'rev_actor = actor_id' ],
345     *
346     * @param string $fname Caller function name @phan-mandatory-param
347     * @param-taint $fname exec_sql
348     *
349     * @param string|array $options Query options
350     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
351     *
352     * Optional: Array of query options. Boolean options are specified by
353     * including them in the array as a string value with a numeric key, for
354     * example:
355     *
356     *    [ 'FOR UPDATE' ]
357     *
358     * The supported options are:
359     *
360     *   - OFFSET: Skip this many rows at the start of the result set. OFFSET
361     *     with LIMIT can theoretically be used for paging through a result set,
362     *     but this is discouraged for performance reasons.
363     *
364     *   - LIMIT: Integer: return at most this many rows. The rows are sorted
365     *     and then the first rows are taken until the limit is reached. LIMIT
366     *     is applied to a result set after OFFSET.
367     *
368     *   - LOCK IN SHARE MODE: Boolean: lock the returned rows so that they can't be
369     *     changed until the next COMMIT. Cannot be used with aggregate functions
370     *     (COUNT, MAX, etc., but also DISTINCT).
371     *
372     *   - FOR UPDATE: Boolean: lock the returned rows so that they can't be
373     *     changed nor read with LOCK IN SHARE MODE until the next COMMIT.
374     *     Cannot be used with aggregate functions (COUNT, MAX, etc., but also DISTINCT).
375     *
376     *   - DISTINCT: Boolean: return only unique result rows.
377     *
378     *   - GROUP BY: May be either an SQL fragment string naming a field or
379     *     expression to group by, or an array of such SQL fragments.
380     *
381     *   - HAVING: May be either a string containing a HAVING clause or an array of
382     *     conditions building the HAVING clause. If an array is given, the conditions
383     *     constructed from each element are combined with AND.
384     *
385     *   - ORDER BY: May be either an SQL fragment giving a field name or
386     *     expression to order by, or an array of such SQL fragments.
387     *
388     *   - USE INDEX: This may be either a string giving the index name to use
389     *     for the query, or an array. If it is an associative array, each key
390     *     gives the table name (or alias), each value gives the index name to
391     *     use for that table. All strings are SQL fragments and so should be
392     *     validated by the caller.
393     *
394     *   - IGNORE INDEX: This may be either be a string giving an index name to
395     *     ignore for the query, or an array. If it is an associative array,
396     *     each key gives the table name (or alias), each value gives the index
397     *     name to ignore for that table. All strings are SQL fragments and so
398     *     should be validated by the caller.
399     *
400     *   - EXPLAIN: In MySQL, this causes an EXPLAIN SELECT query to be run,
401     *     instead of SELECT.
402     *
403     *   - MAX_EXECUTION_TIME: (only in MySQL/MariaDB) maximum allowed time to
404     *     run the query in milliseconds (if database supports it).
405     *
406     * And also the following boolean MySQL extensions, see the MySQL manual
407     * for documentation:
408     *
409     *    - STRAIGHT_JOIN
410     *    - SQL_BIG_RESULT
411     *    - SQL_BUFFER_RESULT
412     *    - SQL_SMALL_RESULT
413     *    - SQL_CALC_FOUND_ROWS
414     *
415     * @param string|array $join_conds Join conditions
416     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
417     *
418     * Optional associative array of table-specific join conditions.
419     * Simple conditions can also be specified in the regular $conds,
420     * but this is strongly discouraged in favor of the more explicit syntax here.
421     *
422     * The key of the array contains the table name or alias. The value is an
423     * array with two elements, numbered 0 and 1. The first gives the type of
424     * join, the second is the same as the $conds parameter. Thus it can be
425     * an SQL fragment, or an array where the string keys are equality and the
426     * numeric keys are SQL fragments all AND'd together. For example:
427     *
428     *    [ 'page' => [ 'LEFT JOIN', 'page_latest=rev_id' ] ]
429     *
430     * @internal
431     * @return IResultWrapper Resulting rows
432     * @return-taint tainted
433     * @throws DBError If an error occurs, {@see query}
434     */
435    public function select(
436        $tables,
437        $vars,
438        $conds = '',
439        $fname = __METHOD__,
440        $options = [],
441        $join_conds = []
442    );
443
444    /**
445     * Wrapper to IDatabase::select() that only fetches one row (via LIMIT)
446     *
447     * If the query returns no rows, false is returned.
448     *
449     * This method is convenient for fetching a row based on a unique key condition.
450     *
451     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchRow}
452     * instead, which is more readable and less error-prone.
453     *
454     * @internal
455     * @param string|array $tables Table reference(s), using the unqualified name of tables
456     *   or of the form "information_schema.<identifier>". {@see select} for details.
457     * @param-taint $tables exec_sql
458     * @param string|array $vars Field names
459     * @param-taint $vars exec_sql
460     * @phpcs:ignore Generic.Files.LineLength
461     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
462     *   Conditions
463     * @param-taint $conds exec_sql_numkey
464     * @param string $fname Caller function name @phan-mandatory-param
465     * @param-taint $fname exec_sql
466     * @param string|array $options Query options
467     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
468     * @param array|string $join_conds Join conditions
469     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
470     * @return stdClass|false
471     * @return-taint tainted
472     * @throws DBError If an error occurs, {@see query}
473     */
474    public function selectRow(
475        $tables,
476        $vars,
477        $conds,
478        $fname = __METHOD__,
479        $options = [],
480        $join_conds = []
481    );
482
483    /**
484     * Estimate the number of rows in dataset
485     *
486     * MySQL allows you to estimate the number of rows that would be returned
487     * by a SELECT query, using EXPLAIN SELECT. The estimate is provided using
488     * index cardinality statistics, and is notoriously inaccurate, especially
489     * when large numbers of rows have recently been added or deleted.
490     *
491     * For DBMSs that don't support fast result size estimation, this function
492     * will actually perform the SELECT COUNT(*).
493     *
494     * Takes the same arguments as IDatabase::select().
495     *
496     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::estimateRowCount}
497     * instead, which is more readable and less error-prone.
498     *
499     * @internal
500     * @param string|string[] $tables Table reference(s), using the unqualified name of tables
501     *   or of the form "information_schema.<identifier>". {@see select} for details.
502     * @param string $var Column for which NULL values are not counted [default "*"]
503     * @phpcs:ignore Generic.Files.LineLength
504     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
505     *   Filters on the table
506     * @param string $fname Function name for profiling @phan-mandatory-param
507     * @param array $options Options for select
508     * @param array|string $join_conds Join conditions
509     * @return int Row count
510     * @throws DBError If an error occurs, {@see query}
511     */
512    public function estimateRowCount(
513        $tables, $var = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
514    ): int;
515
516    /**
517     * Get the number of rows in dataset
518     *
519     * This is useful when trying to do COUNT(*) but with a LIMIT for performance.
520     *
521     * Takes the same arguments as IDatabase::select().
522     *
523     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchRowCount}
524     * instead, which is more readable and less error-prone.
525     *
526     * @since 1.27 Added $join_conds parameter
527     *
528     * @internal
529     * @param string|string[] $tables Table reference(s), using the unqualified name of tables
530     *   or of the form "information_schema.<identifier>". {@see select} for details.
531     * @param-taint $tables exec_sql
532     * @param string $var Column for which NULL values are not counted [default "*"]
533     * @param-taint $var exec_sql
534     * @phpcs:ignore Generic.Files.LineLength
535     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
536     *   Filters on the table
537     * @param-taint $conds exec_sql_numkey
538     * @param string $fname Function name for profiling @phan-mandatory-param
539     * @param-taint $fname exec_sql
540     * @param array $options Options for select
541     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
542     * @param array $join_conds Join conditions (since 1.27)
543     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
544     * @return int Row count
545     * @return-taint none
546     * @throws DBError If an error occurs, {@see query}
547     */
548    public function selectRowCount(
549        $tables, $var = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
550    ): int;
551
552    /**
553     * Returns true if DBs are assumed to be on potentially different servers
554     *
555     * In systems like mysql/mariadb, different databases can easily be referenced on a single
556     * connection merely by name, even in a single query via JOIN. On the other hand, Postgres
557     * treats databases as logically separate, with different database users, requiring special
558     * mechanisms like postgres_fdw to "mount" foreign DBs. This is true even among DBs on the
559     * same server. Changing the selected database via selectDomain() requires a new connection.
560     *
561     * @return bool
562     * @since 1.29
563     */
564    public function databasesAreIndependent();
565
566    /**
567     * Set the current domain (database, schema, and table prefix)
568     *
569     * This will throw an error for some database types if the database is unspecified
570     *
571     * This should only be called by a load balancer or if the handle is not attached to one
572     *
573     * @param string|DatabaseDomain $domain
574     * @throws DBConnectionError If databasesAreIndependent() is true and connection change fails
575     * @throws DBError On query error, if domain changes are disallowed, or the domain is invalid
576     * @since 1.32
577     */
578    public function selectDomain( $domain );
579
580    /**
581     * Get the current database name; null if there isn't one
582     *
583     * @return string|null
584     */
585    public function getDBname();
586
587    /**
588     * Get the hostname or IP address of the server
589     *
590     * @return string|null
591     */
592    public function getServer();
593
594    /**
595     * Get the readable name for the server
596     *
597     * @return string Readable server name, falling back to the hostname or IP address
598     * @since 1.36
599     */
600    public function getServerName();
601
602    /**
603     * Ping the server and try to reconnect if it there is no connection
604     *
605     * @return bool Success or failure
606     */
607    public function ping();
608
609    /**
610     * Get the seconds of replication lag on this database server
611     *
612     * Callers should avoid using this method while a transaction is active
613     *
614     * @return float|int|false Database replication lag in seconds or false on error
615     * @throws DBError If an error occurs, {@see query}
616     */
617    public function getLag();
618
619    /**
620     * Get a cached estimate of the seconds of replication lag on this database server,
621     * using the estimate obtained at the start of the current transaction if one is active
622     *
623     * This is useful when transactions might use snapshot isolation (e.g. REPEATABLE-READ in
624     * innodb), so the "real" lag of that data is this lag plus transaction duration. If they
625     * don't, it is still safe to be pessimistic. In AUTOCOMMIT mode, this still gives an
626     * indication of the staleness of subsequent reads.
627     *
628     * @return array ('lag': seconds or false on error, 'since': UNIX timestamp of BEGIN)
629     * @throws DBError If an error occurs, {@see query}
630     * @since 1.27
631     */
632    public function getSessionLagStatus();
633
634    /**
635     * Some DBMSs have a special format for inserting into blob fields, they
636     * don't allow simple quoted strings to be inserted. To insert into such
637     * a field, pass the data through this function before passing it to
638     * IDatabase::insert().
639     *
640     * @param string $b
641     * @return string|Blob
642     * @throws DBError
643     */
644    public function encodeBlob( $b );
645
646    /**
647     * Some DBMSs return a special placeholder object representing blob fields
648     * in result objects. Pass the object through this function to return the
649     * original string.
650     *
651     * @param string|Blob $b
652     * @return string
653     * @throws DBError
654     */
655    public function decodeBlob( $b );
656
657    /**
658     * See Expression::__construct()
659     *
660     * @since 1.42
661     * @param string $field
662     * @param-taint $field exec_sql
663     * @param string $op One of '>', '<', '!=', '=', '>=', '<=', IExpression::LIKE, IExpression::NOT_LIKE
664     * @phan-param '\x3E'|'\x3C'|'!='|'='|'\x3E='|'\x3C='|'LIKE'|'NOT LIKE' $op
665     * @param-taint $op exec_sql
666     * @param ?scalar|RawSQLValue|Blob|LikeValue|non-empty-list<scalar|Blob> $value
667     * @param-taint $value escapes_sql
668     * @return Expression
669     * @phan-side-effect-free
670     */
671    public function expr( string $field, string $op, $value ): Expression;
672
673    /**
674     * See Expression::__construct()
675     *
676     * @since 1.43
677     * @phpcs:ignore Generic.Files.LineLength
678     * @param non-empty-array<string,?scalar|RawSQLValue|Blob|LikeValue|non-empty-list<scalar|Blob>>|non-empty-array<int,IExpression> $conds
679     * @param-taint $conds exec_sql_numkey
680     * @return AndExpressionGroup
681     * @phan-side-effect-free
682     */
683    public function andExpr( array $conds ): AndExpressionGroup;
684
685    /**
686     * See Expression::__construct()
687     *
688     * @since 1.43
689     * @phpcs:ignore Generic.Files.LineLength
690     * @param non-empty-array<string,?scalar|RawSQLValue|Blob|LikeValue|non-empty-list<scalar|Blob>>|non-empty-array<int,IExpression> $conds
691     * @param-taint $conds exec_sql_numkey
692     * @return OrExpressionGroup
693     * @phan-side-effect-free
694     */
695    public function orExpr( array $conds ): OrExpressionGroup;
696
697    /**
698     * Get a debugging string that mentions the database type, the ID of this instance,
699     * and the ID of any underlying connection resource or driver object if one is present
700     *
701     * @return string "<db type> object #<X>" or "<db type> object #<X> (resource/handle id #<Y>)"
702     * @since 1.34
703     */
704    public function __toString();
705}