Merged in upgrade_and_refactoring (pull request #29)

Updating dependencies and implementing ILIKE for DQL.
This commit is contained in:
Alexey Eschenko 2019-10-20 21:31:18 +00:00
commit a722dd4653
9 changed files with 631 additions and 465 deletions

View File

@ -19,6 +19,7 @@
"sentry/sentry-symfony": "^2.2",
"symfony/console": "^4.1",
"symfony/dotenv": "^4.1",
"symfony/expression-language": "^4.1",
"symfony/flex": "^1.0",
"symfony/form": "^4.1",
"symfony/framework-bundle": "^4.1",

972
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -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'

View File

@ -43,4 +43,4 @@ services:
# Torrent searcher
App\Search\TorrentSearcher:
arguments:
$em: '@doctrine.orm.magneticod_entity_manager'
$classMetadata: '@=service(''doctrine.orm.magneticod_entity_manager'').getClassMetadata(''App\\Magnetico\\Entity\\Torrent'')'

View 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);
}
}

View 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');
}
}

View File

@ -2,9 +2,8 @@
namespace App\Search;
use App\Magnetico\Entity\Torrent;
use App\Magnetico\Repository\TorrentRepository;
use Doctrine\ORM\{EntityManagerInterface, QueryBuilder};
use Doctrine\ORM\{Mapping\ClassMetadata, QueryBuilder};
class TorrentSearcher
{
@ -13,13 +12,13 @@ class TorrentSearcher
/** @var TorrentRepository */
private $torrentRepo;
/** @var EntityManagerInterface */
private $em;
/** @var ClassMetadata */
private $classMetadata;
public function __construct(TorrentRepository $torrentRepo, EntityManagerInterface $em)
public function __construct(TorrentRepository $torrentRepo, ClassMetadata $classMetadata)
{
$this->torrentRepo = $torrentRepo;
$this->em = $em;
$this->classMetadata = $classMetadata;
}
public function createSearchQueryBuilder(string $query, string $orderBy = null, string $order = 'asc'): QueryBuilder
@ -40,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).'%');
}
@ -64,7 +63,7 @@ class TorrentSearcher
{
return (
!\in_array($orderBy, self::ORDER_DISABLED_FIELDS, true)
&& $this->em->getClassMetadata(Torrent::class)->hasField($orderBy)
&& $this->classMetadata->hasField($orderBy)
);
}
@ -76,4 +75,4 @@ class TorrentSearcher
return explode(' ', $query);
}
}
}

View File

@ -158,6 +158,9 @@
"symfony/event-dispatcher-contracts": {
"version": "v1.1.5"
},
"symfony/expression-language": {
"version": "v4.3.5"
},
"symfony/filesystem": {
"version": "v4.1.0"
},

Binary file not shown.