rdbms: set the schema in the LBFactory local domain
authorAaron Schulz <aschulz@wikimedia.org>
Tue, 30 Jan 2018 03:09:07 +0000 (19:09 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Wed, 31 Jan 2018 16:53:29 +0000 (08:53 -0800)
Also, enforce that new DB connection use the domain
schema as is the case with the DB name and table prefix.

The code worked previously since the local domain did not override
the schema in the server configuration arrays, so it happened not
to clobber the domain schema.

Lastly, fix unit test fatal in LBFactorySingle::forEachLB() when
called during LBFactorySingle::_destruct().

Change-Id: Ia9ddef0f21591d0c8b15f2947cd61569e3fec7a0

includes/db/MWLBFactory.php
includes/libs/rdbms/lbfactory/LBFactorySingle.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancerSingle.php

index aa1918d..5607332 100644 (file)
@@ -46,7 +46,7 @@ abstract class MWLBFactory {
                $lbConf += [
                        'localDomain' => new DatabaseDomain(
                                $mainConfig->get( 'DBname' ),
-                               null,
+                               $mainConfig->get( 'DBmwschema' ),
                                $mainConfig->get( 'DBprefix' )
                        ),
                        'profiler' => Profiler::instance(),
index cd998c3..587ab23 100644 (file)
@@ -102,6 +102,8 @@ class LBFactorySingle extends LBFactory {
         * @param array $params
         */
        public function forEachLB( $callback, array $params = [] ) {
-               call_user_func_array( $callback, array_merge( [ $this->lb ], $params ) );
+               if ( isset( $this->lb ) ) { // may not be set during _destruct()
+                       call_user_func_array( $callback, array_merge( [ $this->lb ], $params ) );
+               }
        }
 }
index ee3c86f..864e6f0 100644 (file)
@@ -825,7 +825,7 @@ class LoadBalancer implements ILoadBalancer {
                                        // Use the local domain table prefix if the local domain is specified
                                        $server['tablePrefix'] = $this->localDomain->getTablePrefix();
                                }
-                               $conn = $this->reallyOpenConnection( $server, $this->localDomain->getDatabase() );
+                               $conn = $this->reallyOpenConnection( $server, $this->localDomain );
                                $host = $this->getServerName( $i );
                                if ( $conn->isOpen() ) {
                                        $this->connLogger->debug( "Connected to database $i at '$host'." );
@@ -926,7 +926,7 @@ class LoadBalancer implements ILoadBalancer {
                        $server['foreignPoolRefCount'] = 0;
                        $server['foreign'] = true;
                        $server['autoCommitOnly'] = $autoCommit;
-                       $conn = $this->reallyOpenConnection( $server, $dbName );
+                       $conn = $this->reallyOpenConnection( $server, $domainInstance );
                        if ( !$conn->isOpen() ) {
                                $this->connLogger->warning( __METHOD__ . ": connection error for $i/$domain" );
                                $this->errorConnection = $conn;
@@ -969,18 +969,19 @@ class LoadBalancer implements ILoadBalancer {
         * Returns a Database object whether or not the connection was successful.
         *
         * @param array $server
-        * @param string|null $dbNameOverride Use "" to not select any database
+        * @param DatabaseDomain $domainOverride Use an unspecified domain to not select any database
         * @return Database
         * @throws DBAccessError
         * @throws InvalidArgumentException
         */
-       protected function reallyOpenConnection( array $server, $dbNameOverride ) {
+       protected function reallyOpenConnection( array $server, DatabaseDomain $domainOverride ) {
                if ( $this->disabled ) {
                        throw new DBAccessError();
                }
 
-               if ( $dbNameOverride !== null ) {
-                       $server['dbname'] = $dbNameOverride;
+               if ( $domainOverride->getDatabase() !== null ) {
+                       $server['dbname'] = $domainOverride->getDatabase();
+                       $server['schema'] = $domainOverride->getSchema();
                }
 
                // Let the handle know what the cluster master is (e.g. "db1052")
@@ -1698,7 +1699,7 @@ class LoadBalancer implements ILoadBalancer {
                $oldDomain = $this->localDomain->getId();
                $this->setLocalDomain( new DatabaseDomain(
                        $this->localDomain->getDatabase(),
-                       null,
+                       $this->localDomain->getSchema(),
                        $prefix
                ) );
 
index c737563..89472e7 100644 (file)
@@ -72,7 +72,7 @@ class LoadBalancerSingle extends LoadBalancer {
                return new static( [ 'connection' => $db ] + $params );
        }
 
-       protected function reallyOpenConnection( array $server, $dbNameOverride ) {
+       protected function reallyOpenConnection( array $server, DatabaseDomain $domainOverride ) {
                return $this->db;
        }
 }