Breakout Query function into its own class

This commit is contained in:
Timothy Warren 2014-03-31 12:47:07 -04:00
parent 955dc78913
commit 7cf3c436dd
3 changed files with 247 additions and 135 deletions

View File

@ -0,0 +1,241 @@
<?php
/**
* Query
*
* Free Query Builder / Database Abstraction Layer
*
* @package Query
* @author Timothy J. Warren
* @copyright Copyright (c) 2012 - 2014
* @link https://github.com/aviat4ion/Query
* @license http://philsturgeon.co.uk/code/dbad-license
*/
// --------------------------------------------------------------------------
/**
* Generic exception for bad drivers
*
* @package Query
* @subpackage Query
*/
class BadDBDriverException extends InvalidArgumentException {}
// --------------------------------------------------------------------------
/**
* Connection manager class to manage connections for the
* Query method
*
* @package Query
* @subpackage Query
*/
final class Connection_Manager {
/**
* Map of named database connections
* @var array
*/
private $connections = array();
/**
* Class instance variable
* @var Connection_Manager
*/
private static $instance = null;
/**
* Private methods for singleton
*/
private function __construct() {}
private function __clone() {}
/**
* Make sure serialize/deseriaze doesn't work
* @throws DomainException
*/
private function __wakup()
{
throw new DomainException("Can't unserialize singleton");
}
// --------------------------------------------------------------------------
/**
* Return a connection manager instance
*
* @staticvar null $instance
* @return Connection_Manager
*/
public static function get_instance()
{
if (self::$instance === null)
{
self::$instance = new self();
}
return self::$instance;
}
// --------------------------------------------------------------------------
/**
* Returns the connection specified by the name given
*
* @param mixed $name
* @return Query_Builder
* @throws InvalidArgumentException
*/
public function get_connection($name = '')
{
// If the paramater is a string, use it as an array index
if (is_scalar($name) && isset($this->connections[$name]))
{
return $this->connections[$name];
}
elseif (empty($name) && ! empty($this->connections)) // Otherwise, return the last one
{
return end($this->connections);
}
else
{
throw new InvalidArgumentException("The specified connection does not exist");
}
}
// --------------------------------------------------------------------------
/**
* Parse the passed parameters and return a connection
*
* @param array|object $params
* @return Query_Builder
* @throws BadConnectionException
*/
public function connect($params)
{
list($dsn, $dbtype, $params, $options) = $this->parse_params($params);
// Create the database connection
$db = ( ! empty($params->user))
? new $dbtype($dsn, $params->user, $params->pass, $options)
: new $dbtype($dsn, '', '', $options);
// --------------------------------------------------------------------------
// Save connection
// --------------------------------------------------------------------------
// Set the table prefix, if it exists
if (isset($params->prefix))
{
$db->table_prefix = $params->prefix;
}
// Create the Query Builder object
$conn = new Query_Builder($db, $params);
// Save it for later
if (isset($params->alias))
{
$this->connections[$params->alias] = $conn;
}
else
{
$this->connections[] = $conn;
}
return $conn;
}
// --------------------------------------------------------------------------
/**
* Parses params into a dsn and option array
*
* @param ArrayObject $params
* @throws BadDBDriverException
*/
private function parse_params($params)
{
// --------------------------------------------------------------------------
// Parse argument array / object
// --------------------------------------------------------------------------
// Convert array to object
if (is_array($params))
{
$params = new ArrayObject($params, ArrayObject::STD_PROP_LIST | ArrayObject::ARRAY_AS_PROPS);
}
$params->type = strtolower($params->type);
$dbtype = ($params->type !== 'postgresql') ? $params->type : 'pgsql';
// Make sure the class exists
if ( ! class_exists($dbtype))
{
throw new BadDBDriverException('Database driver does not exist, or is not supported');
}
// Set additional PDO options
$options = array();
if (isset($params->options))
{
$options = (array) $params->options;
}
// Create the dsn for the database to connect to
$dsn = $this->create_dsn($dbtype, $params);
return array($dsn, $dbtype, $params, $options);
}
// --------------------------------------------------------------------------
/**
* Create the dsn from the db type and params
*
* @param string $dbtype
* @param array|object $params
* @return string
*/
private function create_dsn($dbtype, $params)
{
// Add the driver type to the dsn
$dsn = ($dbtype !== 'firebird' && $dbtype !== 'sqlite')
? strtolower($dbtype).':'
: '';
if ($dbtype === 'firebird') $dsn = "{$params->host}:{$params->file}";
elseif ($dbtype === 'sqlite') $dsn = $params->file;
else
{
if ( ! empty($params->database))
{
$dsn .= "dbname={$params->database}";
}
$skip = array(
'name' => 'name',
'pass' => 'pass',
'user' => 'user',
'file' => 'file',
'type' => 'type',
'prefix' => 'prefix',
'options' => 'options',
'database' => 'database'
);
foreach($params as $key => $val)
{
if ( ! isset($skip[$key]))
{
$dsn .= ";{$key}={$val}";
}
}
}
return $dsn;
}
}

View File

@ -14,27 +14,9 @@
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
/** /**
* Global classes/functions that don't really fit anywhere else * Global functions that don't really fit anywhere else
*/ */
/**
* Generic exception for bad drivers
*
* @package Query
* @subpackage Query
*/
class BadDBDriverException extends InvalidArgumentException {}
// --------------------------------------------------------------------------
/**
* Generic exception for bad connection strings
*
* @package Query
* @subpackage Query
*/
class BadConnectionException extends UnexpectedValueException {}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
if ( ! function_exists('do_include')) if ( ! function_exists('do_include'))
@ -96,130 +78,19 @@ function db_filter($array, $index)
* *
* @param mixed $params * @param mixed $params
* @return Query_Builder * @return Query_Builder
* @throws InvalidArgumentException
* @throws BadDBDriverException
* @throws BadConnectionException
*/ */
function Query($params = '') function Query($params = '')
{ {
static $connections; $cmanager = Connection_Manager::get_instance();
// If you are getting a previously created connection // If you are getting a previously created connection
if (is_scalar($params)) if (is_scalar($params))
{ {
// If the paramater is a string, use it as an array index return $cmanager->get_connection($params);
if (is_scalar($params) && isset($connections[$params]))
{
return $connections[$params];
}
elseif (empty($params) && ! empty($connections)) // Otherwise, return the last one
{
return end($connections);
} }
throw new InvalidArgumentException("The specified connection does not exist"); // Otherwise, return a new connection
} return $cmanager->connect($params);
// --------------------------------------------------------------------------
// Parse argument array / object
// --------------------------------------------------------------------------
// Convert array to object
if (is_array($params))
{
$params = new ArrayObject($params, ArrayObject::STD_PROP_LIST | ArrayObject::ARRAY_AS_PROPS);
}
$params->type = strtolower($params->type);
$dbtype = ($params->type !== 'postgresql') ? $params->type : 'pgsql';
// Let the connection work with 'conn_db' or 'database'
if (isset($params->database))
{
$params->conn_db = $params->database;
}
// Add the driver type to the dsn
$dsn = ($dbtype !== 'firebird' && $dbtype !== 'sqlite')
? strtolower($dbtype).':'
: '';
// Make sure the class exists
if ( ! class_exists($dbtype))
{
throw new BadDBDriverException('Database driver does not exist, or is not supported');
}
// Set additional PDO options
$options = array();
if (isset($params->options))
{
$options = (array) $params->options;
}
// --------------------------------------------------------------------------
// Attempt to connect
// --------------------------------------------------------------------------
// Create the dsn for the database to connect to
if ($dbtype === 'firebird') $dsn = "{$params->host}:{$params->file}";
elseif ($dbtype === 'sqlite') $dsn = $params->file;
else
{
if ( ! empty($params->conn_db))
{
$dsn .= "dbname={$params->conn_db}";
}
if ( ! empty($params->host))
{
$dsn .= ";host={$params->host}";
}
if ( ! empty($params->port))
{
$dsn .= ";port={$params->port}";
}
}
try
{
// Create the database connection
$db = ( ! empty($params->user))
? new $dbtype($dsn, $params->user, $params->pass, $options)
: new $dbtype($dsn, '', '', $options);
}
catch(Exception $e)
{
throw new BadConnectionException('Connection failed, invalid arguments', 2);
}
// --------------------------------------------------------------------------
// Save connection
// --------------------------------------------------------------------------
// Set the table prefix, if it exists
if (isset($params->prefix))
{
$db->table_prefix = $params->prefix;
}
// Create the Query Builder object
$conn = new Query_Builder($db, $params);
// Save it for later
if (isset($params->alias))
{
$connections[$params->alias] = $conn;
}
else
{
$connections[] = $conn;
}
// Return the Query Builder object
return $conn;
} }
// End of common.php // End of common.php

View File

@ -35,7 +35,7 @@ class PgTest extends DBTest {
$params = json_decode(file_get_contents(QTEST_DIR . "/settings.json")); $params = json_decode(file_get_contents(QTEST_DIR . "/settings.json"));
$params = $params->pgsql; $params = $params->pgsql;
$this->db = new PgSQL("pgsql:host={$params->host};dbname={$params->database}", $params->user, $params->pass); $this->db = new PgSQL("pgsql:dbname={$params->database}", $params->user, $params->pass);
} }
elseif (($var = getenv('CI'))) elseif (($var = getenv('CI')))
{ {