fluent repository prototype
This commit is contained in:
parent
934561ca0e
commit
c1a58f4bd6
34
src/Event/HandleDatabaseModifierEvent.php
Normal file
34
src/Event/HandleDatabaseModifierEvent.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Event;
|
||||
|
||||
use App\Event\HandleModifierEvent;
|
||||
use App\Modifiers\Modifier;
|
||||
use App\Provider\Repository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class HandleDatabaseModifierEvent extends HandleModifierEvent
|
||||
{
|
||||
private $builder;
|
||||
|
||||
public function __construct(
|
||||
Modifier $modifier,
|
||||
Repository $repository,
|
||||
QueryBuilder $builder,
|
||||
array $meta = []
|
||||
) {
|
||||
parent::__construct($modifier, $repository, $meta);
|
||||
|
||||
$this->builder = $builder;
|
||||
}
|
||||
|
||||
public function getBuilder(): QueryBuilder
|
||||
{
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
public function replaceBuilder(QueryBuilder $builder): void
|
||||
{
|
||||
$this->builder = $builder;
|
||||
}
|
||||
}
|
35
src/Event/HandleModifierEvent.php
Normal file
35
src/Event/HandleModifierEvent.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Event;
|
||||
|
||||
use App\Modifiers\Modifier;
|
||||
use App\Provider\Repository;
|
||||
|
||||
class HandleModifierEvent
|
||||
{
|
||||
private $repository;
|
||||
private $modifier;
|
||||
private $meta = [];
|
||||
|
||||
public function __construct(Modifier $modifier, Repository $repository, array $meta = [])
|
||||
{
|
||||
$this->repository = $repository;
|
||||
$this->modifier = $modifier;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getModifier(): Modifier
|
||||
{
|
||||
return $this->modifier;
|
||||
}
|
||||
|
||||
public function getRepository()
|
||||
{
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
public function getMeta(): array
|
||||
{
|
||||
return $this->meta;
|
||||
}
|
||||
}
|
13
src/Exception/InvalidOptionException.php
Normal file
13
src/Exception/InvalidOptionException.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exception;
|
||||
|
||||
class InvalidOptionException extends \InvalidArgumentException
|
||||
{
|
||||
public static function invalidType($parameter, $value, array $expected = [])
|
||||
{
|
||||
return new \InvalidArgumentException(
|
||||
sprintf('Expected %s to be of type: %s. %s given.', $parameter, implode(', ', $expected), gettype($value))
|
||||
);
|
||||
}
|
||||
}
|
27
src/Handlers/Database/LimitDatabaseHandler.php
Normal file
27
src/Handlers/Database/LimitDatabaseHandler.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Handlers\Database;
|
||||
|
||||
use App\Event\HandleDatabaseModifierEvent;
|
||||
use App\Event\HandleModifierEvent;
|
||||
use App\Handlers\ModifierHandler;
|
||||
use App\Modifiers\Limit;
|
||||
|
||||
class LimitDatabaseHandler implements ModifierHandler
|
||||
{
|
||||
public function process(HandleModifierEvent $event)
|
||||
{
|
||||
if (!$event instanceof HandleDatabaseModifierEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Limit $modifier */
|
||||
$modifier = $event->getModifier();
|
||||
$builder = $event->getBuilder();
|
||||
|
||||
$builder
|
||||
->setFirstResult($modifier->getOffset())
|
||||
->setMaxResults($modifier->getCount())
|
||||
;
|
||||
}
|
||||
}
|
45
src/Handlers/Database/WithIdDatabaseHandler.php
Normal file
45
src/Handlers/Database/WithIdDatabaseHandler.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Handlers\Database;
|
||||
|
||||
use App\Handlers\ModifierHandler;
|
||||
use App\Modifiers\WithId;
|
||||
use App\Event\HandleDatabaseModifierEvent;
|
||||
use App\Event\HandleModifierEvent;
|
||||
use App\Service\IdUtils;
|
||||
use function Kadet\Functional\apply;
|
||||
use function Kadet\Functional\ref;
|
||||
|
||||
class WithIdDatabaseHandler implements ModifierHandler
|
||||
{
|
||||
/**
|
||||
* @var IdUtils
|
||||
*/
|
||||
private $id;
|
||||
|
||||
public function __construct(IdUtils $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function process(HandleModifierEvent $event)
|
||||
{
|
||||
if (!$event instanceof HandleDatabaseModifierEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var WithId $modifier */
|
||||
$modifier = $event->getModifier();
|
||||
$builder = $event->getBuilder();
|
||||
$alias = $event->getMeta()['alias'];
|
||||
$provider = $event->getMeta()['provider'];
|
||||
|
||||
$id = $modifier->getId();
|
||||
$mapper = apply([$this->id, 'generate'], $provider);
|
||||
|
||||
$builder
|
||||
->where($modifier->isMultiple() ? "{$alias} in (:id)" : "{$alias} = :id")
|
||||
->setParameter(':id', $modifier->isMultiple() ? array_map($mapper, $id) : $mapper($id));
|
||||
;
|
||||
}
|
||||
}
|
10
src/Handlers/ModifierHandler.php
Normal file
10
src/Handlers/ModifierHandler.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Handlers;
|
||||
|
||||
use App\Event\HandleModifierEvent;
|
||||
|
||||
interface ModifierHandler
|
||||
{
|
||||
public function process(HandleModifierEvent $event);
|
||||
}
|
30
src/Modifiers/Limit.php
Normal file
30
src/Modifiers/Limit.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modifiers;
|
||||
|
||||
class Limit implements Modifier
|
||||
{
|
||||
private $offset;
|
||||
private $count;
|
||||
|
||||
public function __construct(int $offset = 0, ?int $count = null)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
public function getOffset()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
public function getCount()
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
public static function count(int $count)
|
||||
{
|
||||
return new static(0, $count);
|
||||
}
|
||||
}
|
8
src/Modifiers/Modifier.php
Normal file
8
src/Modifiers/Modifier.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modifiers;
|
||||
|
||||
interface Modifier
|
||||
{
|
||||
|
||||
}
|
31
src/Modifiers/WithId.php
Normal file
31
src/Modifiers/WithId.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Modifiers;
|
||||
|
||||
use App\Exception\InvalidOptionException;
|
||||
use App\Modifiers\Modifier;
|
||||
|
||||
class WithId implements Modifier
|
||||
{
|
||||
/** @var string|array */
|
||||
private $id;
|
||||
|
||||
public function __construct($id)
|
||||
{
|
||||
if (!is_iterable($id) && !is_string($id)) {
|
||||
throw InvalidOptionException::invalidType('id', $id, ['string', 'array']);
|
||||
}
|
||||
|
||||
$this->id = $id instanceof \Traversable ? iterator_to_array($id) : $id;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function isMultiple()
|
||||
{
|
||||
return is_array($this->id);
|
||||
}
|
||||
}
|
@ -3,8 +3,15 @@
|
||||
namespace App\Provider\Database;
|
||||
|
||||
use App\Entity\LineEntity;
|
||||
use App\Event\HandleDatabaseModifierEvent;
|
||||
use App\Handlers\Database\LimitDatabaseHandler;
|
||||
use App\Handlers\Database\WithIdDatabaseHandler;
|
||||
use App\Handlers\ModifierHandler;
|
||||
use App\Model\Line;
|
||||
use App\Modifiers\Limit;
|
||||
use App\Modifiers\WithId;
|
||||
use App\Provider\LineRepository;
|
||||
use App\Modifiers\Modifier;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
use Kadet\Functional as f;
|
||||
|
||||
@ -12,25 +19,52 @@ class GenericLineRepository extends DatabaseRepository implements LineRepository
|
||||
{
|
||||
public function getAll(): Collection
|
||||
{
|
||||
$repository = $this->em->getRepository(LineEntity::class);
|
||||
$lines = $repository->findAll();
|
||||
|
||||
return collect($lines)->map(f\ref([$this, 'convert']));
|
||||
return $this->all();
|
||||
}
|
||||
|
||||
public function getById($id): ?Line
|
||||
{
|
||||
$repository = $this->em->getRepository(LineEntity::class);
|
||||
return $this->convert($repository->find($id));
|
||||
return $this->first(new WithId($id));
|
||||
}
|
||||
|
||||
public function getManyById($ids): Collection
|
||||
{
|
||||
$ids = collect($ids)->map(f\apply(f\ref([$this->id, 'generate']), $this->provider));
|
||||
|
||||
$repository = $this->em->getRepository(LineEntity::class);
|
||||
$lines = $repository->findBy(['id' => $ids->all()]);
|
||||
|
||||
return collect($lines)->map(f\ref([$this, 'convert']));
|
||||
return $this->all(new WithId($ids));
|
||||
}
|
||||
}
|
||||
|
||||
public function first(Modifier ...$modifiers)
|
||||
{
|
||||
return $this->all(Limit::count(1), ...$modifiers)->first();
|
||||
}
|
||||
|
||||
public function all(Modifier ...$modifiers)
|
||||
{
|
||||
$builder = $this->em
|
||||
->createQueryBuilder()
|
||||
->from(LineEntity::class, 'line')
|
||||
->select('line')
|
||||
;
|
||||
|
||||
foreach ($modifiers as $modifier) {
|
||||
$event = new HandleDatabaseModifierEvent($modifier, $this, $builder, [
|
||||
'alias' => 'line',
|
||||
'provider' => $this->provider,
|
||||
]);
|
||||
|
||||
$handler = $this->getHandlers()[get_class($modifier)];
|
||||
|
||||
$handler->process($event);
|
||||
}
|
||||
|
||||
return collect($builder->getQuery()->execute())->map(f\ref([$this, 'convert']));
|
||||
}
|
||||
|
||||
/** @return ModifierHandler[] */
|
||||
private function getHandlers()
|
||||
{
|
||||
return [
|
||||
WithId::class => new WithIdDatabaseHandler($this->id),
|
||||
Limit::class => new LimitDatabaseHandler(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
11
src/Provider/FluentRepository.php
Normal file
11
src/Provider/FluentRepository.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Provider;
|
||||
|
||||
use App\Modifiers\Modifier;
|
||||
|
||||
interface FluentRepository extends Repository
|
||||
{
|
||||
public function first(Modifier ...$modifiers);
|
||||
public function all(Modifier ...$modifiers);
|
||||
}
|
@ -7,10 +7,10 @@ namespace App\Provider;
|
||||
use App\Model\Line;
|
||||
use Tightenco\Collect\Support\Collection;
|
||||
|
||||
interface LineRepository extends Repository
|
||||
interface LineRepository extends FluentRepository
|
||||
{
|
||||
public function getAll(): Collection;
|
||||
|
||||
public function getById($id): ?Line;
|
||||
public function getManyById($ids): Collection;
|
||||
}
|
||||
}
|
||||
|
@ -6,5 +6,4 @@ namespace App\Provider;
|
||||
|
||||
interface Repository
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user