src/DataLayer/Database/Connection.php
<?php
namespace Automatorm\DataLayer\Database;
use Automatorm\Exception as Ex;
use Automatorm\DataLayer\Database\DataAccess;
use Automatorm\DataLayer\Database\SchemaGenerator;
use Automatorm\Interfaces\DataAccess as DataAccessInterface;
use Automatorm\Interfaces\SchemaGenerator as SchemaGeneratorInterface;
use Automatorm\Interfaces\Connection as ConnectionInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use PDO;
use PDOException;
class Connection implements ConnectionInterface
{
use LoggerAwareTrait;
public function getLogger()
{
return $this->logger;
}
/************************
* CONNECTION FUNCTIONS *
************************/
public static function register(array $db, LoggerInterface $logger = null, array $options = [])
{
return new static($db, $options, $logger);
}
public static function registerPDO(PDO $pdo, LoggerInterface $logger = null)
{
return new static($pdo, [], $logger);
}
public function __get($var)
{
if (property_exists($this, $var)) {
return $this->{$var};
}
return null;
}
protected $type;
protected $user;
protected $pass;
protected $server;
protected $database;
protected $options;
protected $unix_socket;
protected $connection;
protected $schemaGenerator;
protected $dataAccess;
protected function __construct($details, array $options = [], LoggerInterface $logger = null)
{
$this->schemaGenerator = new SchemaGenerator($this);
$this->dataAccess = new DataAccess($this);
$this->logger = $logger;
$options = $options + [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
];
if ($details instanceof PDO) {
$this->connection = $details;
} elseif (is_array($details)) {
$this->unix_socket = array_key_exists('unix_socket', $details) ? $details['unix_socket'] : null;
$this->server = array_key_exists('server', $details) ? $details['server'] : null;
$this->user = $details['user'];
$this->pass = $details['pass'];
$this->database = $details['database'];
$this->options = $options;
$this->type = array_key_exists('type', $details) ? $details['type'] : 'mysql';
if ($this->unix_socket && $this->server) {
throw new Ex\Database("Must use server OR unix_socket - both supplied", $details);
}
} else {
throw new Ex\Database("Not enough details to construct Database object", $details);
}
}
/**
* Clear connection.
* A call to connect() after this call will return a new PDO instance.
*
* @return null
*/
public function disconnect()
{
unset($this->connection);
}
/**
* Return a PDO instance based on the supplied connection details.
* This object should always return the same PDO instance until ->disconnect() is called.
*
* @return PDO Instance of PDO connection
*/
public function connect()
{
if ($this->connection) {
return $this->connection;
}
if ($this->unix_socket) {
$dsn = $this->type . ':unix_socket=' . $this->unix_socket . ';dbname=' . $this->database.';charset=utf8';
} else {
$dsn = $this->type . ':host=' . $this->server . ';dbname=' . $this->database.';charset=utf8';
}
try {
$this->connection = new PDO($dsn, $this->user, $this->pass, $this->options);
return $this->connection;
} catch (PDOException $e) {
unset($this->connection);
throw new Ex\Database("Database connection failed ({$dsn})", $this, $e);
}
}
public function getDataAccessor() : DataAccessInterface
{
return $this->dataAccess;
}
public function getSchemaGenerator() : SchemaGeneratorInterface
{
return $this->schemaGenerator;
}
public function __sleep()
{
return [
'type',
'user',
'pass',
'server',
'database',
'options',
'unix_socket'
];
}
public function __wakeup()
{
if (!$this->server) {
throw new \Exception('Cannot unserialise a Connection that does not contain a server address');
}
$this->schemaGenerator = new SchemaGenerator($this);
$this->dataAccess = new DataAccess($this);
}
}