Skip to content

Commit

Permalink
Added database access functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
epixa committed Apr 19, 2011
1 parent 05d91af commit 24db6a0
Show file tree
Hide file tree
Showing 7 changed files with 460 additions and 2 deletions.
11 changes: 11 additions & 0 deletions application/config/production.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,16 @@
'debug' => array(
'renderExceptions' => true
)
),
'resources' => array(
'database'
),
'database' => array(
'dsnParams' => array(
'host' => 'localhost',
'dbname' => 'microdb'
),
'username' => 'dbuser',
'password' => 'dbpass'
)
);
27 changes: 27 additions & 0 deletions library/Micro/Bootstrap/MvcBootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
Micro\Response\HttpResponse,
Micro\Router\SimpleRouter,
Micro\Dispatcher\MvcDispatcher,
Micro\Database\Adapter\MysqlDriver,
Micro\Model\AbstractDbModel,
Micro\View\FileView,
Micro\Controller\AbstractController,
Micro\Exception\ConfigException,
Expand Down Expand Up @@ -119,6 +121,31 @@ protected function _initView()

return $view;
}

/**
* Initializes the application's primary database connection
*
* @return HttpResponse
*/
protected function _initDatabase()
{
$config = $this->getConfig('database');
if ($config === null) {
throw new ConfigException('No database config set');
}

$adapter = new MysqlDriver();
$adapter->setConnectionInfo(
$config->dsnParams ? $config->dsnParams->toArray() : array(),
$config->username,
$config->password,
$config->driverOptions ? $config->driverOptions->toArray() : array()
);

AbstractDbModel::setDefaultAdapter($adapter);

return $adapter;
}

/**
* Runs the application
Expand Down
48 changes: 46 additions & 2 deletions library/Micro/Config/ArrayConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

namespace Micro\Config;

use IteratorAggregate,
use ArrayAccess,
IteratorAggregate,
Serializable;

/**
Expand All @@ -15,7 +16,7 @@
* @license http://github.com/epixa/MicroMVC/blob/master/LICENSE New BSD
* @author Court Ewing (court@epixa.com)
*/
class ArrayConfig implements IteratorAggregate, Serializable
class ArrayConfig implements ArrayAccess, IteratorAggregate, Serializable
{
/**
* @var array
Expand Down Expand Up @@ -146,4 +147,47 @@ public function getIterator()
{
return new ArrayIterator($this->_data);
}

/**
* From ArrayAccess
*
* @param mixed $offset
* @param mixed $value
*/
public function offsetSet($offset, $value)
{
$this->__set($offset, $value);
}

/**
* From ArrayAccess
*
* @param mixed $offset
* @return boolean
*/
public function offsetExists($offset)
{
return $this->__isset($offset);
}

/**
* From ArrayAccess
*
* @param mixed $offset
*/
public function offsetUnset($offset)
{
$this->__unset($offset);
}

/**
* From ArrayAccess
*
* @param mixed $offset
* @return mixed
*/
public function offsetGet($offset)
{
return $this->__get($offset);
}
}
207 changes: 207 additions & 0 deletions library/Micro/Database/Adapter/AbstractAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
<?php
/**
* Epixa MicroMVC
*/

namespace Micro\Database\Adapter;

use PDO,
LogicException,
Micro\Exception\ConfigException;

/**
* @category Epixa
* @package Database
* @subpackage Adapter
* @copyright 2011 epixa.com - Court Ewing
* @license http://github.com/epixa/MicroMVC/blob/master/LICENSE New BSD
* @author Court Ewing (court@epixa.com)
*/
abstract class AbstractAdapter implements AdapterInterface
{
/**
* @var integer
*/
protected static $_transactionLevel = 0;

/**
* @var null|PDO
*/
protected $_connection = null;

/**
* @var null|array
*/
protected $_connectionInfo = null;


/**
* Sets the database connection information
*
* @param array $params
* @param null|string $user
* @param null|string $pass
* @param array $driverOptions
* @return AbstractAdapter *Fluent interface*
*/
public function setConnectionInfo(array $params, $user = null, $pass = null, array $driverOptions = array())
{
$this->_connectionInfo = array(
'dsnParams' => $params,
'dbUsername' => $user,
'dbPassword' => $pass,
'dbDriverOptions' => $driverOptions
);

return $this;
}

/**
* Creates a new PDO connection
*
* @throws LogicException|ConfigException
*/
public function connect()
{
if ($this->_connection !== null) {
throw new LogicException('Connection is already established');
}

if ($this->_connectionInfo === null) {
throw new ConfigException('No database connection information specified');
}

$params = $this->_connectionInfo['dsnParams'];
$user = $this->_connectionInfo['dbUsername'];
$pass = $this->_connectionInfo['dbPassword'];
$driverOptions = $this->_connectionInfo['dbDriverOptions'];

$pdo = new PDO($this->_createDsn($params), $user, $pass, $driverOptions);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$this->setConnection($pdo);
}

/**
* Executes the given sql query with the optional bound parameters
*
* If the given query is a select statement, the results are returned in an array.
* If the given query is an insert statement, the last inserted id is returned.
* For all other queries, true is returned on success.
*
* @param string $sql
* @param array $bind
* @return boolean|array|integer
*/
public function query($sql, array $bind = array())
{
$sql = trim($sql);

foreach ($bind as $name => $value) {
if (!is_int($name) && strpos($name, ':') !== 0) {
unset($bind[$name]);
$bind[':' . $name] = $value;
}
}

$connection = $this->getConnection();

$stmt = $connection->prepare($sql);
$return = $stmt->execute($bind);

if (stripos($sql, 'SELECT') === 0) {
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$return = $stmt->fetchAll();
} else if (stripos($sql, 'INSERT') === 0) {
$return = $connection->lastInsertId();
}

return $return;
}

/**
* Attempts to begin a new transaction
*
* To allow stacked transactions, the transaction level is always
* incremented, but a new transaction is only begun when there are no others
* started.
*/
public function beginTransaction()
{
self::$_transactionLevel++;

if (self::$_transactionLevel == 1) {
$this->getConnection()->beginTransaction();
}
}

/**
* Attempts to commit the current transaction
*
* To allow stacked transactions, a commit is only executed if there is only
* =one transaction that is suppose to be started.
*/
public function commit()
{
if (self::$_transactionLevel == 1) {
$this->getConnection()->commit();
}

if (self::$_transactionLevel > 0) {
self::$_transactionLevel--;
}
}

/**
* Attempts to rollback the current transaction
*
* To allow stacked transactions, a rollback is only executed if there is
* only one transaction that is suppose to be started.
*/
public function rollback()
{
if (self::$_transactionLevel == 1) {
$this->getConnection()->rollBack();
}

if (self::$_transactionLevel > 0) {
self::$_transactionLevel--;
}
}

/**
* Sets the current database connection
*
* @param PDO $pdo
* @return AbstractAdapter *Fluent interface*
*/
public function setConnection(PDO $pdo)
{
$this->_connection = $pdo;

return $this;
}

/**
* Gets the current database connection
*
* @return PDO
*/
public function getConnection()
{
if ($this->_connection === null) {
$this->connect();
}

return $this->_connection;
}


/**
* Creates a dsn string from the given parameters
*
* @param array $params
* @return string
*/
abstract protected function _createDsn(array $params);
}
55 changes: 55 additions & 0 deletions library/Micro/Database/Adapter/AdapterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* Epixa MicroMVC
*/

namespace Micro\Database\Adapter;

/**
* @category Epixa
* @package Database
* @subpackage Adapter
* @copyright 2011 epixa.com - Court Ewing
* @license http://github.com/epixa/MicroMVC/blob/master/LICENSE New BSD
* @author Court Ewing (court@epixa.com)
*/
interface AdapterInterface
{
/**
* Creates a new database connection
*/
public function connect();

/**
* Executes the given query and injects the given parameters
*
* @param string $sql
* @param array $bind
*/
public function query($sql, array $bind = array());

/**
* Attempts to begin a new transaction
*
* To allow stacked transactions, the transaction level is always
* incremented, but a new transaction is only begun when there are no others
* started.
*/
public function beginTransaction();

/**
* Attempts to commit the current transaction
*
* To allow stacked transactions, a commit is only executed if there is only
* one transaction that is suppose to be started.
*/
public function commit();

/**
* Attempts to rollback the current transaction
*
* To allow stacked transactions, a rollback is only executed if there is
* only one transaction that is suppose to be started.
*/
public function rollback();
}
Loading

0 comments on commit 24db6a0

Please sign in to comment.