Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
10.00% covered (danger)
10.00%
1 / 10
CRAP
19.44% covered (danger)
19.44%
7 / 36
ConnectionFactory
0.00% covered (danger)
0.00%
0 / 1
10.00% covered (danger)
10.00%
1 / 10
207.71
19.44% covered (danger)
19.44%
7 / 36
 addConnection
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 getConnection
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getInstance
0.00% covered (danger)
0.00%
0 / 1
2.15
66.67% covered (warning)
66.67%
2 / 3
 reset
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 __construct
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 3
 _getConnection
0.00% covered (danger)
0.00%
0 / 1
5.67
33.33% covered (danger)
33.33%
2 / 6
 getDefaultConnection
0.00% covered (danger)
0.00%
0 / 1
2.15
66.67% covered (warning)
66.67%
2 / 3
 _addConnection
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 9
 _getDriver
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 4
 instantiateDriver
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 4
<?php
declare(strict_types = 1);
namespace Siesta\Database;
use Siesta\Database\Exception\ConnectException;
use Siesta\Exception\InvalidConfigurationException;
use Siesta\Util\ArrayUtil;
/**
 * @author Gregor Müller
 */
class ConnectionFactory
{
    const EXCEPTION_NO_DEFAULT = "No default connection available";
    const EXCEPTION_NOT_CONFIGURED = "Connection with name %s is not configured";
    const EXCEPTION_DRIVER_NOT_IMPLEMENTD = "Driver for %s is not implemented";
    /**
     * @var ConnectionFactory
     */
    private static $connectionFactory;
    /**
     * @param ConnectionData $connectionData
     *
     * @throws ConnectException
     * @throws InvalidConfigurationException
     * @return Connection
     */
    public static function addConnection(ConnectionData $connectionData) : Connection
    {
        return self::getInstance()->_addConnection($connectionData);
    }
    /**
     * @param null $name
     *
     * @return Connection
     * @throws InvalidConfigurationException
     */
    public static function getConnection($name = null) : Connection
    {
        return self::getInstance()->_getConnection($name);
    }
    /**
     * @return ConnectionFactory
     */
    public static function getInstance() : ConnectionFactory
    {
        if (!self::$connectionFactory) {
            self::$connectionFactory = new static();
        }
        return self::$connectionFactory;
    }
    /**
     *
     */
    public static function reset()
    {
        self::$connectionFactory = null;
    }
    /**
     * @var Driver[]
     */
    protected $driverList;
    /**
     * @var Connection[]
     */
    protected $connectionList;
    /**
     * @var Connection
     */
    protected $defaultConnection;
    /**
     *
     */
    private function __construct()
    {
        $this->driverList = [];
        $this->connectionList = [];
    }
    /**
     * @param $name
     *
     * @return Connection
     * @throws InvalidConfigurationException
     */
    protected function _getConnection($name = null)
    {
        if ($name === null) {
            return $this->getDefaultConnection();
        }
        $connection = ArrayUtil::getFromArray($this->connectionList, $name);
        if ($connection === null) {
            throw new InvalidConfigurationException(sprintf(self::EXCEPTION_NOT_CONFIGURED, $name));
        }
        return $connection;
    }
    /**
     * @return Connection
     * @throws InvalidConfigurationException
     */
    protected function getDefaultConnection() : Connection
    {
        if ($this->defaultConnection === null) {
            throw new InvalidConfigurationException(self::EXCEPTION_NO_DEFAULT);
        }
        return $this->defaultConnection;
    }
    /**
     * @param ConnectionData $connectionData
     *
     * @throws ConnectException
     * @throws InvalidConfigurationException
     * @return Connection
     */
    protected function _addConnection(ConnectionData $connectionData) : Connection
    {
        $connection = ArrayUtil::getFromArray($this->connectionList, $connectionData->name);
        if ($connection !== null) {
            return $connection;
        }
        $driver = $this->_getDriver($connectionData);
        $connection = $driver->connect($connectionData);
        $this->connectionList[$connectionData->name] = $connection;
        if ($this->defaultConnection === null or $connectionData->isDefault) {
            $this->defaultConnection = $connection;
        }
        return $connection;
    }
    /**
     * @param ConnectionData $connectionData
     *
     * @return Driver
     * @throws InvalidConfigurationException
     */
    protected function _getDriver(ConnectionData $connectionData) : Driver
    {
        $driver = ArrayUtil::getFromArray($this->driverList, $connectionData->database);
        if ($driver === null) {
            $this->driverList[$connectionData->database] = $this->instantiateDriver($connectionData);
        }
        return $this->driverList[$connectionData->database];
    }
    /**
     * @param ConnectionData $connectionData
     *
     * @return Driver
     * @throws InvalidConfigurationException
     */
    protected function instantiateDriver(ConnectionData $connectionData) : Driver
    {
        $class = $connectionData->driver;
        if (!class_exists($class)) {
            throw new InvalidConfigurationException(sprintf(self::EXCEPTION_DRIVER_NOT_IMPLEMENTD, $connectionData->driver));
        }
        return new $class;
    }
}