Passed
Push — master ( a290cb...57bf28 )
by Dawid
02:40
created

Repository::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Igni\Storage\Driver\Pdo;
4
5
use Igni\Storage\Storable;
6
use Igni\Storage\Manager;
7
use Igni\Storage\Exception\RepositoryException;
8
use Igni\Storage\Repository as RepositoryInterface;
9
10
abstract class Repository implements RepositoryInterface
11
{
12
    protected $connection;
13
    protected $entityManager;
14
    protected $hydrator;
15
    protected $metaData;
16
17 18
    final public function __construct(Connection $connection, Manager $entityManager)
18
    {
19 18
        $this->connection = $connection;
20 18
        $this->entityManager = $entityManager;
21 18
        $this->metaData = $this->entityManager->getMetaData($this->getEntityClass());
22 18
        $this->hydrator = $this->entityManager->getHydrator($this->getEntityClass());
23 18
    }
24
25 11
    public function get($id): Storable
26
    {
27 11
        if ($this->entityManager->has($this->getEntityClass(), $id)) {
28 1
            return $this->entityManager->get($this->getEntityClass(), $id);
29
        }
30
31 11
        $cursor = $this->buildSelectQuery($id);
32 11
        $cursor->setHydrator($this->hydrator);
33 11
        $entity = $cursor->current();
34 11
        $cursor->close();
35
36 11
        if (!$entity instanceof Storable) {
37 2
            throw RepositoryException::forNotFound($id);
38
        }
39
40 9
        return $entity;
41
    }
42
43 2
    public function create(Storable $entity): Storable
44
    {
45
        // Execute id auto-generation.
46 2
        $entity->getId();
47 2
        $cursor = $this->buildCreateQuery($entity);
48 2
        $cursor->execute();
49
50 2
        return $entity;
51
    }
52
53 2
    public function remove(Storable $entity): Storable
54
    {
55 2
        $cursor = $this->buildDeleteQuery($entity);
56 2
        $cursor->execute();
57
58 2
        return $entity;
59
    }
60
61 2
    public function update(Storable $entity): Storable
62
    {
63 2
        $cursor = $this->buildUpdateQuery($entity);
64 2
        $cursor->execute();
65
66 2
        return $entity;
67
    }
68
69 8
    protected function query($query, array $parameters = []): Cursor
70
    {
71 8
        $cursor = $this->connection->execute($query, $parameters);
72 8
        $cursor->setHydrator($this->hydrator);
73
74 8
        return $cursor;
75
    }
76
77 11
    protected function buildSelectQuery($id): Cursor
78
    {
79 11
        $query = sprintf(
80 11
            'SELECT *FROM %s WHERE %s = :_id',
81 11
            $this->metaData->getSource(),
82 11
            $this->metaData->getIdentifier()->getFieldName()
83
        );
84
85 11
        return $this->connection->execute($query, ['_id' => $id]);
86
    }
87
88 2
    protected function buildDeleteQuery(Storable $entity): Cursor
89
    {
90 2
        $query = sprintf(
91 2
            'DELETE FROM %s WHERE %s = :_id',
92 2
            $this->metaData->getSource(),
93 2
            $this->metaData->getIdentifier()->getFieldName()
94
        );
95 2
        return $this->connection->execute($query, ['_id' => $entity->getId()]);
96
    }
97
98 2
    protected function buildCreateQuery(Storable $entity): Cursor
99
    {
100 2
        $data = $this->hydrator->extract($entity);
101 2
        $fields = array_keys($data);
102 2
        $binds = [];
103 2
        $columns = [];
104 2
        foreach ($fields as $columnName) {
105 2
            $columns[] = "\"${columnName}\"";
106 2
            $binds[] = ":${columnName}";
107
        }
108 2
        $sql = sprintf(
109 2
            'INSERT INTO %s (%s) VALUES(%s)',
110 2
            $this->metaData->getSource(),
111 2
            implode(',', $columns),
112 2
            implode(',', $binds)
113
        );
114 2
        return $this->connection->execute($sql, $data);
115
    }
116
117
    protected function buildUpdateQuery(Storable $entity): Cursor
118
    {
119 2
        $data = $this->hydrator->extract($entity);
120 2
        $fields = array_keys($data);
121 2
        $columns = [];
122 2
        foreach ($fields as $columnName) {
123 2
            $columns[] = "\"${columnName}\" = :${columnName}";
124
        }
125 2
        $sql = sprintf(
126 2
            'UPDATE %s SET %s WHERE %s = :_id',
127 2
            $this->metaData->getSource(),
128 2
            implode(', ', $columns),
129 2
            $this->metaData->getIdentifier()->getFieldName()
130
        );
131 2
        return $this->connection->execute($sql, array_merge($data, ['_id' => $entity->getId()]));
132
    }
133
134
    abstract public function getEntityClass(): string;
135
}
136