Finished testing the Database class

This commit is contained in:
Joshua Sherman 2014-01-18 10:31:46 -05:00
parent 2ff7a658e7
commit 30b9616b12
2 changed files with 233 additions and 115 deletions

View file

@ -13,6 +13,8 @@
* @license http://www.opensource.org/licenses/mit-license.html * @license http://www.opensource.org/licenses/mit-license.html
* @package PICKLES * @package PICKLES
* @link https://github.com/joshtronic/pickles * @link https://github.com/joshtronic/pickles
* @todo Drop driver, hardcode drivers based on the type
* @todo More assumptions for the datasource variables
*/ */
/** /**
@ -231,12 +233,6 @@ class Database extends Object
{ {
if ($this->connection === null) if ($this->connection === null)
{ {
// Checks that the prefix is set
if ($this->dsn == null)
{
throw new Exception('Data source name is not defined');
}
switch ($this->driver) switch ($this->driver)
{ {
case 'pdo_mysql': case 'pdo_mysql':
@ -256,30 +252,22 @@ class Database extends Object
if (isset($this->username, $this->password, $this->database)) if (isset($this->username, $this->password, $this->database))
{ {
// Creates a new PDO database object (persistent) // Swaps out any variables with values in the DSN
try $this->dsn = str_replace(
{ ['[[hostname]]', '[[port]]', '[[socket]]', '[[username]]', '[[password]]', '[[database]]'],
// Swaps out any variables with values in the DSN [$this->hostname, $this->port, $this->socket, $this->username, $this->password, $this->database],
$this->dsn = str_replace( $this->dsn
['[[hostname]]', '[[port]]', '[[socket]]', '[[username]]', '[[password]]', '[[database]]'], );
[$this->hostname, $this->port, $this->socket, $this->username, $this->password, $this->database],
$this->dsn
);
// Strips any empty parameters in the DSN // Strips any empty parameters in the DSN
$this->dsn = str_replace(['host=;', 'port=;', 'unix_socket=;'], '', $this->dsn); $this->dsn = str_replace(['host=;', 'port=;', 'unix_socket=;'], '', $this->dsn);
// Attempts to establish a connection // Attempts to establish a connection
$this->connection = new PDO($this->dsn, $this->username, $this->password, $this->attributes); $this->connection = new PDO($this->dsn, $this->username, $this->password, $this->attributes);
}
catch (PDOException $e)
{
throw new Exception($e);
}
} }
else else
{ {
throw new Exception('There was an error loading the database configuration'); throw new Exception('There was an error loading the database configuration.');
} }
} }
@ -308,9 +296,10 @@ class Database extends Object
* *
* @param string $sql statement to execute * @param string $sql statement to execute
* @param array $input_parameters optional key/values to be bound * @param array $input_parameters optional key/values to be bound
* @param boolean $force_slow optional, force slow query logging
* @return integer ID of the last inserted row or sequence number * @return integer ID of the last inserted row or sequence number
*/ */
public function execute($sql, $input_parameters = null) public function execute($sql, $input_parameters = null, $force_slow = false)
{ {
$this->open(); $this->open();
@ -347,68 +336,59 @@ class Database extends Object
$sql .= "\n" . '/* [' . implode('|', $files) . '] */'; $sql .= "\n" . '/* [' . implode('|', $files) . '] */';
try // Establishes if we're working on an EXPLAIN
if (Profiler::enabled('explains'))
{ {
// Establishes if we're working on an EXPLAIN $explain = preg_match('/^SELECT /i', $sql);
if (Profiler::enabled('explains') == true)
{
$explaining = preg_match('/^EXPLAIN /i', $sql);
$selecting = preg_match('/^SELECT /i', $sql);
}
else
{
$explaining = null;
$selecting = null;
}
// Executes a standard query
if ($input_parameters === null)
{
// Explains the query
if ($selecting == true && $explaining == false)
{
$explain = $this->fetch('EXPLAIN ' . $sql);
}
$start_time = microtime(true);
$this->results = $this->connection->query($sql);
}
// Executes a prepared statement
else
{
// Explains the query
if ($selecting == true && $explaining == false)
{
$explain = $this->fetch('EXPLAIN ' . $sql, $input_parameters);
}
$start_time = microtime(true);
$this->results = $this->connection->prepare($sql);
$this->results->execute($input_parameters);
}
$end_time = microtime(true);
$duration = $end_time - $start_time;
if ($duration >= 1)
{
Log::slowQuery($duration . ' seconds: ' . $loggable_query);
}
// Logs the information to the profiler
if ($explaining == false && Profiler::enabled('explains', 'queries'))
{
Profiler::logQuery($sql, $input_parameters, (isset($explain) ? $explain : false), $duration);
}
} }
catch (PDOException $e) else
{ {
throw new Exception($e); $explain = null;
}
// Executes a standard query
if ($input_parameters === null)
{
// Explains the query
if ($explain)
{
$explain = $this->fetch('EXPLAIN ' . $sql);
}
$start_time = microtime(true);
$this->results = $this->connection->query($sql);
}
// Executes a prepared statement
else
{
// Explains the query
if ($explain)
{
$explain = $this->fetch('EXPLAIN ' . $sql, $input_parameters);
}
$start_time = microtime(true);
$this->results = $this->connection->prepare($sql);
$this->results->execute($input_parameters);
}
$end_time = microtime(true);
$duration = $end_time - $start_time;
if ($duration >= 1 || $force_slow)
{
Log::slowQuery($duration . ' seconds: ' . $loggable_query);
}
// Logs the information to the profiler
if (Profiler::enabled('explains', 'queries'))
{
Profiler::logQuery($sql, $input_parameters, (isset($explain) ? $explain : false), $duration);
} }
} }
else else
{ {
throw new Exception('No query to execute'); throw new Exception('No query to execute.');
} }
return $this->connection->lastInsertId(); return $this->connection->lastInsertId();

View file

@ -14,44 +14,182 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
public function testGetInstanceDatasourceNotDefined() public function testGetInstanceDatasourceNotDefined()
{ {
$config = Config::getInstance(); $config = Config::getInstance();
$config->data['pickles']['datasource'] = 'mysql'; $config->data['pickles']['datasource'] = 'bad';
Database::getInstance(); Database::getInstance();
} }
// /** /**
// * @expectedException Exception * @expectedException Exception
// * @expectedExceptionMessage The specified datasource lacks a driver. * @expectedExceptionMessage The specified datasource lacks a driver.
// */ */
// public function testGetInstanceDatasourceLacksDriver() public function testGetInstanceDatasourceLacksDriver()
// { {
// $config = Config::getInstance(); $config = Config::getInstance();
// $config->data['datasources'] = [ $config->data['datasources'] = [
// 'mysql' => [ 'bad' => [
// 'type' => 'mysql', 'type' => 'mysql',
// ], ],
// ]; ];
// $this->assertInstanceOf('Database', Database::getInstance()); $this->assertInstanceOf('Database', Database::getInstance());
// } }
//
// public function testGetInstanceDatasourcesArray()
// {
// $config = Config::getInstance();
// $config->data['datasources'] = [
// 'mysql' => [
// 'type' => 'mysql',
// 'driver' => 'pdo_mysql',
// ],
// ];
// $this->assertInstanceOf('Database', Database::getInstance());
// }
// public function testGetInstanceFirstDatasource() /**
// { * @expectedException Exception
// $config = Config::getInstance(); * @expectedExceptionMessage There was an error loading the database configuration.
// $config->data['pickles']['datasource'] = false; */
// public function testOpenConfigError()
// //$this->assertInstanceOf('Database', Database::getInstance()); {
// } $config = Config::getInstance();
$config->data['datasources'] = [
'bad' => [
'type' => 'mysql',
'driver' => 'pdo_mysql',
'database' => 'test',
],
];
$db = Database::getInstance();
$db->open();
}
public function testGetInstanceDatasourcesArray()
{
$config = Config::getInstance();
$config->data['datasources'] = [
'mysql' => [
'type' => 'mysql',
'driver' => 'pdo_mysql',
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => 'test',
],
];
$this->assertInstanceOf('Database', Database::getInstance());
}
// Also tests the datasource being missing and selecting the first one
public function testGetInstanceMySQL()
{
$config = Config::getInstance();
unset($config->data['pickles']['datasource']);
$this->assertInstanceOf('Database', Database::getInstance());
}
public function testOpenMySQL()
{
$config = Config::getInstance();
$config->data['pickles']['datasource'] = 'mysql';
$db = Database::getInstance();
$db->open();
}
public function testExecute()
{
$db = Database::getInstance();
$this->assertEquals('0', $db->execute('SHOW TABLES'));
}
/**
* @expectedException Exception
* @expectedExceptionMessage No query to execute.
*/
public function testExecuteNoQuery()
{
$db = Database::getInstance();
$db->execute(' ');
}
public function testFetch()
{
$config = Config::getInstance();
$config->data['pickles']['logging'] = true;
$config->data['pickles']['profiler'] = true;
$db = Database::getInstance();
$this->assertEquals([], $db->fetch('SELECT * FROM pickles WHERE id != ?', ['0']));
}
public function testExplainNoInput()
{
$config = Config::getInstance();
$db = Database::getInstance();
$this->assertEquals([], $db->fetch('SELECT * FROM pickles WHERE id != 0'));
}
public function testSlowQuery()
{
$db = Database::getInstance();
$this->assertEquals('0', $db->execute('SHOW DATABASES', null, true));
}
public function testCloseMySQL()
{
$db = Database::getInstance();
$db->open();
$this->assertTrue($db->close());
}
public function testGetInstancePostgreSQL()
{
$config = Config::getInstance();
$config->data['pickles']['datasource'] = 'pgsql';
$config->data['datasources']['pgsql'] = [
'type' => 'pgsql',
'driver' => 'pdo_pgsql',
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => 'test',
];
$this->assertInstanceOf('Database', Database::getInstance());
}
/**
* @expectedException PDOException
* @expectedExceptionMessage SQLSTATE[08006] [7] could not connect to server
* @expectedExceptionCode 7
*/
public function testOpenPostgreSQL()
{
// Also throws an exception since I don't have PostgreSQL set up
$config = Config::getInstance();
$db = Database::getInstance();
$db->open();
}
public function testGetInstanceSQLite()
{
$config = Config::getInstance();
$config->data['pickles']['datasource'] = 'sqlite';
$config->data['datasources']['sqlite'] = [
'type' => 'sqlite',
'driver' => 'pdo_sqlite',
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => 'test',
];
$this->assertInstanceOf('Database', Database::getInstance());
}
/**
* @expectedException Exception
* @expectedExceptionMessage Datasource driver "pdo_invalid" is invalid
*/
public function testGetInstanceInvalidDriver()
{
$config = Config::getInstance();
$config->data['pickles']['datasource'] = 'invalid';
$config->data['datasources']['invalid'] = [
'type' => 'invalid',
'driver' => 'pdo_invalid',
'hostname' => 'localhost',
'username' => '',
'password' => '',
'database' => 'test',
];
Database::getInstance();
}
} }
?> ?>