From: Aaron Schulz Date: Fri, 8 Mar 2019 22:04:54 +0000 (-0800) Subject: rdbms: optimize Database::selectDomain() to avoid extra queries X-Git-Tag: 1.34.0-rc.0~2587^2 X-Git-Url: http://git.cyclocoop.org/%24image?a=commitdiff_plain;h=bfd7f1aa4c685e7ec9a7b09085f6829544eb6f09;p=lhc%2Fweb%2Fwiklou.git rdbms: optimize Database::selectDomain() to avoid extra queries Also clean up and align the mysql subclass versions of the method. Enforce that raw "USE" queries are not passed in, since they would break the tracking (even before this change). Change-Id: I11c9145c6c0525f27a4ec8d94c500a22a712b320 --- diff --git a/includes/libs/rdbms/database/Database.php b/includes/libs/rdbms/database/Database.php index bafdb44b1d..3475b098c2 100644 --- a/includes/libs/rdbms/database/Database.php +++ b/includes/libs/rdbms/database/Database.php @@ -1347,12 +1347,19 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware } /** + * Error out if the DB is not in a valid state for a query via query() + * * @param string $sql * @param string $fname * @throws DBTransactionStateError */ private function assertTransactionStatus( $sql, $fname ) { - if ( $this->getQueryVerb( $sql ) === 'ROLLBACK' ) { // transaction/savepoint + $verb = $this->getQueryVerb( $sql ); + if ( $verb === 'USE' ) { + throw new DBUnexpectedError( $this, "Got USE query; use selectDomain() instead." ); + } + + if ( $verb === 'ROLLBACK' ) { // transaction/savepoint return; } diff --git a/includes/libs/rdbms/database/DatabaseMssql.php b/includes/libs/rdbms/database/DatabaseMssql.php index 6e50f5f103..ad5cf98f5c 100644 --- a/includes/libs/rdbms/database/DatabaseMssql.php +++ b/includes/libs/rdbms/database/DatabaseMssql.php @@ -1167,8 +1167,18 @@ class DatabaseMssql extends Database { } protected function doSelectDomain( DatabaseDomain $domain ) { - $encDatabase = $this->addIdentifierQuotes( $domain->getDatabase() ); - $this->query( "USE $encDatabase" ); + if ( $domain->getSchema() !== null ) { + throw new DBExpectedError( $this, __CLASS__ . ": domain schemas are not supported." ); + } + + $database = $domain->getDatabase(); + if ( $database !== $this->getDBname() ) { + $encDatabase = $this->addIdentifierQuotes( $database ); + $res = $this->doQuery( "USE $encDatabase" ); + if ( !$res ) { + throw new DBExpectedError( $this, "Could not select database '$database'." ); + } + } // Update that domain fields on success (no exception thrown) $this->currentDomain = $domain; diff --git a/includes/libs/rdbms/database/DatabaseMysqli.php b/includes/libs/rdbms/database/DatabaseMysqli.php index a3907caa06..d0bd1b3805 100644 --- a/includes/libs/rdbms/database/DatabaseMysqli.php +++ b/includes/libs/rdbms/database/DatabaseMysqli.php @@ -185,15 +185,16 @@ class DatabaseMysqli extends DatabaseMysqlBase { } function doSelectDomain( DatabaseDomain $domain ) { - $conn = $this->getBindingHandle(); - if ( $domain->getSchema() !== null ) { throw new DBExpectedError( $this, __CLASS__ . ": domain schemas are not supported." ); } $database = $domain->getDatabase(); - if ( !$conn->select_db( $database ) ) { - throw new DBExpectedError( $this, "Could not select database '$database'." ); + if ( $database !== $this->getDBname() ) { + $conn = $this->getBindingHandle(); + if ( !$conn->select_db( $database ) ) { + throw new DBExpectedError( $this, "Could not select database '$database'." ); + } } // Update that domain fields on success (no exception thrown)