From 59a7e47f822a71a13a31f8e6ed131da38c42f548 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 12 Sep 2011 23:14:24 -0500 Subject: [PATCH] simplified database connection configuration. --- application/config/database.php | 82 ++++++++++--------- laravel/config/container.php | 4 +- laravel/database/connection.php | 77 +++-------------- laravel/database/connector/callback.php | 16 ---- laravel/database/connector/connector.php | 28 ------- laravel/database/connector/mysql.php | 37 --------- laravel/database/connector/postgres.php | 32 -------- laravel/database/connector/sqlite.php | 31 ------- laravel/database/manager.php | 76 ++++------------- .../grammars/grammar.php} | 6 +- .../compiler => queries/grammars}/mysql.php | 4 +- .../grammars}/postgres.php | 6 +- .../database/{query => queries}/postgres.php | 4 +- laravel/database/{query => queries}/query.php | 26 +++--- 14 files changed, 98 insertions(+), 331 deletions(-) delete mode 100644 laravel/database/connector/callback.php delete mode 100644 laravel/database/connector/connector.php delete mode 100644 laravel/database/connector/mysql.php delete mode 100644 laravel/database/connector/postgres.php delete mode 100644 laravel/database/connector/sqlite.php rename laravel/database/{query/compiler/compiler.php => queries/grammars/grammar.php} (98%) rename laravel/database/{query/compiler => queries/grammars}/mysql.php (63%) rename laravel/database/{query/compiler => queries/grammars}/postgres.php (72%) rename laravel/database/{query => queries}/postgres.php (72%) rename laravel/database/{query => queries}/query.php (94%) diff --git a/application/config/database.php b/application/config/database.php index d8109118..2d0ca6cb 100644 --- a/application/config/database.php +++ b/application/config/database.php @@ -10,7 +10,9 @@ | The name of your default database connection. | | 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 @@ /* |-------------------------------------------------------------------------- - | 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 - | be added automatically. You only need to specify the database name. + | The entire database configuration array is passed to the connector + | 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 - | connection. Simply specify a driver and DSN option: - | - | '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. + | Note: When using an unsupported database, Eloquent and the fluent query + | builder may not work as expected. Currently, MySQL, Postgres, and + | SQLite are fully supported by Laravel. | */ - 'connections' => array( + 'connectors' => array( - 'sqlite' => array( - 'driver' => 'sqlite', - 'database' => 'application', - ), + 'sqlite' => function($config) + { + return new PDO('sqlite:'.DATABASE_PATH.'application.sqlite', null, null, $config['options']); + } - 'mysql' => array( - 'driver' => 'mysql', - 'host' => 'localhost', - 'database' => 'database', - 'username' => 'root', - 'password' => 'password', - 'charset' => 'utf8', - ), + 'mysql' => function($config) + { + return new PDO('mysql:host=localhost;dbname=database', 'username', 'password', $config['options']); + } 'pgsql' => array( - 'driver' => 'pgsql', - 'host' => 'localhost', - 'database' => 'database', - 'username' => 'root', - 'password' => 'password', - 'charset' => 'utf8', + return new PDO('pgsql:host=localhost;dbname=database', 'username', 'password', $config['options']); ), ), + /* + |-------------------------------------------------------------------------- + | 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 diff --git a/laravel/config/container.php b/laravel/config/container.php index 27f3e6c5..c3c6f46f 100644 --- a/laravel/config/container.php +++ b/laravel/config/container.php @@ -49,9 +49,7 @@ 'laravel.database' => array('singleton' => true, 'resolver' => function($container) { - $config = $container->resolve('laravel.config'); - - return new Database\Manager(new Database\Connector\Factory, $config->get('database.connections'), $config->get('database.default')); + return new Database\Manager($container->resolve('laravel.config')->get('database')); }), diff --git a/laravel/database/connection.php b/laravel/database/connection.php index c0aec562..3f501635 100644 --- a/laravel/database/connection.php +++ b/laravel/database/connection.php @@ -5,27 +5,6 @@ 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. * @@ -41,38 +20,14 @@ class Connection { public $queries = array(); /** - * Create a new Connection instance. + * Create a new database connection instance. * - * @param Connector\Connector $connector - * @param string $name - * @param array $config + * @param PDO $pdo * @return void */ - public function __construct(Connector\Connector $connector, $name, $config) + public function __construct(PDO $pdo) { - $this->name = $name; - $this->config = $config; - $this->connector = $connector; - } - - /** - * Establish the PDO connection for the connection instance. - * - * @return void - */ - public function connect() - { - $this->pdo = $this->connector->connect($this->config); - } - - /** - * Determine if a PDO connection has been established for the connection. - * - * @return bool - */ - public function connected() - { - return ! is_null($this->pdo); + $this->pdo = $pdo; } /** @@ -141,8 +96,6 @@ public function first($sql, $bindings = array()) */ public function query($sql, $bindings = array()) { - if ( ! $this->connected()) $this->connect(); - $this->queries[] = compact('sql', 'bindings'); return $this->execute($this->pdo->prepare(trim($sql)), $bindings); @@ -190,32 +143,30 @@ public function table($table) switch ($this->driver()) { case 'pgsql': - return new Query\Postgres($this, $this->compiler(), $table); + return new Queries\Postgres($this, $this->grammar(), $table); 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 ($compiler) + switch ($this->driver()) { case 'mysql': - return new Query\Compiler\MySQL; + return new Queries\Grammars\MySQL; case 'pgsql': - return new Query\Compiler\Postgres; + return new Queries\Grammars\Postgres; default: - return new Query\Compiler\Compiler; + return new Queries\Grammars\Grammar; } } @@ -226,8 +177,6 @@ protected function compiler() */ public function driver() { - if ( ! $this->connected()) $this->connect(); - return $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME); } diff --git a/laravel/database/connector/callback.php b/laravel/database/connector/callback.php deleted file mode 100644 index 860a8cfc..00000000 --- a/laravel/database/connector/callback.php +++ /dev/null @@ -1,16 +0,0 @@ - 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 diff --git a/laravel/database/connector/mysql.php b/laravel/database/connector/mysql.php deleted file mode 100644 index 929769a5..00000000 --- a/laravel/database/connector/mysql.php +++ /dev/null @@ -1,37 +0,0 @@ -options); - - if (isset($config['charset'])) - { - $connection->prepare("SET NAMES '".$config['charset']."'")->execute(); - } - - return $connection; - } - -} \ No newline at end of file diff --git a/laravel/database/connector/postgres.php b/laravel/database/connector/postgres.php deleted file mode 100644 index 0ec4db1c..00000000 --- a/laravel/database/connector/postgres.php +++ /dev/null @@ -1,32 +0,0 @@ -options); - - if (isset($config['charset'])) - { - $connection->prepare("SET NAMES '".$config['charset']."'")->execute(); - } - - return $connection; - } - -} \ No newline at end of file diff --git a/laravel/database/connector/sqlite.php b/laravel/database/connector/sqlite.php deleted file mode 100644 index 8c6d7015..00000000 --- a/laravel/database/connector/sqlite.php +++ /dev/null @@ -1,31 +0,0 @@ -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 diff --git a/laravel/database/manager.php b/laravel/database/manager.php index 2937fb3b..0707befd 100644 --- a/laravel/database/manager.php +++ b/laravel/database/manager.php @@ -9,45 +9,22 @@ class Manager { */ 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. * - * @param Connector\Factory $connector - * @param array $config - * @param string $default + * @param array $config * @return void */ - public function __construct(Connector\Factory $connector, $config, $default) + public function __construct($config) { $this->config = $config; - $this->default = $default; - $this->connector = $connector; } /** - * Get a database connection. If no database name is specified, the default - * connection will be returned as defined in the database configuration file. + * Get a database connection. + * + * 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. * @@ -64,48 +41,25 @@ public function __construct(Connector\Factory $connector, $config, $default) */ 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 ( ! 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]; - - $this->connections[$connection] = new Connection($this->connector($config), $connection, $config); + // Database connections are established by developer configurable connector closures. + // 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. + $this->connections[$connection] = new Connection(call_user_func($this->config['connectors'][$connection], $this->config)); } 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. * @@ -119,7 +73,7 @@ protected function connector($config) * * @param string $table * @param string $connection - * @return Database\Query + * @return Queries\Query */ public function table($table, $connection = null) { diff --git a/laravel/database/query/compiler/compiler.php b/laravel/database/queries/grammars/grammar.php similarity index 98% rename from laravel/database/query/compiler/compiler.php rename to laravel/database/queries/grammars/grammar.php index a0efe929..9de7eece 100644 --- a/laravel/database/query/compiler/compiler.php +++ b/laravel/database/queries/grammars/grammar.php @@ -1,8 +1,8 @@ -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)); diff --git a/laravel/database/query/query.php b/laravel/database/queries/query.php similarity index 94% rename from laravel/database/query/query.php rename to laravel/database/queries/query.php index 0641781a..73e25969 100644 --- a/laravel/database/query/query.php +++ b/laravel/database/queries/query.php @@ -1,4 +1,4 @@ -table = $table; - $this->compiler = $compiler; + $this->grammar = $grammar; $this->connection = $connection; } @@ -551,7 +551,7 @@ private function aggregate($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. // This is helpful for getting aggregates and then getting actual results. @@ -581,7 +581,7 @@ public function get($columns = array('*')) { 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. // This is helpful for getting aggregates and then getting actual results. @@ -603,7 +603,7 @@ public function get($columns = array('*')) */ 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 @@ public function insert($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(); } @@ -637,7 +637,7 @@ public function insert_get_id($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 @@ public function delete($id = null) { 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); } /**