Skip to content

Commit

Permalink
Merge pull request #33 from KazuyaUchida/fix-sql-with-comments-can-be…
Browse files Browse the repository at this point in the history
…-executed

コメントを付与したSQLが実行されない問題の修正
  • Loading branch information
koriym authored Dec 18, 2024
2 parents 103efbc + 20a90ae commit 45b0308
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 11 deletions.
9 changes: 7 additions & 2 deletions src/QueryInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public function invoke(MethodInvocation $invocation)
}

/**
* @param array<string, mixed> $param
* @param MethodInvocation<object> $invocation
* @param array<string, mixed> $param
*
* @return mixed
*/
Expand All @@ -56,13 +57,17 @@ private function getQueryResult(MethodInvocation $invocation, QueryInterface $qu
$result = $query($param);
$object = $invocation->getThis();
if ($object instanceof ResourceObject) {
/** @var array<array-key, mixed>|object|scalar|null $result */
return $this->returnRo($object, $invocation, $result);
}

return $result;
}

/** @param mixed $result */
/**
* @param MethodInvocation<object> $invocation
* @param mixed $result
*/
private function returnRo(ResourceObject $ro, MethodInvocation $invocation, $result): ResourceObject
{
if (! $result) {
Expand Down
11 changes: 9 additions & 2 deletions src/SqlQueryRowList.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
use function array_pop;
use function count;
use function explode;
use function preg_replace;
use function strpos;
use function strtolower;
use function trim;

class SqlQueryRowList implements RowListInterface
{
public const QUERY_CLEANUP_REGEX = '/\/\*.*?\*\/|--.*$/m';
public const TRIM_CHARACTERS_REGEX = "\\ \t\n\r\0\x0B";

/** @var ExtendedPdoInterface */
private $pdo;

Expand All @@ -37,7 +41,7 @@ public function __invoke(array ...$queries): iterable
$this->sql .= ';';
}

$sqls = explode(';', trim($this->sql, "\\ \t\n\r\0\x0B"));
$sqls = explode(';', trim($this->sql, self::TRIM_CHARACTERS_REGEX));
array_pop($sqls);
$numQueris = count($queries);
if (count($sqls) !== $numQueris) {
Expand All @@ -52,7 +56,10 @@ public function __invoke(array ...$queries): iterable
}

$lastQuery = $result
? strtolower(trim((string) $result->queryString, "\\ \t\n\r\0\x0B")) : '';
? strtolower(trim(
(string) preg_replace(self::QUERY_CLEANUP_REGEX, '', (string) $result->queryString),
self::TRIM_CHARACTERS_REGEX,
)) : '';
if ($result instanceof PDOStatement && strpos($lastQuery, 'select') === 0) {
return (array) $result->fetchAll(PDO::FETCH_ASSOC);
}
Expand Down
7 changes: 7 additions & 0 deletions tests/Fake/sql/todo_item_by_id_with_comment.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* todo_item_by_id_with_comment.sql */
SELECT
*
FROM
todo /* table */
WHERE
id = :id /* conditions */
2 changes: 2 additions & 0 deletions tests/Fake/sql/todo_item_by_id_with_line_comment.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- todo_item_by_id_with_line_comment.sql
SELECT * FROM todo WHERE id = :id -- comment
1 change: 1 addition & 0 deletions tests/Fake/sql/todo_item_by_id_with_multiple_comment.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* todo_item_by_id_with_multiple_comment.sql */ SELECT * FROM todo WHERE id = :id -- conditions
39 changes: 32 additions & 7 deletions tests/SqlQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,7 @@ protected function setUp(): void
public function testInvoke(): void
{
$sql = (string) file_get_contents(__DIR__ . '/Fake/sql/todo_item_by_id.sql');
$query = new SqlQueryRowList($this->pdo, $sql);
$row = ((array) $query(['id' => 1]))[0];
assert(is_array($row));
assert(isset($row['title']));
assert(isset($row['id']));
$this->assertSame('run', $row['title']);
$this->assertSame('1', $row['id']);
$this->testSql($sql);
}

public function testNotFound(): void
Expand Down Expand Up @@ -66,4 +60,35 @@ public function testMultipleQuery(): void
$this->assertSame('test', $row['title']);
$this->assertSame('2', $row['id']);
}

public function testWithComment(): void
{
$sql = (string) file_get_contents(__DIR__ . '/Fake/sql/todo_item_by_id_with_comment.sql');
$this->testSql($sql);
}

public function testWithLineComment(): void
{
$sql = (string) file_get_contents(__DIR__ . '/Fake/sql/todo_item_by_id_with_line_comment.sql');
$this->testSql($sql);
}

public function testWithMultipleComment(): void
{
$sql = (string) file_get_contents(__DIR__ . '/Fake/sql/todo_item_by_id_with_multiple_comment.sql');
$this->testSql($sql);
}

private function testSql(string $sql): void
{
$query = new SqlQueryRowList($this->pdo, $sql);
$result = (array) $query(['id' => 1]);
$this->assertNotEmpty($result);
$row = $result[0];
$this->assertIsArray($row);
$this->assertArrayHasKey('title', $row);
$this->assertArrayHasKey('id', $row);
$this->assertSame('run', $row['title']);
$this->assertSame('1', $row['id']);
}
}

0 comments on commit 45b0308

Please sign in to comment.