From 961c869c30fb225ec4d76b7e954850ad39e5e0dd Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 22 Sep 2013 21:44:54 +0200 Subject: [PATCH] implement drivers as Singleton --- core/Driver.inc | 2 +- drivers/DatabaseDriver.inc | 62 +++++++------- drivers/MysqlDriver.inc | 153 --------------------------------- drivers/MysqliDriver.inc | 167 +++++++++++++++++++++++++++++++++++++ models/DatabaseModel.inc | 70 +++------------- 5 files changed, 214 insertions(+), 240 deletions(-) delete mode 100644 drivers/MysqlDriver.inc create mode 100644 drivers/MysqliDriver.inc diff --git a/core/Driver.inc b/core/Driver.inc index bf9084d1..eec59143 100644 --- a/core/Driver.inc +++ b/core/Driver.inc @@ -63,7 +63,7 @@ // Construct and return Driver - return new $className($config); + return $className::singleton($config); } diff --git a/drivers/DatabaseDriver.inc b/drivers/DatabaseDriver.inc index c69d6add..dfd5c0fd 100644 --- a/drivers/DatabaseDriver.inc +++ b/drivers/DatabaseDriver.inc @@ -20,11 +20,12 @@ abstract class DatabaseDriver extends \nre\core\Driver { /** - * Connection and login settings + * Driver class instance * - * @var array + * @static + * @var DatabaseDriver */ - protected $config; + protected static $driver = null; /** * Connection resource * @@ -36,31 +37,25 @@ /** - * Execute a SQL-query. + * Singleton-pattern. * - * @param string $query Query to run - * @return array Result + * @param array $config Database driver configuration + * @return DatabaseDriver Singleton-instance of database driver class */ - public abstract function query($query); - - - /** - * Return the last insert id (of the last insert-query). - * - * @return int Last insert id - */ - public abstract function getInsertId(); - - - /** - * Mask an input for using it in a SQL-query. - * - * @param mixed $input Input to mask - * @return mixed Masked input - */ - public abstract function mask($input); - - + public static function singleton($config) + { + // Singleton + if(self::$driver !== null) { + return self::$driver; + } + + // Construct + $className = get_called_class(); + self::$driver = new $className($config); + + + return self::$driver; + } /** @@ -72,10 +67,21 @@ { parent::__construct(); - // Save values - $this->config = $config; + // Establish connection + $this->connect($config); } + + + + /** + * Establish a connect to a MqSQL-database. + * + * @throws DatamodelException + * @param array $config Connection and login settings + */ + protected abstract function connect($config); + } ?> diff --git a/drivers/MysqlDriver.inc b/drivers/MysqlDriver.inc deleted file mode 100644 index 11122b38..00000000 --- a/drivers/MysqlDriver.inc +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright 2013 coderkun (http://www.coderkun.de) - * @license http://www.gnu.org/licenses/gpl.html - * @link http://www.coderkun.de/projects/nre - */ - - namespace nre\drivers; - - - /** - * Implementation of a database driver for MySQL-databases. - * - * @author coderkun - */ - class MysqlDriver extends \nre\drivers\DatabaseDriver - { - - - - - /** - * Construct a MySQL-driver. - * - * @throws DatamodelException - * @param array $config Connection and login settings - */ - function __construct($config) - { - parent::__construct($config); - - // Connect - $this->connect(); - } - - - - - /** - * Execute a SQL-query. - * - * @param string $query Query to run - * @return array Result - */ - public function query($query) - { - // Return-array - $data = array(); - - - // Execute query - $result = mysql_query($query, $this->connection); - - // Check result - if(($errno = mysql_errno($this->connection)) > 0) { - throw new DatamodelException(mysql_error($this->connection), $errno); - } - - // Process result - if(is_resource($result)) - { - while($row = mysql_fetch_array($result, MYSQL_ASSOC)) { - $data[] = $row; - } - } - - - // Return data - return $data; - } - - - /** - * Return the last insert id (of the last insert-query). - * - * @return int Last insert id - */ - public function getInsertId() - { - return mysql_insert_id($this->connection); - } - - - /** - * Mask an input for using it in a SQL-query. - * - * @param mixed $input Input to mask - * @return mixed Masked input - */ - public function mask($input) - { - return mysql_real_escape_string($input, $this->connection); - } - - - - - /** - * Establish a connect to a MqSQL-database. - * - * @throws DatamodelException - */ - private function connect() - { - // Connect - $con = @mysql_connect( - $this->config['host'], - $this->config['user'], - $this->config['password'] - ); - - // Check connection - if($con === false) { - throw new \nre\exceptions\DatamodelException(mysql_error(), mysql_errno()); - } - - // Save connection - $this->connection = $con; - - - // Select database - $db = mysql_select_db( - $this->config['db'], - $this->connection - ); - - // Check database selection - if(!$db) { - throw new DatamodelException(mysql_error(), mysql_errno()); - } - - - // Configure connection - $this->configConnection(); - } - - - /** - * Configure the current connection - */ - private function configConnection() - { - // Set character encoding - $this->query("SET NAMES 'utf8'", $this->connection); - } - - } - -?> diff --git a/drivers/MysqliDriver.inc b/drivers/MysqliDriver.inc new file mode 100644 index 00000000..9520fa1e --- /dev/null +++ b/drivers/MysqliDriver.inc @@ -0,0 +1,167 @@ + + * @copyright 2013 coderkun (http://www.coderkun.de) + * @license http://www.gnu.org/licenses/gpl.html + * @link http://www.coderkun.de/projects/nre + */ + + namespace nre\drivers; + + + /** + * Implementation of a database driver for MySQL-databases. + * + * @author coderkun + */ + class MysqliDriver extends \nre\drivers\DatabaseDriver + { + + + + + /** + * Construct a MySQL-driver. + * + * @throws DatamodelException + * @param array $config Connection and login settings + */ + function __construct($config) + { + parent::__construct($config); + } + + + + + /** + * Execute a SQL-query. + * + * @throws DatamodelException + * @param string $query Query to run + * @param mixed … Params + * @return array Result + */ + public function query($query) + { + // Prepare statement + if(!($stmt = $this->connection->prepare($query))) { + throw new \nre\exceptions\DatamodelException($this->connection->error, $this->connection->errno); + } + + try { + // Prepare data + $data = array(); + + // Bind parameters + $p = array_slice(func_get_args(), 1); + $params = array(); + foreach($p as $key => $value) { + $params[$key] = &$p[$key]; + } + if(count($params) > 0) + { + if(!(call_user_func_array(array($stmt, 'bind_param'), $params))) { + throw new \nre\exceptions\DatamodelException($this->connection->error, $this->connection->errno); + } + } + + // Execute query + if(!$stmt->execute()) { + throw new \nre\exceptions\DatamodelException($this->connection->error, $this->connection->errno); + } + + // Fetch result + if($result = $stmt->get_result()) { + while($row = $result->fetch_assoc()) { + $data[] = $row; + } + } + + + return $data; + } + finally { + $stmt->close(); + } + } + + + /** + * Return the last insert id (of the last insert-query). + * + * @return int Last insert id + */ + public function getInsertId() + { + return $this->connection->insert_id; + } + + + /** + * Enable/disable autocommit feature. + * + * @param boolean $autocommit Enable/disable autocommit + */ + public function setAutocommit($autocommit) + { + $this->connection->autocommit($autocommit); + } + + + /** + * Rollback the current transaction. + */ + public function rollback() + { + $this->connection->rollback(); + } + + + /** + * Commit the current transaction. + */ + public function commit() + { + $this->connection->commit(); + } + + + + + /** + * Establish a connect to a MqSQL-database. + * + * @throws DatamodelException + * @param array $config Connection and login settings + */ + protected function connect($config) + { + // Connect + $con = @new \mysqli( + $config['host'], + $config['user'], + $config['password'], + $config['db'] + ); + + // Check connection + if($con->connect_error) { + throw new \nre\exceptions\DatamodelException($con->connect_error, $con->connect_errno); + } + + // Set character encoding + if(!$con->set_charset('utf8')) { + throw new \nre\exceptions\DatamodelException($con->connect_error, $con->connect_errno); + } + + // Save connection + $this->connection = $con; + } + + } + +?> diff --git a/models/DatabaseModel.inc b/models/DatabaseModel.inc index 8017f959..51259f4f 100644 --- a/models/DatabaseModel.inc +++ b/models/DatabaseModel.inc @@ -19,14 +19,13 @@ */ class DatabaseModel extends \nre\core\Model { - /** * Database connection * * @static - * @var object + * @var DatabaseDriver */ - private static $db = NULL; + protected $db = NULL; @@ -34,64 +33,21 @@ /** * Construct a new datamase model. * + * @throws DatamodelException * @throws DriverNotFoundException * @throws DriverNotValidException - * @throws DatamodelException - * @param string $databaseType Database type - * @param array $config Connection settings + * @param string $type Database type + * @param array $config Connection settings */ - function __construct($databaseType, $config) + function __construct($type, $config) { parent::__construct(); // Load database driver - $this->loadDriver($databaseType); + $this->loadDriver($type); // Establish database connection - $this->connect($databaseType, $config); - } - - - - - /** - * Execute a SQL-query. - * - * @param string $query Query to run - * @param mixed … Query parameters - * @return array Result - */ - protected function query($query) - { - // Mask parameters - $args = array($query); - foreach(array_slice(func_get_args(), 1) as $arg) { - $args[] = self::$db->mask($arg); - } - - // Format query - $query = call_user_func_array( - 'sprintf', - $args - ); - - // Execute query - $data = self::$db->query($query); - - - // Return data - return $data; - } - - - /** - * Return the last insert id (of the last insert-query). - * - * @return int Last insert id - */ - protected function getInsertId() - { - return self::$db->getInsertId(); + $this->connect($type, $config); } @@ -104,10 +60,9 @@ * @throws DriverNotValidException * @param string $driverName Name of the database driver */ - private static function loadDriver($driverName) + private function loadDriver($driverName) { \nre\core\Driver::load($driverName); - } @@ -116,12 +71,11 @@ * * @throws DatamodelException * @param string $driverName Name of the database driver + * @param array $config Connection settings */ - private static function connect($driverName, $config) + private function connect($driverName, $config) { - if(self::$db === NULL) { - self::$db = \nre\core\Driver::factory($driverName, $config); - } + $this->db = \nre\core\Driver::factory($driverName, $config); } }