diff --git a/src/Event/HandleDatabaseModifierEvent.php b/src/Event/HandleDatabaseModifierEvent.php new file mode 100644 index 0000000..74bbc81 --- /dev/null +++ b/src/Event/HandleDatabaseModifierEvent.php @@ -0,0 +1,34 @@ +builder = $builder; + } + + public function getBuilder(): QueryBuilder + { + return $this->builder; + } + + public function replaceBuilder(QueryBuilder $builder): void + { + $this->builder = $builder; + } +} diff --git a/src/Event/HandleModifierEvent.php b/src/Event/HandleModifierEvent.php new file mode 100644 index 0000000..af28988 --- /dev/null +++ b/src/Event/HandleModifierEvent.php @@ -0,0 +1,35 @@ +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; + } +} diff --git a/src/Exception/InvalidOptionException.php b/src/Exception/InvalidOptionException.php new file mode 100644 index 0000000..b052f10 --- /dev/null +++ b/src/Exception/InvalidOptionException.php @@ -0,0 +1,13 @@ +getModifier(); + $builder = $event->getBuilder(); + + $builder + ->setFirstResult($modifier->getOffset()) + ->setMaxResults($modifier->getCount()) + ; + } +} diff --git a/src/Handlers/Database/WithIdDatabaseHandler.php b/src/Handlers/Database/WithIdDatabaseHandler.php new file mode 100644 index 0000000..1cbb324 --- /dev/null +++ b/src/Handlers/Database/WithIdDatabaseHandler.php @@ -0,0 +1,45 @@ +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)); + ; + } +} diff --git a/src/Handlers/ModifierHandler.php b/src/Handlers/ModifierHandler.php new file mode 100644 index 0000000..b4e015e --- /dev/null +++ b/src/Handlers/ModifierHandler.php @@ -0,0 +1,10 @@ +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); + } +} diff --git a/src/Modifiers/Modifier.php b/src/Modifiers/Modifier.php new file mode 100644 index 0000000..a8ddd7c --- /dev/null +++ b/src/Modifiers/Modifier.php @@ -0,0 +1,8 @@ +id = $id instanceof \Traversable ? iterator_to_array($id) : $id; + } + + public function getId() + { + return $this->id; + } + + public function isMultiple() + { + return is_array($this->id); + } +} diff --git a/src/Provider/Database/GenericLineRepository.php b/src/Provider/Database/GenericLineRepository.php index e9bab49..66d3cc0 100644 --- a/src/Provider/Database/GenericLineRepository.php +++ b/src/Provider/Database/GenericLineRepository.php @@ -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)); } -} \ No newline at end of file + + 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(), + ]; + } +} diff --git a/src/Provider/FluentRepository.php b/src/Provider/FluentRepository.php new file mode 100644 index 0000000..e24545d --- /dev/null +++ b/src/Provider/FluentRepository.php @@ -0,0 +1,11 @@ +