Commit 59a7e47f authored by Taylor Otwell's avatar Taylor Otwell

simplified database connection configuration.

parent 045858d8
...@@ -10,7 +10,9 @@ return array( ...@@ -10,7 +10,9 @@ return array(
| The name of your default database connection. | The name of your default database connection.
| |
| This connection will be the default for all database operations unless a | This connection will be the default for all database operations unless a
| different connection is specified when performing the operation. | different connection is specified when performing the operation. The name
| of the default connection should correspond to the name of a connector
| defined below.
| |
*/ */
...@@ -18,56 +20,62 @@ return array( ...@@ -18,56 +20,62 @@ return array(
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Database Connections | Database Connectors
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| All of the database connections used by your application. | All of the database connectors used by your application.
| |
| Supported Drivers: 'mysql', 'pgsql', 'sqlite'. | Each connector should return a PDO connection. You may connect to any
| database system you wish. Of course, default configurations for the
| systems supported by Laravel are provided for you.
| |
| Note: When using the SQLite driver, the path and "sqlite" extention will | The entire database configuration array is passed to the connector
| be added automatically. You only need to specify the database name. | closure, so you may convenient use it when connecting to your database.
| |
| Using a driver that isn't supported? You can still establish a PDO | Note: When using an unsupported database, Eloquent and the fluent query
| connection. Simply specify a driver and DSN option: | builder may not work as expected. Currently, MySQL, Postgres, and
| | SQLite are fully supported by Laravel.
| 'odbc' => array(
| 'driver' => 'odbc',
| 'dsn' => 'your-dsn',
| 'username' => 'username',
| 'password' => 'password',
| )
|
| Note: When using an unsupported driver, Eloquent and the fluent query
| builder may not work as expected.
| |
*/ */
'connections' => array( 'connectors' => array(
'sqlite' => array( 'sqlite' => function($config)
'driver' => 'sqlite', {
'database' => 'application', return new PDO('sqlite:'.DATABASE_PATH.'application.sqlite', null, null, $config['options']);
), }
'mysql' => array( 'mysql' => function($config)
'driver' => 'mysql', {
'host' => 'localhost', return new PDO('mysql:host=localhost;dbname=database', 'username', 'password', $config['options']);
'database' => 'database', }
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
),
'pgsql' => array( 'pgsql' => array(
'driver' => 'pgsql', return new PDO('pgsql:host=localhost;dbname=database', 'username', 'password', $config['options']);
'host' => 'localhost',
'database' => 'database',
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
), ),
), ),
/*
|--------------------------------------------------------------------------
| Database PDO Options
|--------------------------------------------------------------------------
|
| Here you may specify the PDO options that should be used when connecting
| to a database. The entire database configuration array is passed to the
| database connector closures, so may convenient access these options from
| your connectors.
|
| For a list of options, visit: http://php.net/manual/en/pdo.setattribute.php
|
*/
'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,
),
); );
\ No newline at end of file
...@@ -49,9 +49,7 @@ return array( ...@@ -49,9 +49,7 @@ return array(
'laravel.database' => array('singleton' => true, 'resolver' => function($container) 'laravel.database' => array('singleton' => true, 'resolver' => function($container)
{ {
$config = $container->resolve('laravel.config'); return new Database\Manager($container->resolve('laravel.config')->get('database'));
return new Database\Manager(new Database\Connector\Factory, $config->get('database.connections'), $config->get('database.default'));
}), }),
......
...@@ -5,27 +5,6 @@ use PDOStatement; ...@@ -5,27 +5,6 @@ use PDOStatement;
class Connection { class Connection {
/**
* The database connector instance.
*
* @var Connector\Connector
*/
protected $connector;
/**
* The connection name.
*
* @var string
*/
protected $name;
/**
* The connection configuration.
*
* @var array
*/
protected $config;
/** /**
* The PDO connection. * The PDO connection.
* *
...@@ -41,38 +20,14 @@ class Connection { ...@@ -41,38 +20,14 @@ class Connection {
public $queries = array(); public $queries = array();
/** /**
* Create a new Connection instance. * Create a new database connection instance.
*
* @param Connector\Connector $connector
* @param string $name
* @param array $config
* @return void
*/
public function __construct(Connector\Connector $connector, $name, $config)
{
$this->name = $name;
$this->config = $config;
$this->connector = $connector;
}
/**
* Establish the PDO connection for the connection instance.
* *
* @param PDO $pdo
* @return void * @return void
*/ */
public function connect() public function __construct(PDO $pdo)
{ {
$this->pdo = $this->connector->connect($this->config); $this->pdo = $pdo;
}
/**
* Determine if a PDO connection has been established for the connection.
*
* @return bool
*/
public function connected()
{
return ! is_null($this->pdo);
} }
/** /**
...@@ -141,8 +96,6 @@ class Connection { ...@@ -141,8 +96,6 @@ class Connection {
*/ */
public function query($sql, $bindings = array()) public function query($sql, $bindings = array())
{ {
if ( ! $this->connected()) $this->connect();
$this->queries[] = compact('sql', 'bindings'); $this->queries[] = compact('sql', 'bindings');
return $this->execute($this->pdo->prepare(trim($sql)), $bindings); return $this->execute($this->pdo->prepare(trim($sql)), $bindings);
...@@ -190,32 +143,30 @@ class Connection { ...@@ -190,32 +143,30 @@ class Connection {
switch ($this->driver()) switch ($this->driver())
{ {
case 'pgsql': case 'pgsql':
return new Query\Postgres($this, $this->compiler(), $table); return new Queries\Postgres($this, $this->grammar(), $table);
default: default:
return new Query\Query($this, $this->compiler(), $table); return new Queries\Query($this, $this->grammar(), $table);
} }
} }
/** /**
* Create a new query compiler for the connection. * Create a new query grammar for the connection.
* *
* @return Query\Compiler * @return Queries\Grammars\Grammar
*/ */
protected function compiler() protected function grammar()
{ {
$compiler = (isset($this->config['compiler'])) ? $this->config['compiler'] : $this->driver(); switch ($this->driver())
switch ($compiler)
{ {
case 'mysql': case 'mysql':
return new Query\Compiler\MySQL; return new Queries\Grammars\MySQL;
case 'pgsql': case 'pgsql':
return new Query\Compiler\Postgres; return new Queries\Grammars\Postgres;
default: default:
return new Query\Compiler\Compiler; return new Queries\Grammars\Grammar;
} }
} }
...@@ -226,8 +177,6 @@ class Connection { ...@@ -226,8 +177,6 @@ class Connection {
*/ */
public function driver() public function driver()
{ {
if ( ! $this->connected()) $this->connect();
return $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME); return $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
} }
......
<?php namespace Laravel\Database\Connector;
class Callback extends Connector {
/**
* Establish a PDO database connection.
*
* @param array $config
* @return PDO
*/
public function connect($config)
{
return call_user_func($config['connector']);
}
}
\ No newline at end of file
<?php namespace Laravel\Database\Connector;
use PDO;
abstract class Connector {
/**
* The PDO connection options.
*
* @var array
*/
public $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.
*
* @param array $config
* @return PDO
*/
abstract public function connect($config);
}
\ No newline at end of file
<?php namespace Laravel\Database\Connector;
use PDO;
class MySQL extends Connector {
/**
* Establish a PDO database connection.
*
* @param array $config
* @return PDO
*/
public function connect($config)
{
$dsn = $config['driver'].':host='.$config['host'].';dbname='.$config['database'];
if (isset($config['port']))
{
$dsn .= ';port='.$config['port'];
}
if (isset($config['socket']))
{
$dsn .= ';unix_socket='.$config['socket'];
}
$connection = new PDO($dsn, $config['username'], $config['password'], $this->options);
if (isset($config['charset']))
{
$connection->prepare("SET NAMES '".$config['charset']."'")->execute();
}
return $connection;
}
}
\ No newline at end of file
<?php namespace Laravel\Database\Connector;
use PDO;
class Postgres extends Connector {
/**
* Establish a PDO database connection.
*
* @param array $config
* @return PDO
*/
public function connect($config)
{
$dsn = $config['driver'].':host='.$config['host'].';dbname='.$config['database'];
if (isset($config['port']))
{
$dsn .= ';port='.$config['port'];
}
$connection = new PDO($dsn, $config['username'], $config['password'], $this->options);
if (isset($config['charset']))
{
$connection->prepare("SET NAMES '".$config['charset']."'")->execute();
}
return $connection;
}
}
\ No newline at end of file
<?php namespace Laravel\Database\Connector;
use PDO;
class SQLite extends Connector {
/**
* Establish a PDO database connection.
*
* @param array $config
* @return PDO
*/
public function connect($config)
{
if ($config['database'] == ':memory:')
{
return new PDO('sqlite::memory:', null, null, $this->options);
}
elseif (file_exists($path = DATABASE_PATH.$config['database'].'.sqlite'))
{
return new PDO('sqlite:'.$path, null, null, $this->options);
}
elseif (file_exists($config['database']))
{
return new PDO('sqlite:'.$config['database'], null, null, $this->options);
}
throw new \Exception("SQLite database [".$config['database']."] could not be found.");
}
}
\ No newline at end of file
...@@ -9,45 +9,22 @@ class Manager { ...@@ -9,45 +9,22 @@ class Manager {
*/ */
protected $connections = array(); protected $connections = array();
/**
* The connector factory instance.
*
* @var Connector\Factory
*/
protected $connector;
/**
* The database connection configurations.
*
* @var array
*/
protected $config;
/**
* The default database connection name.
*
* @var string
*/
protected $default;
/** /**
* Create a new database manager instance. * Create a new database manager instance.
* *
* @param Connector\Factory $connector
* @param array $config * @param array $config
* @param string $default
* @return void * @return void
*/ */
public function __construct(Connector\Factory $connector, $config, $default) public function __construct($config)
{ {
$this->config = $config; $this->config = $config;
$this->default = $default;
$this->connector = $connector;
} }
/** /**
* Get a database connection. If no database name is specified, the default * Get a database connection.
* connection will be returned as defined in the database configuration file. *
* If no database name is specified, the default connection will be returned as
* defined in the database configuration file.
* *
* Note: Database connections are managed as singletons. * Note: Database connections are managed as singletons.
* *
...@@ -64,48 +41,25 @@ class Manager { ...@@ -64,48 +41,25 @@ class Manager {
*/ */
public function connection($connection = null) public function connection($connection = null)
{ {
if (is_null($connection)) $connection = $this->default; if (is_null($connection)) $connection = $this->config['default'];
if ( ! array_key_exists($connection, $this->connections)) if ( ! array_key_exists($connection, $this->connections))
{ {
if ( ! isset($this->config[$connection])) if ( ! isset($this->config['connectors'][$connection]))
{ {
throw new \Exception("Database connection [$connection] is not defined."); throw new \Exception("Database connection configuration is not defined for connection [$connection].");
} }
$config = $this->config[$connection]; // Database connections are established by developer configurable connector closures.
// This provides the developer the maximum amount of freedom in establishing their
$this->connections[$connection] = new Connection($this->connector($config), $connection, $config); // database connections, and allows the framework to remain agonstic to ugly database
// specific PDO connection details. Less code. Less bugs.
$this->connections[$connection] = new Connection(call_user_func($this->config['connectors'][$connection], $this->config));
} }
return $this->connections[$connection]; return $this->connections[$connection];
} }
/**
* Create a new database connector instance base on a connection configuration.
*
* @param array $config
* @return Connector\Connector
*/
protected function connector($config)
{
if (isset($config['connector'])) return new Connector\Callback;
switch ($config['driver'])
{
case 'sqlite':
return new Connector\SQLite;
case 'mysql':
return new Connector\MySQL;
case 'pgsql':
return new Connector\Postgres;
}
throw new \Exception("Database configuration is invalid. Please verify your configuration.");
}
/** /**
* Begin a fluent query against a table. * Begin a fluent query against a table.
* *
...@@ -119,7 +73,7 @@ class Manager { ...@@ -119,7 +73,7 @@ class Manager {
* *
* @param string $table * @param string $table
* @param string $connection * @param string $connection
* @return Database\Query * @return Queries\Query
*/ */
public function table($table, $connection = null) public function table($table, $connection = null)
{ {
......
<?php namespace Laravel\Database\Query\Compiler; <?php namespace Laravel\Database\Query\Grammars;
use Laravel\Database\Query; use Laravel\Database\Queries\Query;
class Compiler { class Grammar {
/** /**
* Compile a SQL SELECT statment from a Query instance. * Compile a SQL SELECT statment from a Query instance.
......
<?php namespace Laravel\Database\Query\Compiler; <?php namespace Laravel\Database\Query\Grammars;
class MySQL extends Compiler { class MySQL extends Grammar {
/** /**
* Get the keyword identifier wrapper for the connection. * Get the keyword identifier wrapper for the connection.
......
<?php namespace Laravel\Database\Query\Compiler; <?php namespace Laravel\Database\Query\Grammars;
class Postgres extends Compiler { use Laravel\Database\Queries\Query;
class Postgres extends Grammar {
/** /**
* Compile a SQL INSERT statment that returns an auto-incrementing ID from a Query instance. * Compile a SQL INSERT statment that returns an auto-incrementing ID from a Query instance.
......
<?php namespace Laravel\Database\Query; <?php namespace Laravel\Database\Queries;
use PDO; use PDO;
...@@ -12,7 +12,7 @@ class Postgres extends Query { ...@@ -12,7 +12,7 @@ class Postgres extends Query {
*/ */
public function insert_get_id($values) public function insert_get_id($values)
{ {
$query = $this->connection->pdo->prepare($this->compiler->insert_get_id($this, $values)); $query = $this->connection->pdo->prepare($this->grammar->insert_get_id($this, $values));
$query->execute(array_values($values)); $query->execute(array_values($values));
......
<?php namespace Laravel\Database\Query; <?php namespace Laravel\Database\Queries;
use Laravel\Database\Connection; use Laravel\Database\Connection;
...@@ -12,11 +12,11 @@ class Query { ...@@ -12,11 +12,11 @@ class Query {
public $connection; public $connection;
/** /**
* The query compiler instance. * The query grammar instance.
* *
* @var Compiler\Compiler * @var Grammars\Grammar
*/ */
public $compiler; public $grammar;
/** /**
* The SELECT clause. * The SELECT clause.
...@@ -93,14 +93,14 @@ class Query { ...@@ -93,14 +93,14 @@ class Query {
* Create a new query instance. * Create a new query instance.
* *
* @param Database\Connection $connection * @param Database\Connection $connection
* @param Compiler\Compiler $compiler * @param Grammars\Grammar $grammar
* @param string $table * @param string $table
* @return void * @return void
*/ */
public function __construct(Connection $connection, Compiler\Compiler $compiler, $table) public function __construct(Connection $connection, Grammars\Grammar $grammar, $table)
{ {
$this->table = $table; $this->table = $table;
$this->compiler = $compiler; $this->grammar = $grammar;
$this->connection = $connection; $this->connection = $connection;
} }
...@@ -551,7 +551,7 @@ class Query { ...@@ -551,7 +551,7 @@ class Query {
{ {
$this->aggregate = compact('aggregator', 'column'); $this->aggregate = compact('aggregator', 'column');
$result = $this->connection->scalar($this->compiler->select($this), $this->bindings); $result = $this->connection->scalar($this->grammar->select($this), $this->bindings);
// Reset the SELECT clause so more queries can be performed using the same instance. // Reset the SELECT clause so more queries can be performed using the same instance.
// This is helpful for getting aggregates and then getting actual results. // This is helpful for getting aggregates and then getting actual results.
...@@ -581,7 +581,7 @@ class Query { ...@@ -581,7 +581,7 @@ class Query {
{ {
if (is_null($this->select)) $this->select($columns); if (is_null($this->select)) $this->select($columns);
$results = $this->connection->query($this->compiler->select($this), $this->bindings); $results = $this->connection->query($this->grammar->select($this), $this->bindings);
// Reset the SELECT clause so more queries can be performed using the same instance. // Reset the SELECT clause so more queries can be performed using the same instance.
// This is helpful for getting aggregates and then getting actual results. // This is helpful for getting aggregates and then getting actual results.
...@@ -603,7 +603,7 @@ class Query { ...@@ -603,7 +603,7 @@ class Query {
*/ */
public function insert($values) public function insert($values)
{ {
return $this->connection->query($this->compiler->insert($this, $values), array_values($values)); return $this->connection->query($this->grammar->insert($this, $values), array_values($values));
} }
/** /**
...@@ -619,7 +619,7 @@ class Query { ...@@ -619,7 +619,7 @@ class Query {
*/ */
public function insert_get_id($values) public function insert_get_id($values)
{ {
$this->connection->query($this->compiler->insert($this, $values), array_values($values)); $this->connection->query($this->grammar->insert($this, $values), array_values($values));
return (int) $this->connection->pdo->lastInsertId(); return (int) $this->connection->pdo->lastInsertId();
} }
...@@ -637,7 +637,7 @@ class Query { ...@@ -637,7 +637,7 @@ class Query {
*/ */
public function update($values) public function update($values)
{ {
return $this->connection->query($this->compiler->update($this, $values), array_merge(array_values($values), $this->bindings)); return $this->connection->query($this->grammar->update($this, $values), array_merge(array_values($values), $this->bindings));
} }
/** /**
...@@ -663,7 +663,7 @@ class Query { ...@@ -663,7 +663,7 @@ class Query {
{ {
if ( ! is_null($id)) $this->where('id', '=', $id); if ( ! is_null($id)) $this->where('id', '=', $id);
return $this->connection->query($this->compiler->delete($this), $this->bindings); return $this->connection->query($this->grammar->delete($this), $this->bindings);
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment