Skip to content

Commit

Permalink
fix: BaseBuilder::getOperator() doesn't recognize LIKE operator in ar…
Browse files Browse the repository at this point in the history
…ray expression
  • Loading branch information
kenjis committed Dec 17, 2022
1 parent f51e8ef commit fe964ec
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
35 changes: 34 additions & 1 deletion system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ protected function whereHaving(string $qbKey, $key, $value = null, string $type
$k = '';
$op = '';
} elseif ($v !== null) {
$op = $this->getOperator($k, true);
$op = $this->getOperatorFromWhereKey($k);

if (! empty($op)) {
$k = trim($k);
Expand Down Expand Up @@ -3387,6 +3387,39 @@ protected function getOperator(string $str, bool $list = false)
) ? ($list ? $match[0] : $match[0][0]) : false;
}

/**
* Returns the SQL string operator from where key
*
* @return array<int, string>|false
* @phpstan-return list<string>|false
*/
private function getOperatorFromWhereKey(string $whereKey)
{
$whereKey = trim($whereKey);

if ($this->pregOperators === []) {
$likeEscapeStr = ($this->db->likeEscapeStr !== '')
? '\s+' . preg_quote(trim(sprintf($this->db->likeEscapeStr, $this->db->likeEscapeChar)), '/')
: '';

$this->pregOperators = [
'\s*(?:<|>|!)?=', // =, <=, >=, !=
'\s*<>?', // <, <>
'\s*>', // >
'\s+IS NULL', // IS NULL
'\s+IS NOT NULL', // IS NOT NULL
'\s+LIKE', // LIKE
'\s+NOT LIKE', // NOT LIKE
];
}

return preg_match_all(
'/' . implode('|', $this->pregOperators) . '/i',
$whereKey,
$match
) ? $match[0] : false;
}

/**
* Stores a bind value after ensuring that it's unique.
* While it might be nicer to have named keys for our binds array
Expand Down
14 changes: 14 additions & 0 deletions tests/system/Database/Builder/WhereTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,20 @@ public function testWhereAssociateArrayKeyHasEqualValueIsNull()
$this->assertSame($expectedBinds, $builder->getBinds());
}

public function testWhereLikeInAssociateArray()
{
$builder = $this->db->table('user');

$where = [
'id <' => 100,
'col1 LIKE' => '%gmail%',
];
$builder->where($where);

$expectedSQL = 'SELECT * FROM "user" WHERE "id" < 100 AND "col1" LIKE \'%gmail%\'';
$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
}

public function testWhereCustomString()
{
$builder = $this->db->table('jobs');
Expand Down

0 comments on commit fe964ec

Please sign in to comment.