Reorganize query logging and add detailed comments

This commit is contained in:
Kijin Sung 2020-06-30 23:21:14 +09:00
parent 8a3afa03cc
commit 6e7049234e
2 changed files with 53 additions and 22 deletions

View file

@ -8,6 +8,9 @@ use Rhymix\Framework\Exceptions\DBError;
/** /**
* DB helper class. * DB helper class.
*
* We use instances of this class instead of raw PDO in order to provide
* better logging and error handling while keeping backward compatibility.
*/ */
class DBHelper extends \PDO class DBHelper extends \PDO
{ {
@ -38,23 +41,32 @@ class DBHelper extends \PDO
try try
{ {
if ($driver_options) /**
{ * $stmt will be an instance of DBStmtHelper.
$stmt = parent::prepare($statement, $driver_options); * This allows it to track the parent database's type
} * and send query logs to the appropriate place.
else */
{ $stmt = $driver_options ? parent::prepare($statement, $driver_options) : parent::prepare($statement);
$stmt = parent::prepare($statement);
}
$stmt->setFetchMode(\PDO::FETCH_OBJ); $stmt->setFetchMode(\PDO::FETCH_OBJ);
$stmt->setType($this->_type); $stmt->setType($this->_type);
$db_class->clearError();
} }
catch (\PDOException $e) catch (\PDOException $e)
{ {
/**
* We only measure the time when the prepared statement fails.
* If the statement is successfully prepared, time will be measured
* when the statement is executed in DBStmtHelper.
*/
$elapsed_time = microtime(true) - $start_time; $elapsed_time = microtime(true) - $start_time;
$db_class->addElapsedTime($elapsed_time); $db_class->addElapsedTime($elapsed_time);
$db_class->setError(-1, $e->getMessage()); $db_class->setError(-1, $e->getMessage());
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time)); Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
/**
* This is a new feature in Rhymix 2.0 so we don't have to mess
* with status objects. We just throw an exception. Catch it!
*/
throw new DBError($e->getMessage(), 0, $e); throw new DBError($e->getMessage(), 0, $e);
} }
@ -64,6 +76,10 @@ class DBHelper extends \PDO
/** /**
* Execute a query. * Execute a query.
* *
* This method accepts additional parameters, but they are not for creating
* prepared statements. They exist because PDO's own query() method accepts
* various kinds of additional parameters, and we don't want to touch them.
*
* @param string $statement * @param string $statement
* @return PDOStatement|DBStmtHelper * @return PDOStatement|DBStmtHelper
*/ */
@ -76,6 +92,11 @@ class DBHelper extends \PDO
try try
{ {
/**
* $stmt will be an instance of DBStmtHelper.
* This allows it to track the parent database's type
* and send query logs to the appropriate place.
*/
$stmt = parent::query($statement, ...$args); $stmt = parent::query($statement, ...$args);
$stmt->setFetchMode(\PDO::FETCH_OBJ); $stmt->setFetchMode(\PDO::FETCH_OBJ);
$stmt->setType($this->_type); $stmt->setType($this->_type);
@ -85,10 +106,12 @@ class DBHelper extends \PDO
{ {
$db_class->setError(-1, $e->getMessage()); $db_class->setError(-1, $e->getMessage());
} }
finally
$elapsed_time = microtime(true) - $start_time; {
$db_class->addElapsedTime($elapsed_time); $elapsed_time = microtime(true) - $start_time;
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time)); $db_class->addElapsedTime($elapsed_time);
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
}
return $stmt; return $stmt;
} }
@ -113,10 +136,12 @@ class DBHelper extends \PDO
{ {
$db_class->setError(-1, $e->getMessage()); $db_class->setError(-1, $e->getMessage());
} }
finally
$elapsed_time = microtime(true) - $start_time; {
$db_class->addElapsedTime($elapsed_time); $elapsed_time = microtime(true) - $start_time;
Debug::addQuery($db_class->getQueryLog($query, $elapsed_time)); $db_class->addElapsedTime($elapsed_time);
Debug::addQuery($db_class->getQueryLog($query, $elapsed_time));
}
return $result; return $result;
} }

View file

@ -8,6 +8,10 @@ use Rhymix\Framework\Exceptions\DBError;
/** /**
* DB Statement helper class. * DB Statement helper class.
*
* We use instances of this class instead of raw PDOStatement in order to log
* individual execute() calls of prepared statements. This is controlled by
* the PDO::ATTR_STATEMENT_CLASS attribute set in the DB class.
*/ */
class DBStmtHelper extends \PDOStatement class DBStmtHelper extends \PDOStatement
{ {
@ -27,6 +31,10 @@ class DBStmtHelper extends \PDOStatement
/** /**
* Execute a prepared statement. * Execute a prepared statement.
* *
* We don't set a type for $input_parameters because the original
* PDOStatement class accepts both arrays and null. Actually, the null
* value must be omitted altogether or it will throw an error.
*
* @param array $input_parameters * @param array $input_parameters
* @return bool * @return bool
*/ */
@ -39,19 +47,17 @@ class DBStmtHelper extends \PDOStatement
{ {
$result = parent::execute($input_parameters); $result = parent::execute($input_parameters);
$db_class->clearError(); $db_class->clearError();
$elapsed_time = microtime(true) - $start_time;
$db_class->addElapsedTime($elapsed_time);
Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time));
} }
catch (\PDOException $e) catch (\PDOException $e)
{ {
$db_class->setError(-1, $e->getMessage()); $db_class->setError(-1, $e->getMessage());
throw new DBError($e->getMessage(), 0, $e);
}
finally
{
$elapsed_time = microtime(true) - $start_time; $elapsed_time = microtime(true) - $start_time;
$db_class->addElapsedTime($elapsed_time); $db_class->addElapsedTime($elapsed_time);
Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time)); Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time));
throw new DBError($e->getMessage(), 0, $e);
} }
return $result; return $result;