/** * @dataProvider provideNewFromId */ public function testNewFromId($id, $db, $schema, $prefix, $exception = false) { if ($exception) { $this->setExpectedException(InvalidArgumentException::class); } $domain = DatabaseDomain::newFromId($id); $this->assertInstanceOf(DatabaseDomain::class, $domain); $this->assertEquals($db, $domain->getDatabase()); $this->assertEquals($schema, $domain->getSchema()); $this->assertEquals($prefix, $domain->getTablePrefix()); }
public function __construct(array $conf) { $this->localDomain = isset($conf['localDomain']) ? DatabaseDomain::newFromId($conf['localDomain']) : DatabaseDomain::newUnspecified(); if (isset($conf['readOnlyReason']) && is_string($conf['readOnlyReason'])) { $this->readOnlyReason = $conf['readOnlyReason']; } $this->srvCache = isset($conf['srvCache']) ? $conf['srvCache'] : new EmptyBagOStuff(); $this->memCache = isset($conf['memCache']) ? $conf['memCache'] : new EmptyBagOStuff(); $this->wanCache = isset($conf['wanCache']) ? $conf['wanCache'] : WANObjectCache::newEmpty(); foreach (self::$loggerFields as $key) { $this->{$key} = isset($conf[$key]) ? $conf[$key] : new \Psr\Log\NullLogger(); } $this->errorLogger = isset($conf['errorLogger']) ? $conf['errorLogger'] : function (Exception $e) { trigger_error(E_USER_WARNING, get_class($e) . ': ' . $e->getMessage()); }; $this->profiler = isset($params['profiler']) ? $params['profiler'] : null; $this->trxProfiler = isset($conf['trxProfiler']) ? $conf['trxProfiler'] : new TransactionProfiler(); $this->requestInfo = ['IPAddress' => isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '', 'UserAgent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '', 'ChronologyProtection' => 'true']; $this->cliMode = isset($params['cliMode']) ? $params['cliMode'] : PHP_SAPI === 'cli'; $this->hostname = isset($conf['hostname']) ? $conf['hostname'] : gethostname(); $this->agent = isset($params['agent']) ? $params['agent'] : ''; $this->ticket = mt_rand(); }
/** * Open a connection to a foreign DB, or return one if it is already open. * * Increments a reference count on the returned connection which locks the * connection to the requested domain. This reference count can be * decremented by calling reuseConnection(). * * If a connection is open to the appropriate server already, but with the wrong * database, it will be switched to the right database and returned, as long as * it has been freed first with reuseConnection(). * * On error, returns false, and the connection which caused the * error will be available via $this->mErrorConnection. * * @note If disable() was called on this LoadBalancer, this method will throw a DBAccessError. * * @param int $i Server index * @param string $domain Domain ID to open * @return Database */ private function openForeignConnection($i, $domain) { $domainInstance = DatabaseDomain::newFromId($domain); $dbName = $domainInstance->getDatabase(); $prefix = $domainInstance->getTablePrefix(); if (isset($this->mConns['foreignUsed'][$i][$domain])) { // Reuse an already-used connection $conn = $this->mConns['foreignUsed'][$i][$domain]; $this->connLogger->debug(__METHOD__ . ": reusing connection {$i}/{$domain}"); } elseif (isset($this->mConns['foreignFree'][$i][$domain])) { // Reuse a free connection for the same domain $conn = $this->mConns['foreignFree'][$i][$domain]; unset($this->mConns['foreignFree'][$i][$domain]); $this->mConns['foreignUsed'][$i][$domain] = $conn; $this->connLogger->debug(__METHOD__ . ": reusing free connection {$i}/{$domain}"); } elseif (!empty($this->mConns['foreignFree'][$i])) { // Reuse a connection from another domain $conn = reset($this->mConns['foreignFree'][$i]); $oldDomain = key($this->mConns['foreignFree'][$i]); // The empty string as a DB name means "don't care". // DatabaseMysqlBase::open() already handle this on connection. if (strlen($dbName) && !$conn->selectDB($dbName)) { $this->mLastError = "Error selecting database '{$dbName}' on server " . $conn->getServer() . " from client host {$this->host}"; $this->mErrorConnection = $conn; $conn = false; } else { $conn->tablePrefix($prefix); unset($this->mConns['foreignFree'][$i][$oldDomain]); $this->mConns['foreignUsed'][$i][$domain] = $conn; $this->connLogger->debug(__METHOD__ . ": reusing free connection from {$oldDomain} for {$domain}"); } } else { if (!isset($this->mServers[$i]) || !is_array($this->mServers[$i])) { throw new InvalidArgumentException("No server with index '{$i}'."); } // Open a new connection $server = $this->mServers[$i]; $server['serverIndex'] = $i; $server['foreignPoolRefCount'] = 0; $server['foreign'] = true; $conn = $this->reallyOpenConnection($server, $dbName); if (!$conn->isOpen()) { $this->connLogger->warning(__METHOD__ . ": connection error for {$i}/{$domain}"); $this->mErrorConnection = $conn; $conn = false; } else { $conn->tablePrefix($prefix); $this->mConns['foreignUsed'][$i][$domain] = $conn; $this->connLogger->debug(__METHOD__ . ": opened new connection for {$i}/{$domain}"); } } // Increment reference count if ($conn) { $refCount = $conn->getLBInfo('foreignPoolRefCount'); $conn->setLBInfo('foreignPoolRefCount', $refCount + 1); } return $conn; }
/** * @param DatabaseDomain|string|bool $domain Domain ID, or false for the current domain * @return array [database name, table prefix] */ private function getDBNameAndPrefix($domain = false) { $domain = $domain === false ? $this->localDomain : DatabaseDomain::newFromId($domain); return [$domain->getDatabase(), $domain->getTablePrefix()]; }