Skip to content

Commit

Permalink
feature: dynamic or
Browse files Browse the repository at this point in the history
  • Loading branch information
g105b committed Aug 18, 2023
1 parent 180df86 commit 4e48d3d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
38 changes: 37 additions & 1 deletion src/Query/SqlQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ public function injectSpecialBindings(
/** @param array<string, string|array<string, string>> $data */
public function injectDynamicBindings(string $sql, array &$data):string {
$sql = $this->injectDynamicBindingsValueSet($sql, $data);
return $this->injectDynamicIn($sql, $data);
$sql = $this->injectDynamicIn($sql, $data);
$sql = $this->injectDynamicOr($sql, $data);
return trim($sql);
}

/** @param array<string, string|array<string, string>> $data */
Expand Down Expand Up @@ -192,6 +194,40 @@ private function injectDynamicIn(string $sql, array &$data):string {
return str_replace($matches[0], "( $replacementString )", $sql);
}

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

Check warning on line 203 in src/Query/SqlQuery.php

View check run for this annotation

Codecov / codecov/patch

src/Query/SqlQuery.php#L203

Added line #L203 was not covered by tests
}

$replacementString = "";
foreach($data["__dynamicOr"] as $i => $kvp) {
$conditionString = "";
foreach($kvp as $key => $value) {
if(is_string($value)) {
$value = str_replace("'", "''", $value);
$value = "'$value'";
}

if($conditionString) {
$conditionString .= " and ";
}
$conditionString .= "`$key` = $value";
}

if($replacementString) {
$replacementString .= " or\n";
}
$replacementString .= "\t($conditionString)";
}

$replacementString = "\n(\n$replacementString\n)\n";
return str_replace($matches[0], $replacementString, $sql);
}

/**
* @param array<string, mixed>|array<mixed> $bindings
* @return array<string, string>|array<string>
Expand Down
27 changes: 27 additions & 0 deletions test/phpunit/Query/SqlQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,33 @@ public function testDynamicBindingsWhereInStrings(
self::assertSame("2020-01-01", $data["startDate"]);
}

/**
* @dataProvider \Gt\Database\Test\Helper\Helper::queryPathNotExistsProvider()
*/
public function testDynamicBindingsOr(
string $queryName,
string $queryCollectionPath,
string $filePath,
) {
$sql = "select `id`, `customerId`, `productId` from `Purchases` where :__dynamicOr limit 10";
file_put_contents($filePath, $sql);
$query = new SqlQuery($filePath, $this->driverSingleton());
$data = [
"__dynamicOr" => [
["customerId" => "cust_105", "productId" => 001],
["customerId" => "cust_450", "productId" => 941],
["customerId" => "cust_450", "productId" => 433],
]
];
$injectedSql = $query->injectDynamicBindings($sql, $data);

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

$injectedSql = str_replace(["\t", "\n"], " ", $injectedSql);
$injectedSql = str_replace(" ", " ", $injectedSql);
self::assertStringContainsString("where ( (`customerId` = 'cust_105' and `productId` = 1) or (`customerId` = 'cust_450' and `productId` = 941) or (`customerId` = 'cust_450' and `productId` = 433) ) limit 10", $injectedSql);
}

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

0 comments on commit 4e48d3d

Please sign in to comment.