Merge "Revert "Move CSS for patrol from mediawiki.legacy to new module mediawiki...
[lhc/web/wiklou.git] / includes / db / IDatabase.php
index 7855861..43592e2 100644 (file)
  * @ingroup Database
  */
 interface IDatabase {
+       /* Constants to onTransactionResolution() callbacks */
+       const TRIGGER_IDLE = 1;
+       const TRIGGER_COMMIT = 2;
+       const TRIGGER_ROLLBACK = 3;
+
        /**
         * A string describing the current software version, and possibly
         * other details in a user-friendly way. Will be listed on Special:Version, etc.
@@ -324,7 +329,7 @@ interface IDatabase {
         *
         * Example:
         * $id = $dbw->nextSequenceValue( 'page_page_id_seq' );
-        * $dbw->insert( 'page', array( 'page_id' => $id ) );
+        * $dbw->insert( 'page', [ 'page_id' => $id ] );
         * $id = $dbw->insertId();
         *
         * @return int
@@ -514,15 +519,17 @@ interface IDatabase {
         * May be either an array of table names, or a single string holding a table
         * name. If an array is given, table aliases can be specified, for example:
         *
-        *    array( 'a' => 'user' )
+        *    [ 'a' => 'user' ]
         *
         * This includes the user table in the query, with the alias "a" available
         * for use in field names (e.g. a.user_name).
         *
         * All of the table names given here are automatically run through
-        * IDatabase::tableName(), which causes the table prefix (if any) to be
+        * DatabaseBase::tableName(), which causes the table prefix (if any) to be
         * added, and various other table name mappings to be performed.
         *
+        * Do not use untrusted user input as a table name. Alias names should
+        * not have characters outside of the Basic multilingual plane.
         *
         * @param string|array $vars
         *
@@ -530,13 +537,14 @@ interface IDatabase {
         * can be complete fragments of SQL, for direct inclusion into the SELECT
         * query. If an array is given, field aliases can be specified, for example:
         *
-        *   array( 'maxrev' => 'MAX(rev_id)' )
+        *   [ 'maxrev' => 'MAX(rev_id)' ]
         *
         * This includes an expression with the alias "maxrev" in the query.
         *
         * If an expression is given, care must be taken to ensure that it is
         * DBMS-independent.
         *
+        * Untrusted user input must not be passed to this parameter.
         *
         * @param string|array $conds
         *
@@ -563,6 +571,10 @@ interface IDatabase {
         *    - IDatabase::buildLike()
         *    - IDatabase::conditional()
         *
+        * Untrusted user input is safe in the values of string keys, however untrusted
+        * input must not be used in the array key names or in the values of numeric keys.
+        * Escaping of untrusted input used in values of numeric keys should be done via
+        * IDatabase::addQuotes()
         *
         * @param string|array $options
         *
@@ -570,7 +582,7 @@ interface IDatabase {
         * including them in the array as a string value with a numeric key, for
         * example:
         *
-        *    array( 'FOR UPDATE' )
+        *    [ 'FOR UPDATE' ]
         *
         * The supported options are:
         *
@@ -628,10 +640,11 @@ interface IDatabase {
         *
         * The key of the array contains the table name or alias. The value is an
         * array with two elements, numbered 0 and 1. The first gives the type of
-        * join, the second is an SQL fragment giving the join condition for that
-        * table. For example:
+        * join, the second is the same as the $conds parameter. Thus it can be
+        * an SQL fragment, or an array where the string keys are equality and the
+        * numeric keys are SQL fragments all AND'd together. For example:
         *
-        *    array( 'page' => array( 'LEFT JOIN', 'page_latest=rev_id' ) )
+        *    [ 'page' => [ 'LEFT JOIN', 'page_latest=rev_id' ] ]
         *
         * @return ResultWrapper|bool If the query returned no rows, a ResultWrapper
         *   with no rows in it will be returned. If there was a query error, a
@@ -794,7 +807,7 @@ interface IDatabase {
         *     IDatabase::affectedRows().
         *
         * @param string $table Table name. This will be passed through
-        *   IDatabase::tableName().
+        *   DatabaseBase::tableName().
         * @param array $a Array of rows to insert
         * @param string $fname Calling function name (use __METHOD__) for logs/profiling
         * @param array $options Array of options
@@ -807,7 +820,7 @@ interface IDatabase {
         * UPDATE wrapper. Takes a condition array and a SET array.
         *
         * @param string $table Name of the table to UPDATE. This will be passed through
-        *   IDatabase::tableName().
+        *   DatabaseBase::tableName().
         * @param array $values An array of values to SET. For each array element,
         *   the key gives the field name, and the value gives the data to set
         *   that field to. The data will be quoted by IDatabase::addQuotes().
@@ -844,7 +857,7 @@ interface IDatabase {
         * The keys on each level may be either integers or strings.
         *
         * @param array $data Organized as 2-d
-        *    array(baseKeyVal => array(subKeyVal => [ignored], ...), ...)
+        *    [ baseKeyVal => [ subKeyVal => [ignored], ... ], ... ]
         * @param string $baseKey Field name to match the base-level keys to (eg 'pl_namespace')
         * @param string $subKey Field name to match the sub-level keys to (eg 'pl_title')
         * @return string|bool SQL fragment, or false if no items in array
@@ -937,7 +950,7 @@ interface IDatabase {
         * Example: $dbr->buildLike( 'My_page_title/', $dbr->anyString() ) returns
         * a LIKE clause that searches for subpages of 'My page title'.
         * Alternatively:
-        *   $pattern = array( 'My_page_title/', $dbr->anyString() );
+        *   $pattern = [ 'My_page_title/', $dbr->anyString() ];
         *   $query .= $dbr->buildLike( $pattern );
         *
         * @since 1.16
@@ -1020,7 +1033,7 @@ interface IDatabase {
         *
         * @since 1.22
         *
-        * @param string $table Table name. This will be passed through IDatabase::tableName().
+        * @param string $table Table name. This will be passed through DatabaseBase::tableName().
         * @param array $rows A single row or list of rows to insert
         * @param array $uniqueIndexes List of single field names or field name tuples
         * @param array $set An array of values to SET. For each array element, the
@@ -1079,7 +1092,7 @@ interface IDatabase {
         *    to include in a join.
         *
         * @param array $varMap Must be an associative array of the form
-        *    array( 'dest1' => 'source1', ...). Source items may be literals
+        *    [ 'dest1' => 'source1', ... ]. Source items may be literals
         *    rather than field names, but strings should be quoted with
         *    IDatabase::addQuotes()
         *
@@ -1143,7 +1156,6 @@ interface IDatabase {
 
        /**
         * Determines how long the server has been up
-        * STUB
         *
         * @return int
         */
@@ -1151,7 +1163,6 @@ interface IDatabase {
 
        /**
         * Determines if the last failure was due to a deadlock
-        * STUB
         *
         * @return bool
         */
@@ -1159,16 +1170,14 @@ interface IDatabase {
 
        /**
         * Determines if the last failure was due to a lock timeout
-        * STUB
         *
         * @return bool
         */
        public function wasLockTimeout();
 
        /**
-        * Determines if the last query error was something that should be dealt
-        * with by pinging the connection and reissuing the query.
-        * STUB
+        * Determines if the last query error was due to a dropped connection and should
+        * be dealt with by pinging the connection and reissuing the query.
         *
         * @return bool
         */
@@ -1176,21 +1185,19 @@ interface IDatabase {
 
        /**
         * Determines if the last failure was due to the database being read-only.
-        * STUB
         *
         * @return bool
         */
        public function wasReadOnlyError();
 
        /**
-        * Wait for the slave to catch up to a given master position.
+        * Wait for the slave to catch up to a given master position
         *
         * @param DBMasterPos $pos
-        * @param int $timeout The maximum number of seconds to wait for
-        *   synchronisation
-        * @return int Zero if the slave was past that position already,
+        * @param int $timeout The maximum number of seconds to wait for synchronisation
+        * @return int|null Zero if the slave was past that position already,
         *   greater than zero if we waited for some period of time, less than
-        *   zero if we timed out.
+        *   zero if it timed out, and null on error
         */
        public function masterPosWait( DBMasterPos $pos, $timeout );
 
@@ -1209,7 +1216,30 @@ interface IDatabase {
        public function getMasterPos();
 
        /**
-        * Run an anonymous function as soon as there is no transaction pending.
+        * @return bool Whether the DB is marked as read-only server-side
+        * @since 1.28
+        */
+       public function serverIsReadOnly();
+
+       /**
+        * Run a callback as soon as the current transaction commits or rolls back.
+        * An error is thrown if no transaction is pending. Queries in the function will run in
+        * AUTO-COMMIT mode unless there are begin() calls. Callbacks must commit any transactions
+        * that they begin.
+        *
+        * This is useful for combining cooperative locks and DB transactions.
+        *
+        * The callback takes one argument:
+        * How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_ROLLBACK)
+        *
+        * @param callable $callback
+        * @return mixed
+        * @since 1.28
+        */
+       public function onTransactionResolution( callable $callback );
+
+       /**
+        * Run a callback as soon as there is no transaction pending.
         * If there is a transaction and it is rolled back, then the callback is cancelled.
         * Queries in the function will run in AUTO-COMMIT mode unless there are begin() calls.
         * Callbacks must commit any transactions that they begin.
@@ -1221,15 +1251,19 @@ interface IDatabase {
         *
         * Updates will execute in the order they were enqueued.
         *
+        * The callback takes one argument:
+        * How the transaction ended (IDatabase::TRIGGER_COMMIT or IDatabase::TRIGGER_IDLE)
+        *
         * @param callable $callback
         * @since 1.20
         */
-       public function onTransactionIdle( $callback );
+       public function onTransactionIdle( callable $callback );
 
        /**
-        * Run an anonymous function before the current transaction commits or now if there is none.
+        * Run a callback before the current transaction commits or now if there is none.
         * If there is a transaction and it is rolled back, then the callback is cancelled.
-        * Callbacks must not start nor commit any transactions.
+        * Callbacks must not start nor commit any transactions. If no transaction is active,
+        * then a transaction will wrap the callback.
         *
         * This is useful for updates that easily cause deadlocks if locks are held too long
         * but where atomicity is strongly desired for these updates and some related updates.
@@ -1239,7 +1273,7 @@ interface IDatabase {
         * @param callable $callback
         * @since 1.22
         */
-       public function onTransactionPreCommitOrIdle( $callback );
+       public function onTransactionPreCommitOrIdle( callable $callback );
 
        /**
         * Begin an atomic section of statements
@@ -1306,7 +1340,7 @@ interface IDatabase {
         * @throws UnexpectedValueException
         * @since 1.27
         */
-       public function doAtomicSection( $fname, $callback );
+       public function doAtomicSection( $fname, callable $callback );
 
        /**
         * Begin a transaction. If a transaction is already in progress,