Skip to content

Commit

Permalink
feature: implement dynamic in
Browse files Browse the repository at this point in the history
closes #347
  • Loading branch information
g105b committed Aug 15, 2023
1 parent 0492885 commit 8fd2602
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
26 changes: 22 additions & 4 deletions src/Query/SqlQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,22 @@ public function injectSpecialBindings(
}

public function injectDynamicBindings(string $sql, array &$data):string {
$sql = $this->injectDynamicBindingsValueset($sql, $data);
$sql = $this->injectDynamicBindingsValueSet($sql, $data);
$sql = $this->injectDynamicIn($sql, $data);
return $sql;
}

private function injectDynamicBindingsValueset($sql, &$data):string {
private function injectDynamicBindingsValueSet(string $sql, array &$data):string {
$pattern = '/\(\s*:__dynamicValueSet\s\)/';
if(!preg_match($pattern, $sql, $matches)) {
return $sql;
}
if(!isset($data["__dynamicValueSet"])) {
return $sql;
}

$replacementRowList = [];
$originalKeys = array_keys($data[0]);
foreach($data as $i => $kvp) {
foreach($data["__dynamicValueSet"] as $i => $kvp) {
$indexedRow = [];
foreach($kvp as $key => $value) {
$indexedKey = $key . "_" . str_pad($i, 5, "0", STR_PAD_LEFT);
Expand All @@ -141,6 +144,7 @@ private function injectDynamicBindingsValueset($sql, &$data):string {
unset($data[$i]);
array_push($replacementRowList, $indexedRow);
}
unset($data["__dynamicValueSet"]);

$replacementString = "";
foreach($replacementRowList as $i => $indexedKeyList) {
Expand All @@ -160,6 +164,20 @@ private function injectDynamicBindingsValueset($sql, &$data):string {
return str_replace($matches[0], $replacementString, $sql);
}

private function injectDynamicIn(string $sql, array &$data):string {
$pattern = '/\(\s*:__dynamicIn\s\)/';
if(!preg_match($pattern, $sql, $matches)) {
return $sql;
}
if(!isset($data["__dynamicIn"])) {
return $sql;
}

$replacementString = implode(", ", $data["__dynamicIn"]);
unset($data["__dynamicIn"]);
return str_replace($matches[0], "( $replacementString )", $sql);
}

/**
* @param array<string, mixed>|array<mixed> $bindings
* @return array<string, string>|array<string>
Expand Down
38 changes: 34 additions & 4 deletions test/phpunit/Query/SqlQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,11 @@ public function testDynamicBindingsInsertMultiple(
file_put_contents($filePath, $sql);
$query = new SqlQuery($filePath, $this->driverSingleton());
$data = [
["id" => 100, "name" => "first inserted"],
["id" => 101, "name" => "second inserted"],
["id" => 102, "name" => "third inserted"],
"__dynamicValueSet" => [
["id" => 100, "name" => "first inserted"],
["id" => 101, "name" => "second inserted"],
["id" => 102, "name" => "third inserted"],
],
];
$originalData = $data;
$injectedSql = $query->injectDynamicBindings($sql, $data);
Expand All @@ -329,13 +331,41 @@ public function testDynamicBindingsInsertMultiple(
self::assertStringContainsString(":name_00001", $injectedSql);
self::assertStringContainsString(":name_00002", $injectedSql);

foreach($originalData as $i => $kvp) {
foreach($originalData["__dynamicValueSet"] as $i => $kvp) {
foreach($kvp as $key => $value) {
$indexedKey = $key . "_" . str_pad($i, 5, "0", STR_PAD_LEFT);
self::assertSame($data[$indexedKey], $value);
}
}

self::assertArrayNotHasKey("__dynamicValueSet", $data);
}

/**
* @dataProvider \Gt\Database\Test\Helper\Helper::queryPathNotExistsProvider()
*/
public function testDynamicBindingsWhereIn(
string $queryName,
string $queryCollectionPath,
string $filePath
) {
$sql = "select `id`, `name` from `test_table` where `createdAt` > :startDate and `id` in ( :__dynamicIn ) limit 10";
file_put_contents($filePath, $sql);
$query = new SqlQuery($filePath, $this->driverSingleton());
$data = [
"startDate" => "2020-01-01",
"__dynamicIn" => [1, 2, 3, 4, 5, 50, 60, 70, 80, 90],
];
$originalData = $data;
$injectedSql = $query->injectDynamicBindings($sql, $data);

self::assertStringNotContainsString("dynamicIn", $injectedSql);

self::assertStringContainsString("where `createdAt` > :startDate and `id` in ( 1, 2, 3, 4, 5, 50, 60, 70, 80, 90 ) limit 10", $injectedSql);
self::assertArrayNotHasKey("__dynamicIn", $data);
self::assertSame("2020-01-01", $data["startDate"]);
}

/**
* @dataProvider \Gt\Database\Test\Helper\Helper::queryPathNotExistsProvider()
*/
Expand Down

0 comments on commit 8fd2602

Please sign in to comment.