Skip to content

Commit

Permalink
Enhance log messages (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
b-hayes authored Jun 6, 2023
1 parent b7ca8ba commit cc7dedb
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 34 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
run: composer install --prefer-dist --no-progress --no-suggest

- name: Run test suite
run: ./vendor/bin/phpunit
run: ./vendor/bin/phpunit tests

test_mysql80:

Expand Down Expand Up @@ -131,4 +131,4 @@ jobs:
run: composer install --prefer-dist --no-progress --no-suggest

- name: Run test suite
run: ./vendor/bin/phpunit
run: ./vendor/bin/phpunit tests
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@
"phpunit/phpunit": "6.5.14"
},
"scripts": {
"test": "phpunit"
"test": "phpunit tests"
}
}
35 changes: 32 additions & 3 deletions lib/PicoDb/StatementHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ class StatementHandler
*/
protected $logQueries = false;

/**
* Flag to combine values in the logged SQL queries.
*
* @access protected
* @var boolean
*/
protected $logQueryValues = false;

/**
* Run explain command on each query
*
Expand Down Expand Up @@ -125,10 +133,12 @@ public function __construct(Database $db)
* Enable query logging
*
* @access public
* @param bool $includeValues
* @return $this
*/
public function withLogging()
public function withLogging(bool $includeValues = false)
{
$this->logQueryValues = $includeValues;
$this->logQueries = true;
return $this;
}
Expand Down Expand Up @@ -229,6 +239,7 @@ public function getNbQueries()
*
* @access public
* @return PDOStatement|false
* @throws SQLException
*/
public function execute()
{
Expand Down Expand Up @@ -285,7 +296,26 @@ protected function bindParams(PDOStatement $pdoStatement)
protected function beforeExecute()
{
if ($this->logQueries) {
$this->db->setLogMessage($this->sql);
$sql = $this->sql;
if ($this->logQueryValues) {
$params = $this->lobParams ?: $this->positionalParams ?: $this->namedParams;

if ($this->useNamedParams) {
$sql = preg_replace_callback('/:([a-zA-Z0-9_]+)/', function ($matches) use ($params) {
$paramName = $matches[1];
$replacement = $params[$paramName] ?? $matches[0];
return "'$replacement'";
}, $sql);
} else {
$i = 0;
$sql = preg_replace_callback('/\?/', function($matches) use ($params, &$i) {
$replacement = $params[$i] ?? '';
$i++;
return "'$replacement'";
}, $sql);
}
}
$this->db->setLogMessage($sql);
}

if ($this->stopwatch) {
Expand Down Expand Up @@ -335,7 +365,6 @@ protected function cleanup()
*
* @access public
* @param PDOException $e
* @return bool
* @throws SQLException
*/
public function handleSqlError(PDOException $e)
Expand Down
28 changes: 0 additions & 28 deletions phpunit.xml.dist

This file was deleted.

106 changes: 106 additions & 0 deletions tests/PicoDb/StatementHandlerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php
declare(strict_types=1);

namespace PicoDb;

use PHPUnit\Framework\TestCase;

class StatementHandlerTest extends TestCase
{
/**
* @var Database
*/
private $db;

protected function setUp()
{
$this->db = new Database(array('driver' => 'sqlite', 'filename' => ':memory:'));
$this->statementHandler = new StatementHandler($this->db);
parent::setUp();
}


public function testBeforeExecuteLogs()
{
// create an anon class that extends statement handler
$statementHandler = new class($this->db) extends StatementHandler {

/**
* A wrapper to set the state of the class before running the protected var.
*
* @param array{
* 'logQueries': boolean,
* 'logQueryValues': boolean,
* 'sql': string,
* 'lobParams': array,
* 'positionalParams': array,
* 'namedParams': array
* } $props
* @return void
*/
public function testBeforeExecute(array $props)
{
foreach ($props as $key => $value) {
$this->{$key} = $value;
}
$this->beforeExecute();
}
};

$statementHandler->testBeforeExecute([
'logQueries' => true,
'logQueryValues' => true,
'useNamedParams' => false,
'sql' => "SELECT * FROM `some_table` WHERE `someCoumn` = ? and `someOtherColumn` = ?",
'lobParams' => ['first value has a ? inside it', 'second value'],
'positionalParams' => [],
'namedParams' => []
]);

$logMessages = $this->db->getLogMessages();
self::assertCount(1, $logMessages);
self::assertEquals(
"SELECT * FROM `some_table` WHERE `someCoumn` = 'first value has a ? inside it' and `someOtherColumn` = 'second value'",
$logMessages[0],
var_export($logMessages, true)
);


// now test with positional params
$statementHandler->testBeforeExecute([
'logQueries' => true,
'logQueryValues' => true,
'sql' => "SELECT * FROM `some_table` WHERE `someCoumn` = ? and `someOtherColumn` = ?",
'lobParams' => [],
'positionalParams' => ['first value has a ? inside it', 'second value'],
'namedParams' => []
]);

$logMessages = $this->db->getLogMessages();
self::assertCount(2, $logMessages);
self::assertEquals(
"SELECT * FROM `some_table` WHERE `someCoumn` = 'first value has a ? inside it' and `someOtherColumn` = 'second value'",
$logMessages[1],
var_export($logMessages, true)
);

// now test with named params
$statementHandler->testBeforeExecute([
'logQueries' => true,
'logQueryValues' => true,
'useNamedParams' => true,
'sql' => "SELECT * FROM `some_table` WHERE `someCoumn` = :first and `someOtherColumn` = :second",
'lobParams' => [],
'positionalParams' => [],
'namedParams' => ['first' => 'first value has :second inside it', 'second' => 'second value']
]);

$logMessages = $this->db->getLogMessages();
self::assertCount(3, $logMessages);
self::assertEquals(
"SELECT * FROM `some_table` WHERE `someCoumn` = 'first value has :second inside it' and `someOtherColumn` = 'second value'",
$logMessages[2],
var_export($logMessages, true)
);
}
}

0 comments on commit cc7dedb

Please sign in to comment.