v.0.1
This commit is contained in:
289
vendor/illuminate/database/Connectors/ConnectionFactory.php
vendored
Executable file
289
vendor/illuminate/database/Connectors/ConnectionFactory.php
vendored
Executable file
@ -0,0 +1,289 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Database\Connectors;
|
||||
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Database\Connection;
|
||||
use Illuminate\Database\MySqlConnection;
|
||||
use Illuminate\Database\PostgresConnection;
|
||||
use Illuminate\Database\SQLiteConnection;
|
||||
use Illuminate\Database\SqlServerConnection;
|
||||
use Illuminate\Support\Arr;
|
||||
use InvalidArgumentException;
|
||||
use PDOException;
|
||||
|
||||
class ConnectionFactory
|
||||
{
|
||||
/**
|
||||
* The IoC container instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Container\Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Create a new connection factory instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Container\Container $container
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a PDO connection based on the configuration.
|
||||
*
|
||||
* @param array $config
|
||||
* @param string|null $name
|
||||
* @return \Illuminate\Database\Connection
|
||||
*/
|
||||
public function make(array $config, $name = null)
|
||||
{
|
||||
$config = $this->parseConfig($config, $name);
|
||||
|
||||
if (isset($config['read'])) {
|
||||
return $this->createReadWriteConnection($config);
|
||||
}
|
||||
|
||||
return $this->createSingleConnection($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and prepare the database configuration.
|
||||
*
|
||||
* @param array $config
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
protected function parseConfig(array $config, $name)
|
||||
{
|
||||
return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a single database connection instance.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Illuminate\Database\Connection
|
||||
*/
|
||||
protected function createSingleConnection(array $config)
|
||||
{
|
||||
$pdo = $this->createPdoResolver($config);
|
||||
|
||||
return $this->createConnection(
|
||||
$config['driver'], $pdo, $config['database'], $config['prefix'], $config
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a read / write database connection instance.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Illuminate\Database\Connection
|
||||
*/
|
||||
protected function createReadWriteConnection(array $config)
|
||||
{
|
||||
$connection = $this->createSingleConnection($this->getWriteConfig($config));
|
||||
|
||||
return $connection->setReadPdo($this->createReadPdo($config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PDO instance for reading.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function createReadPdo(array $config)
|
||||
{
|
||||
return $this->createPdoResolver($this->getReadConfig($config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the read configuration for a read / write connection.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function getReadConfig(array $config)
|
||||
{
|
||||
return $this->mergeReadWriteConfig(
|
||||
$config, $this->getReadWriteConfig($config, 'read')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the write configuration for a read / write connection.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*/
|
||||
protected function getWriteConfig(array $config)
|
||||
{
|
||||
return $this->mergeReadWriteConfig(
|
||||
$config, $this->getReadWriteConfig($config, 'write')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a read / write level configuration.
|
||||
*
|
||||
* @param array $config
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function getReadWriteConfig(array $config, $type)
|
||||
{
|
||||
return isset($config[$type][0])
|
||||
? Arr::random($config[$type])
|
||||
: $config[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge a configuration for a read / write connection.
|
||||
*
|
||||
* @param array $config
|
||||
* @param array $merge
|
||||
* @return array
|
||||
*/
|
||||
protected function mergeReadWriteConfig(array $config, array $merge)
|
||||
{
|
||||
return Arr::except(array_merge($config, $merge), ['read', 'write']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Closure that resolves to a PDO instance.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function createPdoResolver(array $config)
|
||||
{
|
||||
return array_key_exists('host', $config)
|
||||
? $this->createPdoResolverWithHosts($config)
|
||||
: $this->createPdoResolverWithoutHosts($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Closure that resolves to a PDO instance with a specific host or an array of hosts.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Closure
|
||||
*
|
||||
* @throws \PDOException
|
||||
*/
|
||||
protected function createPdoResolverWithHosts(array $config)
|
||||
{
|
||||
return function () use ($config) {
|
||||
foreach (Arr::shuffle($hosts = $this->parseHosts($config)) as $key => $host) {
|
||||
$config['host'] = $host;
|
||||
|
||||
try {
|
||||
return $this->createConnector($config)->connect($config);
|
||||
} catch (PDOException $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
throw $e;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the hosts configuration item into an array.
|
||||
*
|
||||
* @param array $config
|
||||
* @return array
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function parseHosts(array $config)
|
||||
{
|
||||
$hosts = Arr::wrap($config['host']);
|
||||
|
||||
if (empty($hosts)) {
|
||||
throw new InvalidArgumentException('Database hosts array is empty.');
|
||||
}
|
||||
|
||||
return $hosts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Closure that resolves to a PDO instance where there is no configured host.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function createPdoResolverWithoutHosts(array $config)
|
||||
{
|
||||
return function () use ($config) {
|
||||
return $this->createConnector($config)->connect($config);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a connector instance based on the configuration.
|
||||
*
|
||||
* @param array $config
|
||||
* @return \Illuminate\Database\Connectors\ConnectorInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function createConnector(array $config)
|
||||
{
|
||||
if (! isset($config['driver'])) {
|
||||
throw new InvalidArgumentException('A driver must be specified.');
|
||||
}
|
||||
|
||||
if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
|
||||
return $this->container->make($key);
|
||||
}
|
||||
|
||||
switch ($config['driver']) {
|
||||
case 'mysql':
|
||||
return new MySqlConnector;
|
||||
case 'pgsql':
|
||||
return new PostgresConnector;
|
||||
case 'sqlite':
|
||||
return new SQLiteConnector;
|
||||
case 'sqlsrv':
|
||||
return new SqlServerConnector;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Unsupported driver [{$config['driver']}].");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new connection instance.
|
||||
*
|
||||
* @param string $driver
|
||||
* @param \PDO|\Closure $connection
|
||||
* @param string $database
|
||||
* @param string $prefix
|
||||
* @param array $config
|
||||
* @return \Illuminate\Database\Connection
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
|
||||
{
|
||||
if ($resolver = Connection::getResolver($driver)) {
|
||||
return $resolver($connection, $database, $prefix, $config);
|
||||
}
|
||||
|
||||
switch ($driver) {
|
||||
case 'mysql':
|
||||
return new MySqlConnection($connection, $database, $prefix, $config);
|
||||
case 'pgsql':
|
||||
return new PostgresConnection($connection, $database, $prefix, $config);
|
||||
case 'sqlite':
|
||||
return new SQLiteConnection($connection, $database, $prefix, $config);
|
||||
case 'sqlsrv':
|
||||
return new SqlServerConnection($connection, $database, $prefix, $config);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Unsupported driver [{$driver}].");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user