Fixed multiple bugs relating the database system.

Debugging now actually works in the Database Driver,
This commit is contained in:
Abel Hoogeveen 2017-07-14 16:05:52 +02:00
parent 092d8dffa0
commit 89ccdb24ba
7 changed files with 127 additions and 49 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@ vendor/
build/
doc
nbproject
._*

View File

@ -1,6 +1,7 @@
language: php
php:
- 7.1
- 7
- 5.6

View File

@ -30,12 +30,12 @@
* @version Version 1.0.0
*/
use FuzeWorks\Factory;
use FuzeWorks\Core;
use FuzeWorks\Logger;
use FuzeWorks\Exception\DatabaseException;
use FuzeWorks\Utf8;
use FuzeWorks\Language;
use FuzeWorks\Core;
use FuzeWorks\DatabaseTracyBridge;
use FuzeWorks\Exception\DatabaseException;
/**
* Database Driver Class
@ -175,7 +175,7 @@ abstract class FW_DB_driver {
*
* @var bool
*/
public $db_debug = FALSE;
public $db_debug = TRUE;
/**
* Benchmark time
@ -217,6 +217,14 @@ abstract class FW_DB_driver {
*/
public $queries = array();
/**
* Data of performed queries
*
* @see FW_DB_driver::$save_queries
* @var array
*/
public $query_data = array();
/**
* Query times
*
@ -375,8 +383,6 @@ abstract class FW_DB_driver {
}
}
$this->factory = Factory::getInstance();
Logger::log('Database Driver ' . get_class($this) . ' Initialized');
}
@ -614,7 +620,6 @@ abstract class FW_DB_driver {
{
if ($sql === '')
{
Logger::logError('Invalid query: '.$sql);
return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
}
elseif ( ! is_bool($return_object))
@ -661,6 +666,7 @@ abstract class FW_DB_driver {
if ($this->save_queries === TRUE)
{
$this->query_times[] = 0;
$this->query_data[] = array('error' => $this->error(), 'rows' => 0);
}
// This will trigger a rollback if transactions are being used
@ -672,9 +678,6 @@ abstract class FW_DB_driver {
// Grab the error now, as we might run some additional queries before displaying the error
$error = $this->error();
// Log errors
Logger::logError('Query error: '.$error['message'].' - Invalid query: '.$sql);
if ($this->db_debug)
{
// We call this function in order to roll-back queries
@ -703,11 +706,6 @@ abstract class FW_DB_driver {
$time_end = microtime(TRUE);
$this->benchmark += $time_end - $time_start;
if ($this->save_queries === TRUE)
{
$this->query_times[] = $time_end - $time_start;
}
// Increment the query counter
$this->query_count++;
@ -727,6 +725,12 @@ abstract class FW_DB_driver {
$driver = $this->load_rdriver();
$RES = new $driver($this);
if ($this->save_queries === TRUE)
{
$this->query_times[] = $time_end - $time_start;
$this->query_data[] = array('error' => $this->error(), 'rows' => $RES->num_rows());
}
// Is query caching enabled? If so, we'll serialize the
// result object and save it to a cache file.
if ($this->cache_on === TRUE && $this->_cache_init())
@ -1762,6 +1766,8 @@ abstract class FW_DB_driver {
// the backtrace until the source file is no longer in the
// database folder.
$trace = debug_backtrace();
$file = '';
$line = '';
foreach ($trace as $call)
{
if (isset($call['file'], $call['class']))
@ -1775,19 +1781,16 @@ abstract class FW_DB_driver {
if (strpos($call['file'], Core::$coreDir . DS . 'Database') === FALSE && strpos($call['class'], 'Loader') === FALSE)
{
// Found it - use a relative path for safety
$message[] = 'Filename: '.str_replace(array('Application', 'Core'), '', $call['file']);
$message[] = 'Line Number: '.$call['line'];
$file = str_replace(array('Application', 'Core'), '', $call['file']);
$line = $call['line'];
break;
}
}
}
Logger::logError($heading);
foreach ($message as $message) {
Logger::logError($message);
}
Logger::http_error(500);
exit(8); // EXIT_DATABASE
Logger::logError($heading . " | " . implode(' | ', $message), null, $file, $line);
throw new DatabaseException($heading . ": " . implode(' ', $this->error()), 1);
}
// --------------------------------------------------------------------

View File

@ -33,6 +33,7 @@
use FuzeWorks\Logger;
use FuzeWorks\Helpers;
use FuzeWorks\Libraries;
use Fuzeworks\Factory;
use FuzeWorks\Exception\DatabaseException;
/**

View File

@ -32,7 +32,6 @@
use FuzeWorks\Logger;
use FuzeWorks\Exception\DatabaseException;
use PDOException;
/**
* PDO Database Adapter Class

View File

@ -30,8 +30,6 @@
* @version Version 1.0.0
*/
use \Exception;
/**
* PDO Result Class
*

View File

@ -31,6 +31,7 @@
*/
namespace FuzeWorks;
use FuzeWorks\Exception\DatabaseException;
use FW_DB;
/**
@ -50,6 +51,12 @@ class Database
* @var type FW_DB|null
*/
protected static $defaultDB = null;
/**
* Array of all the non-default databases
* @var array FW_DB|null
*/
protected static $databases = array();
/**
* The default database forge.
@ -57,12 +64,29 @@ class Database
*/
protected static $defaultForge = null;
/**
* Array of all the non-default databases forges.
* @var array FW_DB_forge|null
*/
protected static $forges = array();
/**
* The default database utility.
* @var type FW_DB_utility|null
*/
protected static $defaultUtil = null;
/**
* Register with the TracyBridge upon startup
*/
public function __construct()
{
if (class_exists('Tracy\Debugger', true))
{
DatabaseTracyBridge::register();
}
}
/**
* Retrieve a database using a DSN or the default configuration.
*
@ -76,7 +100,6 @@ class Database
* default one. $newInstance will also make sure that the loaded database is not default one.
* This behaviour will be changed in the future.
*
* @todo Change $newInstance behaviour related to self::$defaultDB
*
* If $queryBuilder = false is provided, the database will load without a queryBuilder.
* By default the queryBuilder will load.
@ -84,48 +107,88 @@ class Database
* @param string $parameters
* @param bool $newInstance
* @param bool $queryBuilder
* @return FW_DB
* @return FW_DB|bool
*/
public static function get($parameters = '', $newInstance = false, $queryBuilder = null)
{
if (!$newInstance && is_object(self::$defaultDB) && ! empty(self::$defaultDB->conn_id))
// Fire the event to allow settings to be changed
$event = Events::fireEvent('databaseLoadDriverEvent', $parameters, $newInstance, $queryBuilder);
if ($event->isCancelled())
{
return false;
}
// If an instance already exists and is requested, return it
if (isset($event->database) && empty($event->parameters))
{
return self::$defaultDB = $event->database;
}
elseif (isset($event->database) && !empty($event->parameters))
{
return self::$databases[$event->parameters] = $event->database;
}
elseif (empty($event->parameters) && !$event->newInstance && is_object(self::$defaultDB) && ! empty(self::$defaultDB->conn_id))
{
return $reference = self::$defaultDB;
}
elseif (!empty($event->parameters) && !$event->newInstance && isset(self::$databases[$event->parameters]))
{
return $reference = self::$databases[$event->parameters];
}
// If a new instance is required, load it
require_once (Core::$coreDir . DS . 'Database'.DS.'DB.php');
if ($newInstance)
if ($event->newInstance === TRUE)
{
return DB($parameters, $queryBuilder);
$database = DB($event->parameters, $event->queryBuilder);
}
elseif (empty($event->parameters) && $event->newInstance === FALSE)
{
$database = self::$defaultDB = DB($event->parameters, $event->queryBuilder);
}
else
{
return self::$defaultDB = DB($parameters, $queryBuilder);
$database = self::$databases[$event->parameters] = DB($event->parameters, $event->queryBuilder);
}
// Tie it into the Tracy Bar if available
if (class_exists('\Tracy\Debugger', true))
{
DatabaseTracyBridge::registerDatabase($database);
}
return $database;
}
/**
* Retrieves a database forge from the provided or default database.
*
* If no database is provided, the default database will be used.
* @todo Change $newInstance behaviour with default instances.
*
*
* @param FW_DB $database
* @param bool $newInstance
* @param FW_DB|null $database
* @param bool $newInstance
* @return FW_DB_forge
*/
public static function getForge($database = null, $newInstance = false)
{
// Fire the event to allow settings to be changed
$event = Events::fireEvent('databaseLoadForgeEvent', $database, $newInstance);
if ($event->isCancelled())
{
return false;
}
// First check if we're talking about the default forge and that one is already set
if (is_object($database) && $database === self::$defaultDB && is_object(self::$defaultForge))
if (is_object($event->forge) && ($event->forge instanceof FW_DB_forge) )
{
return $event->forge;
}
elseif (is_object($event->database) && $event->database === self::$defaultDB && is_object(self::$defaultForge))
{
return $reference = self::$defaultForge;
}
if ( ! is_object($database) OR ! ($database instanceof FW_DB))
elseif ( ! is_object($event->database) OR ! ($event->database instanceof FW_DB))
{
isset(self::$defaultDB) OR self::get('', false);
$database =& self::$defaultDB;
@ -142,6 +205,10 @@ class Database
require_once($driver_path);
$class = 'FW_DB_'.$database->dbdriver.'_'.$database->subdriver.'_forge';
}
else
{
throw new DatabaseException("Could not load forge. Driver file does not exist.", 1);
}
}
else
{
@ -149,7 +216,7 @@ class Database
}
// Create a new instance of set the default database
if ($newInstance)
if ($event->newInstance)
{
return new $class($database);
}
@ -163,23 +230,31 @@ class Database
* Retrieves a database utility from the provided or default database.
*
* If no database is provided, the default database will be used.
* @todo Change $newInstance behaviour with default instances.
*
*
* @param FW_DB $database
* @param FW_DB|null $database
* @param bool $newInstance
* @return FW_DB_utility
*/
public static function getUtil($database = null, $newInstance = false)
{
// First check if we're talking about the default util and that one is already set
if (is_object($database) && $database === self::$defaultDB && is_object(self::$defaultUtil))
// Fire the event to allow settings to be changed
$event = Events::fireEvent('databaseLoadUtilEvent', $database, $newInstance);
if ($event->isCancelled())
{
return false;
}
// First check if we're talking about the default util and that one is already set
if (is_object($event->util) && ($event->util instanceof FW_DB_utility))
{
return $event->util;
}
elseif (is_object($event->database) && $event->database === self::$defaultDB && is_object(self::$defaultUtil))
{
echo "CALLED";
return $reference = self::$defaultUtil;
}
if ( ! is_object($database) OR ! ($database instanceof FW_DB))
if ( ! is_object($event->database) OR ! ($event->database instanceof FW_DB))
{
isset(self::$defaultDB) OR self::get('', false);
$database = & self::$defaultDB;
@ -189,7 +264,7 @@ class Database
require_once(Core::$coreDir . DS . 'Database'.DS.'drivers'.DS.$database->dbdriver.DS.$database->dbdriver.'_utility.php');
$class = 'FW_DB_'.$database->dbdriver.'_utility';
if ($newInstance)
if ($event->newInstance)
{
return new $class($database);
}