Using DQL 'ILIKE' implementation instead of 'LIKE' for search.
This commit is contained in:
parent
7d6b777603
commit
5109227b25
|
@ -41,3 +41,6 @@ doctrine:
|
|||
dir: '%kernel.project_dir%/src/Magnetico/Entity'
|
||||
prefix: 'App\Magnetico'
|
||||
alias: Magnetico
|
||||
dql:
|
||||
string_functions:
|
||||
ILIKE: 'App\Doctrine\ORM\AST\Ilike'
|
||||
|
|
73
src/Doctrine/ORM/AST/BaseFunction.php
Normal file
73
src/Doctrine/ORM/AST/BaseFunction.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Doctrine\ORM\AST;
|
||||
|
||||
use Doctrine\ORM\Query\{AST\Functions\FunctionNode, AST\Node, Lexer, Parser, SqlWalker};
|
||||
|
||||
/**
|
||||
* @since 0.1
|
||||
*
|
||||
* @author Martin Georgiev <martin.georgiev@gmail.com>
|
||||
* @see https://github.com/martin-georgiev/postgresql-for-doctrine
|
||||
*/
|
||||
abstract class BaseFunction extends FunctionNode
|
||||
{
|
||||
/** @var string */
|
||||
protected $functionPrototype;
|
||||
|
||||
/** @var string[] */
|
||||
protected $nodesMapping = [];
|
||||
|
||||
/** @var Node[] */
|
||||
protected $nodes = [];
|
||||
|
||||
abstract protected function customiseFunction(): void;
|
||||
|
||||
protected function setFunctionPrototype(string $functionPrototype): void
|
||||
{
|
||||
$this->functionPrototype = $functionPrototype;
|
||||
}
|
||||
|
||||
protected function addNodeMapping(string $parserMethod): void
|
||||
{
|
||||
$this->nodesMapping[] = $parserMethod;
|
||||
}
|
||||
|
||||
public function parse(Parser $parser): void
|
||||
{
|
||||
$this->customiseFunction();
|
||||
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
$this->feedParserWithNodes($parser);
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Feeds given parser with previously set nodes.
|
||||
*/
|
||||
protected function feedParserWithNodes(Parser $parser): void
|
||||
{
|
||||
$nodesMappingCount = \count($this->nodesMapping);
|
||||
$lastNode = $nodesMappingCount - 1;
|
||||
for ($i = 0; $i < $nodesMappingCount; $i++) {
|
||||
$parserMethod = $this->nodesMapping[$i];
|
||||
$this->nodes[$i] = $parser->{$parserMethod}();
|
||||
if ($i < $lastNode) {
|
||||
$parser->match(Lexer::T_COMMA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getSql(SqlWalker $sqlWalker): string
|
||||
{
|
||||
$dispatched = [];
|
||||
foreach ($this->nodes as $node) {
|
||||
$dispatched[] = $node->dispatch($sqlWalker);
|
||||
}
|
||||
|
||||
return \vsprintf($this->functionPrototype, $dispatched);
|
||||
}
|
||||
}
|
25
src/Doctrine/ORM/AST/Ilike.php
Normal file
25
src/Doctrine/ORM/AST/Ilike.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Doctrine\ORM\AST;
|
||||
|
||||
/**
|
||||
* Implementation of PostgreSql ILIKE().
|
||||
*
|
||||
* For usage example @see https://github.com/martin-georgiev/postgresql-for-doctrine/blob/master/docs/USE-CASES-AND-EXAMPLES.md
|
||||
*
|
||||
* @see https://www.postgresql.org/docs/9.3/functions-matching.html
|
||||
*
|
||||
* @author llaakkkk <lenakirichokv@gmail.com>
|
||||
* @see https://github.com/martin-georgiev/postgresql-for-doctrine
|
||||
*/
|
||||
class Ilike extends BaseFunction
|
||||
{
|
||||
protected function customiseFunction(): void
|
||||
{
|
||||
$this->setFunctionPrototype('%s ilike %s');
|
||||
$this->addNodeMapping('StringPrimary');
|
||||
$this->addNodeMapping('StringPrimary');
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ class TorrentSearcher
|
|||
$where = $qb->expr()->andX();
|
||||
|
||||
foreach ($this->splitQueryToParts($query) as $idx => $part) {
|
||||
$where->add($qb->expr()->like('LOWER(t.name)', ':part_'.$idx));
|
||||
$where->add('ILIKE(t.name , :part_'.$idx.') = TRUE');
|
||||
$qb->setParameter('part_'.$idx, '%'.strtolower($part).'%');
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue