added database connectors and cleaned up configuration.
This commit is contained in:
parent
5387312e0d
commit
cb5a426cba
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
'laravel.database' => array('singleton' => true, 'resolver' => function($container)
|
'laravel.database' => array('singleton' => true, 'resolver' => function($container)
|
||||||
{
|
{
|
||||||
return new Database\Manager($container->resolve('laravel.config')->get('database'));
|
return new Database\Manager($container->resolve('laravel.config'));
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,13 @@
|
||||||
|
|
||||||
class Connection {
|
class Connection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection configuration array.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The PDO connection.
|
* The PDO connection.
|
||||||
*
|
*
|
||||||
|
@ -22,12 +29,14 @@ class Connection {
|
||||||
/**
|
/**
|
||||||
* Create a new database connection instance.
|
* Create a new database connection instance.
|
||||||
*
|
*
|
||||||
* @param PDO $pdo
|
* @param PDO $pdo
|
||||||
|
* @param array $config
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(PDO $pdo)
|
public function __construct(PDO $pdo, $config)
|
||||||
{
|
{
|
||||||
$this->pdo = $pdo;
|
$this->pdo = $pdo;
|
||||||
|
$this->config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,18 +123,15 @@ public function table($table)
|
||||||
/**
|
/**
|
||||||
* Create a new query grammar for the connection.
|
* Create a new query grammar for the connection.
|
||||||
*
|
*
|
||||||
* @return Queries\Grammars\Grammar
|
* @return Grammars\Grammar
|
||||||
*/
|
*/
|
||||||
protected function grammar()
|
protected function grammar()
|
||||||
{
|
{
|
||||||
switch ($this->driver())
|
switch (isset($this->config['grammar']) ? $this->config['grammar'] : $this->driver())
|
||||||
{
|
{
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
return new Grammars\MySQL;
|
return new Grammars\MySQL;
|
||||||
|
|
||||||
case 'pgsql':
|
|
||||||
return new Grammars\Postgres;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new Grammars\Grammar;
|
return new Grammars\Grammar;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php namespace Laravel\Database\Connectors; use PDO;
|
||||||
|
|
||||||
|
abstract class Connector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PDO connection options.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $options = array(
|
||||||
|
PDO::ATTR_CASE => PDO::CASE_LOWER,
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
|
||||||
|
PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||||
|
PDO::ATTR_EMULATE_PREPARES => false,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish a PDO database connection for a given database configuration.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return PDO
|
||||||
|
*/
|
||||||
|
abstract public function connect($config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the PDO connection options for a given database configuration.
|
||||||
|
*
|
||||||
|
* Developer specified options will override the default connection options.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function options($config)
|
||||||
|
{
|
||||||
|
$options = (isset($config['options'])) ? $config['options'] : array();
|
||||||
|
|
||||||
|
return array_merge($this->options, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php namespace Laravel\Database\Connectors; use PDO;
|
||||||
|
|
||||||
|
class MySQL extends Connector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish a PDO database connection for a given database configuration.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return PDO
|
||||||
|
*/
|
||||||
|
public function connect($config)
|
||||||
|
{
|
||||||
|
$connection = new PDO($this->dsn($config), $config['username'], $config['password'], $this->options($config));
|
||||||
|
|
||||||
|
if (isset($config['charset']))
|
||||||
|
{
|
||||||
|
$connection->prepare("SET NAMES '{$config['charset']}'")->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the DSN connection string for a MySQL connection.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function dsn($config)
|
||||||
|
{
|
||||||
|
// Format the initial MySQL PDO connection string. These options are required
|
||||||
|
// for every MySQL connection that is established. The connection strings
|
||||||
|
// have the following convention: "mysql:host=hostname;dbname=database"
|
||||||
|
$dsn = sprintf('%s:host=%s;dbname=%s', $config['driver'], $config['host'], $config['database']);
|
||||||
|
|
||||||
|
// Check for any optional MySQL PDO options. These options are not required
|
||||||
|
// to establish a PDO connection; however, may be needed in certain server
|
||||||
|
// or hosting environments used by the developer.
|
||||||
|
foreach (array('port', 'unix_socket') as $key => $value)
|
||||||
|
{
|
||||||
|
if (isset($config[$key])) $dsn .= ";{$key}={$value}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dsn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php namespace Laravel\Database\Connectors; use PDO;
|
||||||
|
|
||||||
|
class Postgres extends Connector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish a PDO database connection for a given database configuration.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return PDO
|
||||||
|
*/
|
||||||
|
public function connect($config)
|
||||||
|
{
|
||||||
|
$connection = new PDO($this->dsn($config), $config['username'], $config['password'], $this->options($config));
|
||||||
|
|
||||||
|
if (isset($config['charset']))
|
||||||
|
{
|
||||||
|
$connection->prepare("SET NAMES '{$config['charset']}'")->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the DSN connection string for a Postgres connection.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function dsn($config)
|
||||||
|
{
|
||||||
|
// Format the initial Postgres PDO connection string. These options are required
|
||||||
|
// for every Postgres connection that is established. The connection strings
|
||||||
|
// have the following convention: "pgsql:host=hostname;dbname=database"
|
||||||
|
$dsn = sprintf('%s:host=%s;dbname=%s', $config['driver'], $config['host'], $config['database']);
|
||||||
|
|
||||||
|
// Check for any optional Postgres PDO options. These options are not required
|
||||||
|
// to establish a PDO connection; however, may be needed in certain server
|
||||||
|
// or hosting environments used by the developer.
|
||||||
|
foreach (array('port', 'unix_socket') as $key => $value)
|
||||||
|
{
|
||||||
|
if (isset($config[$key])) $dsn .= ";{$key}={$value}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dsn;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php namespace Laravel\Database\Connectors; use PDO;
|
||||||
|
|
||||||
|
class SQLite extends Connector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish a PDO database connection for a given database configuration.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return PDO
|
||||||
|
*/
|
||||||
|
public function connect($config)
|
||||||
|
{
|
||||||
|
$options = $this->options($config);
|
||||||
|
|
||||||
|
if ($config['database'] == ':memory:')
|
||||||
|
{
|
||||||
|
return new PDO('sqlite::memory:', null, null, $options);
|
||||||
|
}
|
||||||
|
elseif (file_exists($path = DATABASE_PATH.$config['database'].'.sqlite'))
|
||||||
|
{
|
||||||
|
return new PDO('sqlite:'.$path, null, null, $options);
|
||||||
|
}
|
||||||
|
elseif (file_exists($config['database']))
|
||||||
|
{
|
||||||
|
return new PDO('sqlite:'.$config['database'], null, null, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \Exception("SQLite database [{$config['database']}] could not be found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
<?php namespace Laravel\Database;
|
<?php namespace Laravel\Database;
|
||||||
|
|
||||||
|
use Laravel\Config;
|
||||||
|
|
||||||
class Manager {
|
class Manager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,13 +11,20 @@ class Manager {
|
||||||
*/
|
*/
|
||||||
protected $connections = array();
|
protected $connections = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The configuration manager instance.
|
||||||
|
*
|
||||||
|
* @var Config
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new database manager instance.
|
* Create a new database manager instance.
|
||||||
*
|
*
|
||||||
* @param array $config
|
* @param Connector $connector
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct($config)
|
public function __construct(Config $config)
|
||||||
{
|
{
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
}
|
}
|
||||||
|
@ -32,27 +41,54 @@ public function __construct($config)
|
||||||
*/
|
*/
|
||||||
public function connection($connection = null)
|
public function connection($connection = null)
|
||||||
{
|
{
|
||||||
if (is_null($connection)) $connection = $this->config['default'];
|
if (is_null($connection)) $connection = $this->config->get('database.default');
|
||||||
|
|
||||||
if ( ! array_key_exists($connection, $this->connections))
|
if ( ! array_key_exists($connection, $this->connections))
|
||||||
{
|
{
|
||||||
if ( ! isset($this->config['connectors'][$connection]))
|
$config = $this->config->get("database.connections.{$connection}");
|
||||||
|
|
||||||
|
if (is_null($config))
|
||||||
{
|
{
|
||||||
throw new \Exception("Database connection configuration is not defined for connection [$connection].");
|
throw new \Exception("Database connection configuration is not defined for connection [$connection].");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Database connections are established by developer configurable connector closures.
|
$this->connections[$connection] = new Connection($this->connect($config), $config);
|
||||||
// This provides the developer the maximum amount of freedom in establishing their
|
|
||||||
// database connections, and allows the framework to remain agonstic to ugly database
|
|
||||||
// specific PDO connection details. Less code. Less bugs.
|
|
||||||
$pdo = call_user_func($this->config['connectors'][$connection], $this->config);
|
|
||||||
|
|
||||||
$this->connections[$connection] = new Connection($pdo, $this->config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->connections[$connection];
|
return $this->connections[$connection];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a PDO database connection for a given database configuration.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return PDO
|
||||||
|
*/
|
||||||
|
protected function connect($config)
|
||||||
|
{
|
||||||
|
if (isset($config['connector'])) { return call_user_func($config['connector'], $config); }
|
||||||
|
|
||||||
|
switch ($config['driver'])
|
||||||
|
{
|
||||||
|
case 'sqlite':
|
||||||
|
$connector = new Connectors\SQLite;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'mysql':
|
||||||
|
$connector = new Connectors\MySQL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'pgsql':
|
||||||
|
$connector = new Connectors\Postgres;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new \Exception("Database driver [{$config['driver']}] is not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $connector->connect($config);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begin a fluent query against a table.
|
* Begin a fluent query against a table.
|
||||||
*
|
*
|
||||||
|
|
|
@ -122,7 +122,7 @@ public function distinct()
|
||||||
*/
|
*/
|
||||||
public function select($columns = array('*'))
|
public function select($columns = array('*'))
|
||||||
{
|
{
|
||||||
$this->select = $columns;
|
$this->select = (array) $columns;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -478,12 +478,25 @@ private function aggregate($aggregator, $column)
|
||||||
/**
|
/**
|
||||||
* Execute the query as a SELECT statement and return the first result.
|
* Execute the query as a SELECT statement and return the first result.
|
||||||
*
|
*
|
||||||
* @param array $columns
|
* If a single column is selected from the database, only the value of that column will be returned.
|
||||||
* @return stdClass
|
*
|
||||||
|
* @param array $columns
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function first($columns = array('*'))
|
public function first($columns = array('*'))
|
||||||
{
|
{
|
||||||
return (count($results = $this->take(1)->get($columns)) > 0) ? $results[0] : null;
|
$columns = (array) $columns;
|
||||||
|
|
||||||
|
$results = (count($results = $this->take(1)->get($columns)) > 0) ? $results[0] : null;
|
||||||
|
|
||||||
|
// If we have results and only a single column was selected from the database,
|
||||||
|
// we will simply return the value of that column for convenience.
|
||||||
|
if ( ! is_null($results) and count($columns) == 1 and $columns[0] !== '*')
|
||||||
|
{
|
||||||
|
return $results->{$columns[0]};
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue