Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.49% covered (success)
91.49%
43 / 47
75.00% covered (warning)
75.00%
9 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
GroupedDataLayer
91.49% covered (success)
91.49%
43 / 47
75.00% covered (warning)
75.00%
9 / 12
17.18
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isSupported
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
4.25
 getFilterColumns
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 getOrderByColumns
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 all
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 find
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getMetadata
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 dispatch
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 persistNew
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 persistExisting
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 removeExisting
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 upsert
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Apie\Core\Datalayers;
3
4use Apie\Core\BoundedContext\BoundedContextId;
5use Apie\Core\Datalayers\Events\EntityPersisted;
6use Apie\Core\Datalayers\Grouped\DataLayerByBoundedContext;
7use Apie\Core\Datalayers\Lists\EntityListInterface;
8use Apie\Core\Entities\EntityInterface;
9use Apie\Core\Identifiers\IdentifierInterface;
10use Apie\Core\Lists\StringSet;
11use Psr\EventDispatcher\EventDispatcherInterface;
12use ReflectionClass;
13
14final class GroupedDataLayer implements ApieDatalayerWithFilters, ApieDatalayer, ApieDatalayerWithSupport
15{
16    public function __construct(
17        private readonly DataLayerByBoundedContext $hashmap,
18        private readonly EventDispatcherInterface $dispatcher
19    ) {
20    }
21
22    public function isSupported(EntityInterface|ReflectionClass|IdentifierInterface $instance, BoundedContextId $boundedContextId): bool
23    {
24        if ($instance instanceof EntityInterface) {
25            $instance = $instance->getId()->getReferenceFor();
26        } elseif ($instance instanceof IdentifierInterface) {
27            $instance = $instance->getReferenceFor();
28        }
29        $datalayer = $this->hashmap->pickDataLayerFor($instance, $boundedContextId);
30        if ($datalayer instanceof ApieDatalayerWithSupport) {
31            return $datalayer->isSupported($instance, $boundedContextId);
32        }
33        return true;
34    }
35
36    public function getFilterColumns(ReflectionClass $class, BoundedContextId $boundedContextId): ?StringSet
37    {
38        $datalayer = $this->hashmap->pickDataLayerFor($class, $boundedContextId);
39        if ($datalayer instanceof ApieDatalayerWithFilters) {
40            return $datalayer->getFilterColumns($class, $boundedContextId);
41        }
42        return null;
43    }
44
45    public function getOrderByColumns(ReflectionClass $class, BoundedContextId $boundedContextId): ?StringSet
46    {
47        $datalayer = $this->hashmap->pickDataLayerFor($class, $boundedContextId);
48        if ($datalayer instanceof ApieDatalayerWithFilters) {
49            return $datalayer->getOrderByColumns($class, $boundedContextId);
50        }
51        return null;
52    }
53
54    public function all(ReflectionClass $class, ?BoundedContextId $boundedContextId = null): EntityListInterface
55    {
56        return $this->hashmap->pickDataLayerFor($class, $boundedContextId)
57            ->all($class, $boundedContextId);
58    }
59
60    public function find(IdentifierInterface $identifier, ?BoundedContextId $boundedContextId = null): EntityInterface
61    {
62        return $this->hashmap->pickDataLayerFor($identifier::getReferenceFor(), $boundedContextId)
63            ->find($identifier, $boundedContextId);
64    }
65
66    /**
67     * @template T of EntityInterface
68     * @param IdentifierInterface<T> $identifier
69     */
70    public function getMetadata(
71        IdentifierInterface $identifier,
72        ?BoundedContextId $boundedContextId = null
73    ): DataLayerMetadata {
74        return $this->hashmap->pickDataLayerFor($identifier::getReferenceFor(), $boundedContextId)
75            ->getMetadata($identifier, $boundedContextId);
76    }
77
78    private function dispatch(EntityInterface $entity, ?BoundedContextId $boundedContextId = null): EntityInterface
79    {
80        $this->dispatcher->dispatch(
81            new EntityPersisted(
82                $entity,
83                $boundedContextId
84            )
85        );
86        return $entity;
87    }
88
89    public function persistNew(EntityInterface $entity, ?BoundedContextId $boundedContextId = null): EntityInterface
90    {
91        return $this->dispatch(
92            $this->hashmap->pickDataLayerFor($entity->getId()::getReferenceFor(), $boundedContextId)
93                ->persistNew($entity, $boundedContextId),
94            $boundedContextId
95        );
96    }
97
98    public function persistExisting(EntityInterface $entity, ?BoundedContextId $boundedContextId = null): EntityInterface
99    {
100        return $this->dispatch(
101            $this->hashmap->pickDataLayerFor($entity->getId()::getReferenceFor(), $boundedContextId)
102                ->persistExisting($entity, $boundedContextId),
103            $boundedContextId
104        );
105    }
106    
107    public function removeExisting(EntityInterface $entity, ?BoundedContextId $boundedContextId = null): void
108    {
109        $this->hashmap->pickDataLayerFor($entity->getId()::getReferenceFor(), $boundedContextId)
110            ->removeExisting($entity, $boundedContextId);
111    }
112
113    public function upsert(EntityInterface $entity, ?BoundedContextId $boundedContextId): EntityInterface
114    {
115        return $this->dispatch(
116            $this->hashmap->pickDataLayerFor($entity->getId()::getReferenceFor(), $boundedContextId)
117                ->upsert($entity, $boundedContextId),
118            $boundedContextId
119        );
120    }
121}