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// Very long type annotations :(
29// phpcs:disable Generic.Files.LineLength
30
31/**
32 * A database connection without write operations.
33 *
34 * @since 1.40
35 * @ingroup Database
36 */
37interface IReadableDatabase extends Stringable, ISQLPlatform, DbQuoter, IDatabaseFlags {
38
39    /** Parameter to unionQueries() for UNION ALL */
40    public const UNION_ALL = true;
41    /** Parameter to unionQueries() for UNION DISTINCT */
42    public const UNION_DISTINCT = false;
43
44    /**
45     * Get a human-readable string describing the current software version
46     *
47     * Use getServerVersion() to get machine-friendly information.
48     *
49     * @return string Version information from the database server
50     */
51    public function getServerInfo();
52
53    /**
54     * Get/set the table prefix
55     *
56     * @param string|null $prefix The table prefix to set, or omitted to leave it unchanged
57     * @return string The previous table prefix
58     */
59    public function tablePrefix( $prefix = null );
60
61    /**
62     * Get/set the db schema
63     *
64     * @param string|null $schema The database schema to set, or omitted to leave it unchanged
65     * @return string The previous db schema
66     */
67    public function dbSchema( $schema = null );
68
69    /**
70     * @return bool Whether a connection to the database open
71     */
72    public function isOpen();
73
74    /**
75     * Return the currently selected domain ID
76     *
77     * Null components (database/schema) might change once a connection is established
78     *
79     * @return string
80     */
81    public function getDomainID();
82
83    /**
84     * Get the RDBMS type of the server (e.g. "mysql", "sqlite")
85     *
86     * @return string
87     */
88    public function getType();
89
90    /**
91     * Get the RDBMS-specific error code from the last attempted query statement
92     *
93     * @return int|string Error code (integer or hexadecimal depending on RDBMS type)
94     */
95    public function lastErrno();
96
97    /**
98     * Get the RDBMS-specific error description from the last attempted query statement
99     *
100     * @return string
101     */
102    public function lastError();
103
104    /**
105     * Returns a wikitext style link to the DB's website (e.g. "[https://www.mysql.com/ MySQL]")
106     *
107     * Should at least contain plain text, if for some reason your database has no website.
108     *
109     * @return string Wikitext of a link to the server software's web site
110     */
111    public function getSoftwareLink();
112
113    /**
114     * A string describing the current software version
115     *
116     * @return string Version information from the database server.
117     */
118    public function getServerVersion();
119
120    /**
121     * Close the database connection
122     *
123     * This should only be called after any transactions have been resolved,
124     * aside from read-only automatic transactions (assuming no callbacks are registered).
125     * If a transaction is still open anyway, it will be rolled back.
126     *
127     * @internal Only for use by LoadBalancer
128     *
129     * @param string $fname Caller name
130     * @return bool Success
131     * @throws DBError
132     */
133    public function close( $fname = __METHOD__ );
134
135    /**
136     * Create an empty SelectQueryBuilder which can be used to run queries
137     * against this connection.
138     *
139     * @note A new query builder must be created per query. Query builders
140     *   should not be reused since this uses a fluent interface and the state of
141     *   the builder changes during the query which may cause unexpected results.
142     *
143     * @return SelectQueryBuilder
144     */
145    public function newSelectQueryBuilder(): SelectQueryBuilder;
146
147    /**
148     * Create an empty UnionQueryBuilder which can be used to run queries
149     * against this connection.
150     *
151     * @note A new query builder must be created per query. Query builders
152     *   should not be reused since this uses a fluent interface and the state of
153     *   the builder changes during the query which may cause unexpected results.
154     *
155     * @since 1.41
156     * @return UnionQueryBuilder
157     */
158    public function newUnionQueryBuilder(): UnionQueryBuilder;
159
160    /**
161     * A SELECT wrapper which returns a single field from a single result row
162     *
163     * If no result rows are returned from the query, false is returned.
164     *
165     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchField}
166     * instead, which is more readable and less error-prone.
167     *
168     * @internal callers outside of rdbms library should use SelectQueryBuilder instead.
169     *
170     * @param string|array $tables Table reference(s), using the unqualified name of tables
171     *  or of the form "information_schema.<identifier>". {@see select} for details.
172     * @param-taint $tables exec_sql
173     * @param string|array $var The field name to select. This must be a valid SQL fragment: do not
174     *  use unvalidated user input. Can be an array, but must contain exactly 1 element then.
175     *  {@see select} for details.
176     * @param-taint $var exec_sql
177     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $cond
178     *  The condition array. {@see select} for details.
179     * @param-taint $cond exec_sql_numkey
180     * @param string $fname The function name of the caller.
181     * @param-taint $fname exec_sql
182     * @param string|array $options The query options. {@see select} for details.
183     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
184     * @param string|array $join_conds The query join conditions. {@see select} for details.
185     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
186     * @return mixed|false The value from the field, or false if nothing was found
187     * @return-taint tainted
188     * @throws DBError If an error occurs, {@see query}
189     */
190    public function selectField(
191        $tables, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
192    );
193
194    /**
195     * A SELECT wrapper which returns a list of single field values from result rows
196     *
197     * If no result rows are returned from the query, an empty array is returned.
198     *
199     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchFieldValues}
200     * instead, which is more readable and less error-prone.
201     *
202     * @internal callers outside of rdbms library should use SelectQueryBuilder instead.
203     *
204     * @param string|array $tables Table reference(s), using the unqualified name of tables
205     *   or of the form "information_schema.<identifier>". {@see select} for details.
206     * @param-taint $tables exec_sql
207     * @param string $var The field name to select. This must be a valid SQL
208     *   fragment: do not use unvalidated user input.
209     * @param-taint $var exec_sql
210     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $cond
211     *   The condition array. {@see select} for details.
212     * @param-taint $cond exec_sql_numkey
213     * @param string $fname The function name of the caller.
214     * @param-taint $fname exec_sql
215     * @param string|array $options The query options. {@see select} for details.
216     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
217     * @param string|array $join_conds The query join conditions. {@see select} for details.
218     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
219     *
220     * @return array The values from the field in the order they were returned from the DB
221     * @return-taint tainted
222     * @throws DBError If an error occurs, {@see query}
223     * @since 1.25
224     */
225    public function selectFieldValues(
226        $tables, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
227    ): array;
228
229    /**
230     * Execute a SELECT query constructed using the various parameters provided
231     *
232     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchResultSet}
233     * instead, which is more readable and less error-prone.
234     *
235     * @param string|array $tables Table reference(s), using the unqualified name of tables
236     *   or of the form "information_schema.<identifier>".
237     * @param-taint $tables exec_sql
238     *
239     * Each table reference assigns a table name to a specified collection of rows
240     * for the context of the query (e.g. field expressions, WHERE clause, GROUP BY
241     * clause, HAVING clause, ect...). Use of multiple table references implies a JOIN.
242     *
243     * If a string is given, it must hold the name of the table having the specified
244     * collection of rows. If an array is given, each entry must be one of the following:
245     *   - A string holding the name of the existing table which has the collection
246     *     of rows. If keyed by a string, the key will be the assigned table name.
247     *   - A Subquery instance which specifies the collection of rows derived from
248     *     a subquery. If keyed by a string, the key will be the assigned table name.
249     *     Otherwise, the SQL text of the subquery will be the assigned table name.
250     *   - An array specifying the collection of rows derived from a parenthesized
251     *     JOIN. It must be keyed by a string, which will be used as the assigned
252     *     table name.
253     *
254     * String keys allow table aliases to be specified, for example:
255     *
256     *    [ 'a' => 'user' ]
257     *
258     * This includes the user table in the query, with the alias "a" available
259     * for use in field names (e.g. a.user_name).
260     *
261     * A derived table, defined by the result of selectSQLText(), requires an alias
262     * key and a Subquery instance value which wraps the SQL query, for example:
263     *
264     *    [ 'c' => new Subquery( 'SELECT ...' ) ]
265     *
266     * Joins using parentheses for grouping (since MediaWiki 1.31) may be
267     * constructed using nested arrays. For example,
268     *
269     *    [ 'tableA', 'nestedB' => [ 'tableB', 'b2' => 'tableB2' ] ]
270     *
271     * along with `$join_conds` like
272     *
273     *    [ 'b2' => [ 'JOIN', 'b_id = b2_id' ], 'nestedB' => [ 'LEFT JOIN', 'b_a = a_id' ] ]
274     *
275     * will produce SQL something like
276     *
277     *    FROM tableA LEFT JOIN (tableB JOIN tableB2 AS b2 ON (b_id = b2_id)) ON (b_a = a_id)
278     *
279     * All of the table names given here are automatically run through
280     * Database::tableName(), which causes the table prefix (if any) to be
281     * added, and various other table name mappings to be performed.
282     *
283     * Do not use untrusted user input as a table name. Alias names should
284     * not have characters outside of the Basic multilingual plane.
285     *
286     * @param string|array $vars Field name(s)
287     * @param-taint $vars exec_sql
288     *
289     * May be either a field name or an array of field names. The field names
290     * can be complete fragments of SQL, for direct inclusion into the SELECT
291     * query. If an array is given, field aliases can be specified, for example:
292     *
293     *   [ 'maxrev' => 'MAX(rev_id)' ]
294     *
295     * This includes an expression with the alias "maxrev" in the query.
296     *
297     * If an expression is given, care must be taken to ensure that it is
298     * DBMS-independent.
299     *
300     * Untrusted user input must not be passed to this parameter.
301     *
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
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     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
461     *   Conditions
462     * @param-taint $conds exec_sql_numkey
463     * @param string $fname Caller function name
464     * @param-taint $fname exec_sql
465     * @param string|array $options Query options
466     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
467     * @param array|string $join_conds Join conditions
468     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
469     * @return stdClass|false
470     * @return-taint tainted
471     * @throws DBError If an error occurs, {@see query}
472     */
473    public function selectRow(
474        $tables,
475        $vars,
476        $conds,
477        $fname = __METHOD__,
478        $options = [],
479        $join_conds = []
480    );
481
482    /**
483     * Estimate the number of rows in dataset
484     *
485     * MySQL allows you to estimate the number of rows that would be returned
486     * by a SELECT query, using EXPLAIN SELECT. The estimate is provided using
487     * index cardinality statistics, and is notoriously inaccurate, especially
488     * when large numbers of rows have recently been added or deleted.
489     *
490     * For DBMSs that don't support fast result size estimation, this function
491     * will actually perform the SELECT COUNT(*).
492     *
493     * Takes the same arguments as IDatabase::select().
494     *
495     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::estimateRowCount}
496     * instead, which is more readable and less error-prone.
497     *
498     * @internal
499     * @param string|string[] $tables Table reference(s), using the unqualified name of tables
500     *   or of the form "information_schema.<identifier>". {@see select} for details.
501     * @param string $var Column for which NULL values are not counted [default "*"]
502     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
503     *   Filters on the table
504     * @param string $fname Function name for profiling
505     * @param array $options Options for select
506     * @param array|string $join_conds Join conditions
507     * @return int Row count
508     * @throws DBError If an error occurs, {@see query}
509     */
510    public function estimateRowCount(
511        $tables, $var = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
512    ): int;
513
514    /**
515     * Get the number of rows in dataset
516     *
517     * This is useful when trying to do COUNT(*) but with a LIMIT for performance.
518     *
519     * Takes the same arguments as IDatabase::select().
520     *
521     * New callers should use {@link newSelectQueryBuilder} with {@link SelectQueryBuilder::fetchRowCount}
522     * instead, which is more readable and less error-prone.
523     *
524     * @since 1.27 Added $join_conds parameter
525     *
526     * @internal
527     * @param string|string[] $tables Table reference(s), using the unqualified name of tables
528     *   or of the form "information_schema.<identifier>". {@see select} for details.
529     * @param-taint $tables exec_sql
530     * @param string $var Column for which NULL values are not counted [default "*"]
531     * @param-taint $var exec_sql
532     * @param string|IExpression|array<string,?scalar|non-empty-array<int,?scalar>|RawSQLValue>|array<int,string|IExpression> $conds
533     *   Filters on the table
534     * @param-taint $conds exec_sql_numkey
535     * @param string $fname Function name for profiling
536     * @param-taint $fname exec_sql
537     * @param array $options Options for select
538     * @param-taint $options none This is special-cased in MediaWikiSecurityCheckPlugin
539     * @param array $join_conds Join conditions (since 1.27)
540     * @param-taint $join_conds none This is special-cased in MediaWikiSecurityCheckPlugin
541     * @return int Row count
542     * @return-taint none
543     * @throws DBError If an error occurs, {@see query}
544     */
545    public function selectRowCount(
546        $tables, $var = '*', $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
547    ): int;
548
549    /**
550     * Returns true if DBs are assumed to be on potentially different servers
551     *
552     * In systems like mysql/mariadb, different databases can easily be referenced on a single
553     * connection merely by name, even in a single query via JOIN. On the other hand, Postgres
554     * treats databases as logically separate, with different database users, requiring special
555     * mechanisms like postgres_fdw to "mount" foreign DBs. This is true even among DBs on the
556     * same server. Changing the selected database via selectDomain() requires a new connection.
557     *
558     * @return bool
559     * @since 1.29
560     */
561    public function databasesAreIndependent();
562
563    /**
564     * Set the current domain (database, schema, and table prefix)
565     *
566     * This will throw an error for some database types if the database is unspecified
567     *
568     * This should only be called by a load balancer or if the handle is not attached to one
569     *
570     * @param string|DatabaseDomain $domain
571     * @throws DBConnectionError If databasesAreIndependent() is true and connection change fails
572     * @throws DBError On query error, if domain changes are disallowed, or the domain is invalid
573     * @since 1.32
574     */
575    public function selectDomain( $domain );
576
577    /**
578     * Get the current database name; null if there isn't one
579     *
580     * @return string|null
581     */
582    public function getDBname();
583
584    /**
585     * Get the hostname or IP address of the server
586     *
587     * @return string|null
588     */
589    public function getServer();
590
591    /**
592     * Get the readable name for the server
593     *
594     * @return string Readable server name, falling back to the hostname or IP address
595     * @since 1.36
596     */
597    public function getServerName();
598
599    /**
600     * Ping the server and try to reconnect if it there is no connection
601     *
602     * @return bool Success or failure
603     */
604    public function ping();
605
606    /**
607     * Get the seconds of replication lag on this database server
608     *
609     * Callers should avoid using this method while a transaction is active
610     *
611     * @return float|int|false Database replication lag in seconds or false on error
612     * @throws DBError If an error occurs, {@see query}
613     */
614    public function getLag();
615
616    /**
617     * Get a cached estimate of the seconds of replication lag on this database server,
618     * using the estimate obtained at the start of the current transaction if one is active
619     *
620     * This is useful when transactions might use snapshot isolation (e.g. REPEATABLE-READ in
621     * innodb), so the "real" lag of that data is this lag plus transaction duration. If they
622     * don't, it is still safe to be pessimistic. In AUTOCOMMIT mode, this still gives an
623     * indication of the staleness of subsequent reads.
624     *
625     * @return array ('lag': seconds or false on error, 'since': UNIX timestamp of BEGIN)
626     * @throws DBError If an error occurs, {@see query}
627     * @since 1.27
628     */
629    public function getSessionLagStatus();
630
631    /**
632     * Some DBMSs have a special format for inserting into blob fields, they
633     * don't allow simple quoted strings to be inserted. To insert into such
634     * a field, pass the data through this function before passing it to
635     * IDatabase::insert().
636     *
637     * @param string $b
638     * @return string|Blob
639     * @throws DBError
640     */
641    public function encodeBlob( $b );
642
643    /**
644     * Some DBMSs return a special placeholder object representing blob fields
645     * in result objects. Pass the object through this function to return the
646     * original string.
647     *
648     * @param string|Blob $b
649     * @return string
650     * @throws DBError
651     */
652    public function decodeBlob( $b );
653
654    /**
655     * See Expression::__construct()
656     *
657     * @since 1.42
658     * @param string $field
659     * @param-taint $field exec_sql
660     * @param string $op One of '>', '<', '!=', '=', '>=', '<=', IExpression::LIKE, IExpression::NOT_LIKE
661     * @phan-param '\x3E'|'\x3C'|'!='|'='|'\x3E='|'\x3C='|'LIKE'|'NOT LIKE' $op
662     * @param-taint $op exec_sql
663     * @param ?scalar|RawSQLValue|Blob|LikeValue|non-empty-list<scalar|Blob> $value
664     * @param-taint $value escapes_sql
665     * @return Expression
666     * @phan-side-effect-free
667     */
668    public function expr( string $field, string $op, $value ): Expression;
669
670    /**
671     * See Expression::__construct()
672     *
673     * @since 1.43
674     * @param non-empty-array<string,?scalar|RawSQLValue|Blob|LikeValue|non-empty-list<scalar|Blob>>|non-empty-array<int,IExpression> $conds
675     * @param-taint $conds exec_sql_numkey
676     * @return AndExpressionGroup
677     * @phan-side-effect-free
678     */
679    public function andExpr( array $conds ): AndExpressionGroup;
680
681    /**
682     * See Expression::__construct()
683     *
684     * @since 1.43
685     * @param non-empty-array<string,?scalar|RawSQLValue|Blob|LikeValue|non-empty-list<scalar|Blob>>|non-empty-array<int,IExpression> $conds
686     * @param-taint $conds exec_sql_numkey
687     * @return OrExpressionGroup
688     * @phan-side-effect-free
689     */
690    public function orExpr( array $conds ): OrExpressionGroup;
691
692    /**
693     * Get a debugging string that mentions the database type, the ID of this instance,
694     * and the ID of any underlying connection resource or driver object if one is present
695     *
696     * @return string "<db type> object #<X>" or "<db type> object #<X> (resource/handle id #<Y>)"
697     * @since 1.34
698     */
699    public function __toString();
700}