mirror of
https://github.com/processwire/processwire.git
synced 2025-08-12 17:54:44 +02:00
Add support for multiple randomly-selected DB readers
This commit is contained in:
@@ -255,10 +255,22 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
'options' => $options,
|
'options' => $options,
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!empty($reader) && (!empty($reader['host']) || !empty($reader['socket']))) {
|
if(!empty($reader)) {
|
||||||
$reader['dsn'] = self::dsn(array_merge($dsnArray, $reader));
|
if(isset($reader['host']) || isset($reader['socket'])) {
|
||||||
$reader = array_merge($data, $reader);
|
// single reader
|
||||||
$data['reader'] = $reader;
|
$reader['dsn'] = self::dsn(array_merge($dsnArray, $reader));
|
||||||
|
$reader = array_merge($data, $reader);
|
||||||
|
$data['reader'] = $reader;
|
||||||
|
} else {
|
||||||
|
// multiple readers
|
||||||
|
$readers = array();
|
||||||
|
foreach($reader as $r) {
|
||||||
|
if(empty($r['host']) && empty($r['socket'])) continue;
|
||||||
|
$r['dsn'] = self::dsn(array_merge($dsnArray, $r));
|
||||||
|
$readers[] = array_merge($data, $r);
|
||||||
|
}
|
||||||
|
$data['reader'] = $readers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$database = new WireDatabasePDO($data);
|
$database = new WireDatabasePDO($data);
|
||||||
@@ -337,12 +349,22 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
public function __construct($dsn, $username = null, $password = null, array $driver_options = array()) {
|
public function __construct($dsn, $username = null, $password = null, array $driver_options = array()) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
if(is_array($dsn) && isset($dsn['dsn'])) {
|
if(is_array($dsn) && isset($dsn['dsn'])) {
|
||||||
|
// configuration data provided in $dsn argument array
|
||||||
if($username !== null && empty($dsn['user'])) $dsn['user'] = $username;
|
if($username !== null && empty($dsn['user'])) $dsn['user'] = $username;
|
||||||
if($password !== null && empty($dsn['pass'])) $dsn['pass'] = $password;
|
if($password !== null && empty($dsn['pass'])) $dsn['pass'] = $password;
|
||||||
if(!isset($dsn['options'])) $dsn['options'] = $driver_options;
|
if(!isset($dsn['options'])) $dsn['options'] = $driver_options;
|
||||||
$this->pdoConfig = array_merge($this->pdoConfig, $dsn);
|
$this->pdoConfig = array_merge($this->pdoConfig, $dsn);
|
||||||
if(!empty($this->pdoConfig['reader']['dsn'])) $this->reader['has'] = true;
|
if(!empty($this->pdoConfig['reader'])) {
|
||||||
|
if(!empty($this->pdoConfig['reader']['dsn'])) {
|
||||||
|
// single reader
|
||||||
|
$this->reader['has'] = true;
|
||||||
|
} else if(!empty($this->pdoConfig['reader'][0]['dsn'])) {
|
||||||
|
// multiple readers
|
||||||
|
$this->reader['has'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// configuration data in direct arguments
|
||||||
$this->pdoConfig['dsn'] = $dsn;
|
$this->pdoConfig['dsn'] = $dsn;
|
||||||
$this->pdoConfig['user'] = $username;
|
$this->pdoConfig['user'] = $username;
|
||||||
$this->pdoConfig['pass'] = $password;
|
$this->pdoConfig['pass'] = $password;
|
||||||
@@ -462,20 +484,42 @@ class WireDatabasePDO extends Wire implements WireDatabase {
|
|||||||
*/
|
*/
|
||||||
protected function pdoReader() {
|
protected function pdoReader() {
|
||||||
if(!$this->allowReader()) return $this->pdoWriter();
|
if(!$this->allowReader()) return $this->pdoWriter();
|
||||||
if(!$this->reader['pdo']) {
|
|
||||||
$this->reader['init'] = false;
|
if($this->reader['pdo']) {
|
||||||
$pdo = new \PDO(
|
|
||||||
$this->pdoConfig['reader']['dsn'],
|
|
||||||
$this->pdoConfig['reader']['user'],
|
|
||||||
$this->pdoConfig['reader']['pass'],
|
|
||||||
$this->pdoConfig['reader']['options']
|
|
||||||
);
|
|
||||||
$this->reader['pdo'] = $pdo;
|
|
||||||
$this->_init($pdo);
|
|
||||||
} else {
|
|
||||||
$pdo = $this->reader['pdo'];
|
$pdo = $this->reader['pdo'];
|
||||||
|
$this->pdoLast = $pdo;
|
||||||
|
return $pdo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->reader['init'] = false;
|
||||||
|
$lastException = null;
|
||||||
|
|
||||||
|
if(isset($this->pdoConfig['reader']['dsn'])) {
|
||||||
|
// just one reader
|
||||||
|
$readers = array($this->pdoConfig['reader']);
|
||||||
|
} else {
|
||||||
|
// randomly select a reader
|
||||||
|
$readers = $this->pdoConfig['reader'];
|
||||||
|
shuffle($readers);
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
// try readers till we find one that gives us a connection
|
||||||
|
$reader = array_shift($readers);
|
||||||
|
try {
|
||||||
|
$pdo = new \PDO($reader['dsn'], $reader['user'], $reader['pass'], $reader['options']);
|
||||||
|
} catch(\PDOException $e) {
|
||||||
|
$pdo = null;
|
||||||
|
$lastException = $e;
|
||||||
|
}
|
||||||
|
} while(!$pdo && count($readers));
|
||||||
|
|
||||||
|
if(!$pdo) throw $lastException;
|
||||||
|
|
||||||
|
$this->reader['pdo'] = $pdo;
|
||||||
|
$this->_init($pdo);
|
||||||
$this->pdoLast = $pdo;
|
$this->pdoLast = $pdo;
|
||||||
|
|
||||||
return $pdo;
|
return $pdo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user