Completed
Push — master ( 597293...345e29 )
by Joao
04:12 queued 02:23
created

Repository   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 254
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 98.2%

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 6
dl 0
loc 254
ccs 109
cts 111
cp 0.982
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getMapper() 0 4 1
A getDbDriver() 0 4 1
A get() 0 10 2
A delete() 0 9 1
A deleteByQuery() 0 9 1
A getByFilter() 0 12 2
D getByQuery() 0 42 9
B save() 0 38 5
A insert() 0 9 2
A insertWithAutoinc() 0 6 1
A insertWithKeyGen() 0 7 1
A update() 0 9 1
1
<?php
2
3
namespace ByJG\MicroOrm;
4
5
use ByJG\AnyDataset\DbDriverInterface;
6
use ByJG\Serializer\BinderObject;
7
8
class Repository
9
{
10
11
    /**
12
     * @var Mapper
13
     */
14
    protected $mapper;
15
16
    /**
17
     * @var DbDriverInterface
18
     */
19
    protected $dbDriver = null;
20
21
    /**
22
     * Repository constructor.
23
     * @param DbDriverInterface $dbDataset
24
     * @param Mapper $mapper
25
     */
26 21
    public function __construct(DbDriverInterface $dbDataset, Mapper $mapper)
27
    {
28 21
        $this->dbDriver = $dbDataset;
29 21
        $this->mapper = $mapper;
30 21
    }
31
32
    /**
33
     * @return Mapper
34
     */
35 9
    public function getMapper()
36
    {
37 9
        return $this->mapper;
38
    }
39
40
    /**
41
     * @return DbDriverInterface
42
     */
43 21
    protected function getDbDriver()
44
    {
45 21
        return $this->dbDriver;
46
    }
47
48
    /**
49
     * @param array|string $pkId
50
     * @return mixed|null
51
     */
52 14
    public function get($pkId)
53
    {
54 14
        $result = $this->getByFilter($this->mapper->getPrimaryKey() . ' = [[id]]', ['id' => $pkId]);
55
56 14
        if (count($result) === 1) {
57 14
            return $result[0];
58
        }
59
60 3
        return null;
61
    }
62
63
    /**
64
     * @param array $pkId
65
     * @return mixed|null
66
     * @throws \Exception
67
     */
68 2
    public function delete($pkId)
69
    {
70 2
        $params = ['id' => $pkId];
71 2
        $updatable = Updatable::getInstance()
72 2
            ->table($this->mapper->getTable())
73 2
            ->where($this->mapper->getPrimaryKey() . ' = [[id]]', $params);
74
75 2
        return $this->deleteByQuery($updatable);
76
    }
77
78
    /**
79
     * @param $updatable
80
     * @return bool
81
     * @throws \Exception
82
     */
83 3
    public function deleteByQuery(Updatable $updatable)
84
    {
85 3
        $params = [];
86 3
        $sql = $updatable->buildDelete($params);
87
88 3
        $this->getDbDriver()->execute($sql, $params);
89
90 3
        return true;
91
    }
92
93
    /**
94
     * @param string $filter
95
     * @param array $params
96
     * @param bool $forUpdate
97
     * @return array
98
     */
99 14
    public function getByFilter($filter, array $params, $forUpdate = false)
100
    {
101 14
        $query = new Query();
102 14
        $query->table($this->mapper->getTable())
103 14
            ->where($filter, $params);
104
        
105 14
        if ($forUpdate) {
106
            $query->forUpdate();
107
        }
108
109 14
        return $this->getByQuery($query);
110
    }
111
112
    /**
113
     * @param Query $query
114
     * @param Mapper[] $mapper
115
     * @return array
116
     */
117 21
    public function getByQuery(Query $query, array $mapper = [])
118
    {
119 21
        $mapper = array_merge([$this->mapper], $mapper);
120 21
        $query = $query->build($this->getDbDriver());
121
122 21
        $params = $query['params'];
123 21
        $sql = $query['sql'];
124 21
        $result = [];
125 21
        $iterator = $this->getDbDriver()->getIterator($sql, $params);
126
127 21
        foreach ($iterator as $row) {
128 21
            $collection = [];
129 21
            foreach ($mapper as $item) {
130 21
                $instance = $item->getEntity();
131 21
                $data = $row->toArray();
132
133 21
                foreach ((array)$item->getFieldAlias() as $fieldname => $fieldalias) {
134 4
                    if (isset($data[$fieldalias])) {
135 2
                        $data[$fieldname] = $data[$fieldalias];
136 2
                        unset($fieldalias);
137 2
                    }
138 21
                }
139 21
                BinderObject::bindObject($data, $instance);
140
141 21
                foreach ((array)$item->getFieldMap() as $property => $fieldmap) {
142 10
                    $selectMask = $fieldmap[Mapper::FIELDMAP_SELECTMASK];
143 10
                    $value = "";
144 10
                    if (isset($data[$fieldmap[Mapper::FIELDMAP_FIELD]])) {
145 10
                        $value = $data[$fieldmap[Mapper::FIELDMAP_FIELD]];
146 10
                    }
147 10
                    $data[$property] = $selectMask($value, $instance);
148 21
                }
149 21
                if (count($item->getFieldMap()) > 0) {
150 10
                    BinderObject::bindObject($data, $instance);
151 10
                }
152 21
                $collection[] = $instance;
153 21
            }
154 21
            $result[] = count($collection) === 1 ? $collection[0] : $collection;
155 21
        }
156
157 21
        return $result;
158
    }
159
160
    /**
161
     * @param mixed $instance
162
     * @throws \Exception
163
     */
164 8
    public function save($instance)
165
    {
166
        // Get all fields
167 8
        $array = BinderObject::toArrayFrom($instance, true);
168 8
        $array = $this->getMapper()->prepareField($array);
169
170
        // Mapping the data
171 8
        foreach ((array)$this->getMapper()->getFieldMap() as $property => $fieldmap) {
172 3
            $fieldname = $fieldmap[Mapper::FIELDMAP_FIELD];
173 3
            $updateMask = $fieldmap[Mapper::FIELDMAP_UPDATEMASK];
174
175
            // Get the value from the mapped field name
176 3
            $value = $array[$property];
177 3
            unset($array[$property]);
178 3
            $updateValue = $updateMask($value, $instance);
179
180
            // If no value for UpdateMask, remove from the list;
181 3
            if ($updateValue === false) {
182 2
                continue;
183
            }
184 3
            $array[$fieldname] = $updateValue;
185 8
        }
186
187
        // Prepare query to insert
188 8
        $updatable = Updatable::getInstance()
189 8
            ->table($this->mapper->getTable())
190 8
            ->fields(array_keys($array));
191
192
        // Check if is insert or update
193 8
        if (empty($array[$this->mapper->getPrimaryKey()])
194 3
            || count($this->get($array[$this->mapper->getPrimaryKey()])) === 0
195 8
        ) {
196 5
            $array[$this->mapper->getPrimaryKey()] = $this->insert($updatable, $array);
197 5
            BinderObject::bindObject($array, $instance);
198 5
        } else {
199 3
            $this->update($updatable, $array);
200
        }
201 8
    }
202
203
    /**
204
     * @param \ByJG\MicroOrm\Updatable $updatable
205
     * @param array $params
206
     * @return int
207
     * @throws \Exception
208
     */
209 5
    protected function insert(Updatable $updatable, array $params)
210
    {
211 5
        $keyGen = $this->getMapper()->generateKey();
212 5
        if (empty($keyGen)) {
213 4
            return $this->insertWithAutoinc($updatable, $params);
214
        } else {
215 1
            return $this->insertWithKeyGen($updatable, $params, $keyGen);
216
        }
217
    }
218
219
    /**
220
     * @param \ByJG\MicroOrm\Updatable $updatable
221
     * @param array $params
222
     * @return int
223
     * @throws \Exception
224
     */
225 4
    protected function insertWithAutoinc(Updatable $updatable, array $params)
226
    {
227 4
        $sql = $updatable->buildInsert($params, $this->getDbDriver()->getDbHelper());
228 4
        $dbFunctions = $this->getDbDriver()->getDbHelper();
229 4
        return $dbFunctions->executeAndGetInsertedId($this->getDbDriver(), $sql, $params);
230
    }
231
232
    /**
233
     * @param \ByJG\MicroOrm\Updatable $updatable
234
     * @param array $params
235
     * @param $keyGen
236
     * @return mixed
237
     * @throws \Exception
238
     */
239 1
    protected function insertWithKeyGen(Updatable $updatable, array $params, $keyGen)
240
    {
241 1
        $params[$this->mapper->getPrimaryKey()] = $keyGen;
242 1
        $sql = $updatable->buildInsert($params, $this->getDbDriver()->getDbHelper());
243 1
        $this->getDbDriver()->execute($sql, $params);
244 1
        return $keyGen;
245
    }
246
247
    /**
248
     * @param \ByJG\MicroOrm\Updatable $updatable
249
     * @param array $params
250
     * @throws \Exception
251
     */
252 3
    protected function update(Updatable $updatable, array $params)
253
    {
254 3
        $params = array_merge($params, ['_id' => $params[$this->mapper->getPrimaryKey()]]);
255 3
        $updatable->where($this->mapper->getPrimaryKey() . ' = [[_id]] ', ['_id' => $params['_id']]);
256
257 3
        $sql = $updatable->buildUpdate($params, $this->getDbDriver()->getDbHelper());
258
259 3
        $this->getDbDriver()->execute($sql, $params);
260 3
    }
261
}
262