Skip to content

Commit

Permalink
reorganized, covered, and documented
Browse files Browse the repository at this point in the history
  • Loading branch information
clphillips committed Jul 1, 2015
1 parent 8c4873e commit 3100f1e
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 74 deletions.
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# minphp/Db

[![Build Status](https://travis-ci.org/phillipsdata/minphp-db.svg?banch=master)](https://travis-ci.org/phillipsdata/minphp-db) [![Coverage Status](https://coveralls.io/repos/phillipsdata/minphp-db/badge.svg)](https://coveralls.io/r/phillipsdata/minphp-db)

Database Connection Library.

Efficiently manages a connection, preventing a new one from being established if a matching connection already exists.

## Installation

Install via composer:

```sh
composer require minphp/db:dev-master
```

## Basic Usage

```php
use minphp\Db\PdoConnection;

$dbInfo = array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'databasename',
'user' => 'user',
'pass' => 'pass'
);

$connection = new PdoConnection($dbInfo);
$connection->query('SELECT * FROM table WHERE id=?', 1);
```

### Explicitly Connecting

By default, PdoConnection will only connect to the database when a connection is required. To explicitly connect to the database use `connect()`:

```php
use minphp\Db\PdoConnection;

$dbInfo = array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'databasename',
'user' => 'user',
'pass' => 'pass'
);

$connection = new PdoConnection($dbInfo);
$connection->connect();
// Connection now ready and waiting
```
130 changes: 58 additions & 72 deletions src/PdoConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

use PDO;
use PDOStatement;
use PDOException;
use RuntimeException;
use InvalidArgumentException;

Expand Down Expand Up @@ -63,14 +62,22 @@ class PdoConnection
* the given database info, or the default configured info set in the database
* config file if no info is given
*
* @param array $dbInfo Database information for this connection
* @param array $dbInfo Database information for this connection:
* - driver DB Driver
* - host DB Host
* - database DB name
* - user DB User
* - pass DB Password
* - port DB Port
* - options Array of PDO connection options
*/
public function __construct(array $dbInfo = null) {
public function __construct(array $dbInfo)
{
$this->dbInfo = $dbInfo;
}

/**
* Attemps to initialize a connection to the database if one does not already exist.
* Attemps to initialize a connection to the database if one does not already exist
*
* @return PDO The PDO connection
*/
Expand All @@ -80,16 +87,49 @@ public function connect()
if ($connection instanceof PDO) {
return $connection;
}
return $this->makeConnection($this->dbInfo);

// Attempt to reuse an existing connection if one exists that matches this connection
if ($this->reuseConnection
&& ($key = array_search($this->dbInfo, self::$dbInfos)) !== false
) {
$connection = self::$connections[$key];
$this->setConnection($connection);
return $connection;
}

$dsn = $this->makeDsn($this->dbInfo);
$username = isset($this->dbInfo['user'])
? $this->dbInfo['user']
: null;
$password = isset($this->dbInfo['pass'])
? $this->dbInfo['pass']
: null;
$options = (array) (
isset($this->dbInfo['options'])
? $this->dbInfo['options']
: null
)
+ $this->options;

$connection = $this->makeConnection($dsn, $username, $password, $options);

self::$connections[] = $connection;
self::$dbInfos[] = $this->dbInfo;
$this->setConnection($connection);

return $connection;
}

/**
* Set whether or not to reuse an existing connection
*
* @param boolean $enable True to reuse an existing matching connection if available
* @return PdoConnection
*/
public function reuseConnection($enable)
{
$this->reuseConnection = $enable;
return $this;
}

/**
Expand Down Expand Up @@ -120,10 +160,12 @@ public function lastInsertId($name = null)
*
* @param long $attribute The attribute to set
* @param int $value The value to assign to the attribute
* @return PdoConnection
*/
public function setAttribute($attribute, $value)
{
$this->connect()->setAttribute($attribute, $value);
return $this;
}

/**
Expand Down Expand Up @@ -223,20 +265,12 @@ public function getConnection()
* Set the PDO connection to use
*
* @param PDO $connection
* @return PdoConnection
*/
public function setConnection(PDO $connection)
{
$this->connection = $connection;
}

/**
* Return all registered connections available
*
* @return array
*/
public function getRegisteredConnections()
{
return $this->connections;
return $this;
}

/**
Expand Down Expand Up @@ -275,71 +309,23 @@ public function makeDsn(array $db)
);
}

return $db['driver'] . ":dbname=" . $db['database'] . ";host=" . $db['host']
. (
isset($db['port'])
? ";port=" . $db['port']
: ""
);
return isset($db['port'])
? $db['driver'] . ':host=' . $db['host'] . ';dbname=' . $db['database'] . ';port=' . $db['port']
: $db['driver'] . ':host=' . $db['host'] . ';dbname=' . $db['database'];
}

/**
* Establish a new PDO connection using the given array of information. If
* a connection already exists, no new connection will be created.
*
* @param array $dbInfo Database information for this connection
* @param string $dsn
* @param string $username
* @param string $password
* @param array $options
* @return \PDO The connection
* @throws RuntimeException Throw when PDOException is encountered
*/
private function makeConnection(array $dbInfo)
private function makeConnection($dsn, $username, $password, $options)
{
// Attempt to reuse an existing connection if one exists that matches this connection
if ($this->reuseConnection
&& ($key = array_search($dbInfo, self::$dbInfos)) !== false
) {
$this->setConnection(self::$connections[$key]);
return $this->getConnection();
}

// Override any default settings with those provided
$options = (array) (
isset($dbInfo['options'])
? $dbInfo['options']
: null
)
+ $this->options;

try {
$this->setConnection(new PDO(
$this->makeDsn($dbInfo),
(
isset($dbInfo['user'])
? $dbInfo['user']
: null
),
(
isset($dbInfo['pass'])
? $dbInfo['pass']
: null
),
$options
));
$connection = $this->getConnection();

// Record the connection
self::$connections[] = $connection;
self::$dbInfos[] = $dbInfo;

// Run a character set query to override the database server's default character set
if (!empty($dbInfo['charset_query'])) {
$this->query($dbInfo['charset_query']);
}
return $connection;

} catch (PDOException $e) {
throw new RuntimeException($e->getMessage());
}

throw new RuntimeException('Connection could not be established.');
return new PDO($dsn, $username, $password, $options);
}
}
13 changes: 13 additions & 0 deletions src/SqliteConnection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
namespace minphp\Db;

class SqliteConnection extends PdoConnection
{
/**
* {@inheritdoc}
*/
public function makeDsn(array $db)
{
return 'sqlite:' . $db['database'];
}
}
82 changes: 82 additions & 0 deletions tests/Integration/PdoConnectionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
namespace minphp\Db\Tests\Integration;

use minphp\Db\PdoConnection;
use minphp\Db\SqliteConnection;
use PHPUnit_Framework_TestCase;

/**
* @coversDefaultClass minphp\Db\PdoConnection
*/
class PdoConnectionTest extends PHPUnit_Framework_TestCase
{
private function getDbInfo()
{
return array(
'database' => ':memory:'
);
}

/**
* @covers ::connect
* @covers ::__construct
* @covers ::setConnection
* @covers ::getConnection
* @covers \minphp\Db\SqliteConnection::makeDsn
* @covers ::makeConnection
* @covers ::query
* @covers ::prepare
*/
public function testConnect()
{
$connection = new SqliteConnection($this->getDbInfo());
$this->assertInstanceOf('\PDO', $connection->connect());
}

/**
* @covers ::__construct
* @covers ::reuseConnection
* @covers ::getConnection
* @covers ::setConnection
* @covers ::connect
* @covers \minphp\Db\SqliteConnection::makeDsn
* @covers ::makeConnection
*/
public function testReuseConnection()
{
$dbInfo = $this->getDbInfo();

$connectionA = new SqliteConnection($dbInfo);
$pdoA = $connectionA->connect();

$connectionB = new SqliteConnection($dbInfo);
$pdoB = $connectionB->reuseConnection(true)->connect();

$connectionC = new SqliteConnection($dbInfo);
$pdoC = $connectionC->reuseConnection(false)->connect();

$this->assertSame($pdoA, $pdoB);
$this->assertNotSame($pdoA, $pdoC);
}

/**
* @covers ::__construct
* @covers ::connect
* @covers ::getConnection
* @covers ::makeDsn
* @covers ::makeConnection
* @expectedException \RuntimeException
*/
public function testConnectException()
{
$dbInfo = array(
'driver' => 'invalid',
'host' => 'invalid',
'database' => 'invalid',
'charset_query' => "SET NAMES 'utf8'"
);

$connection = new PdoConnection($dbInfo);
$connection->connect();
}
}
13 changes: 11 additions & 2 deletions tests/Unit/PdoConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class PdoConnectionTest extends PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->connection = new PdoConnection();
$this->connection = new PdoConnection(array());
}

/**
Expand Down Expand Up @@ -211,7 +211,7 @@ public function testMakeDsn()
'host' => 'localhost',
'port' => '8889'
);
$expected = 'mysql:dbname=database;host=localhost;port=8889';
$expected = 'mysql:host=localhost;dbname=database;port=8889';

$this->assertEquals($expected, $this->connection->makeDsn($info));
}
Expand All @@ -225,4 +225,13 @@ public function testMakeDsnException()
{
$this->connection->makeDsn(array());
}

/**
* @covers ::reuseConnection
* @covers ::__construct
*/
public function testReuseConnection()
{
$this->assertSame($this->connection->reuseConnection(true), $this->connection);
}
}
Loading

0 comments on commit 3100f1e

Please sign in to comment.