Completed
Push — master ( 13b38a...f07239 )
by Joao
02:35
created

Repository::getByQuery()   C

Complexity

Conditions 7
Paths 28

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 25
cts 25
cp 1
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 20
nc 28
nop 2
crap 7
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: jg
5
 * Date: 21/06/16
6
 * Time: 16:17
7
 */
8
9
namespace ByJG\MicroOrm;
10
11
12
use ByJG\AnyDataset\DbDriverInterface;
13
use ByJG\Serializer\BinderObject;
14
15
class Repository
16
{
17
18
    /**
19
     * @var Mapper
20
     */
21
    protected $mapper;
22
23
    /**
24
     * @var DbDriverInterface
25
     */
26
    protected $dbDriver = null;
27
28
    protected $limitStart = null;
29
    protected $limitEnd = null;
30
    protected $top = null;
31
32
    /**
33
     * Repository constructor.
34
     * @param DbDriverInterface $dbDataset
35
     * @param Mapper $mapper
36
     */
37 10
    public function __construct(DbDriverInterface $dbDataset, Mapper $mapper)
38
    {
39 10
        $this->dbDriver = $dbDataset;
40 10
        $this->mapper = $mapper;
41 10
    }
42
43
    /**
44
     * @return Mapper
45
     */
46
    public function getMapper()
47
    {
48
        return $this->mapper;
49
    }
50
51
    /**
52
     * @return DbDriverInterface
53
     */
54 10
    protected function getDbDriver()
55
    {
56 10
        return $this->dbDriver;
57
    }
58
59
    /**
60
     * @param array|string $id
61
     * @return mixed|null
62
     */
63 5
    public function get($id)
64
    {
65 5
        $result = $this->getByFilter($this->mapper->getPrimaryKey() . ' = [[id]]', ['id' => $id]);
66
67 5
        if (count($result) === 1) {
68 5
            return $result[0];
69
        }
70
71 2
        return null;
72
    }
73
74
    /**
75
     * @param array $id
76
     * @return mixed|null
77
     */
78 1
    public function delete($id)
79
    {
80 1
        $params = ['id' => $id];
81 1
        $query = new Query();
82 1
        $query->table($this->mapper->getTable())
83 1
            ->where($this->mapper->getPrimaryKey() . ' = [[id]]', $params);
84
85 1
        return $this->deleteByQuery($query);
86
    }
87
88
    /**
89
     * @param $query
90
     * @return bool
91
     */
92 2
    public function deleteByQuery($query)
93
    {
94 2
        $delete = $query->getDelete();
95 2
        $sql = $delete['sql'];
96 2
        $params = $delete['params'];
97
98 2
        $this->getDbDriver()->execute($sql, $params);
99
100 2
        return true;
101
    }
102
103 1
    public function limit($start, $end)
104
    {
105 1
        $this->limitStart = $start;
106 1
        $this->limitEnd = $end;
107 1
        $this->top = null;
108 1
        return $this;
109
    }
110
111 1
    public function top($top)
112
    {
113 1
        $this->top = $top;
114 1
        $this->limitStart = $this->limitEnd = null;
115
116 1
        return $this;
117
    }
118
119
    /**
120
     * @param string $filter
121
     * @param array $params
122
     * @param bool $forUpdate
123
     * @return array
124
     */
125 5
    public function getByFilter($filter, array $params, $forUpdate = false)
126
    {
127 5
        $query = new Query();
128 5
        $query->table($this->mapper->getTable())
129 5
            ->where($filter, $params);
130
        
131 5
        if ($forUpdate) {
132
            $query->forUpdate();
133
        }
134
135 5
        return $this->getByQuery($query);
136
    }
137
138
    /**
139
     * @param Query $query
140
     * @param Mapper[] $mapper
141
     * @return array
142
     */
143 10
    public function getByQuery(Query $query, array $mapper = [])
144
    {
145 10
        $mapper = array_merge([$this->mapper], $mapper);
146 10
        $query = $query->getSelect();
147
148 10
        if (!empty($this->top)) {
149 1
            $query['sql'] = $this->getDbDriver()->getDbHelper()->top($query['sql'], $this->top);
150 1
        }
151
152 10
        if (!empty($this->limitStart)) {
153 1
            $query['sql'] = $this->getDbDriver()->getDbHelper()->limit($query['sql'], $this->limitStart, $this->limitEnd);
154 1
        }
155
156 10
        $result = [];
157 10
        $iterator = $this->getDbDriver()->getIterator($query['sql'], $query['params']);
158
159 10
        foreach ($iterator as $row) {
160 10
            $collection = [];
161 10
            foreach ($mapper as $item) {
162 10
                $instance = $item->getEntity();
163 10
                BinderObject::bindObject($row->toArray(), $instance);
164
165 10
                foreach ((array)$item->getFieldMap() as $property => $fieldName) {
166 3
                    $instance->$property = $row->getField($fieldName);
167 10
                }
168 10
                $collection[] = $instance;
169 10
            }
170 10
            $result[] = count($collection) === 1 ? $collection[0] : $collection;
171 10
        }
172
173 10
        $this->limitStart = $this->limitEnd = $this->top = null;
174
175 10
        return $result;
176
    }
177
178
    /**
179
     * @param mixed $instance
180
     */
181 2
    public function save($instance)
182
    {
183 2
        $array = BinderObject::toArrayFrom($instance, true);
184
185 2
        $query = new Query();
186 2
        $query->table($this->mapper->getTable())
187 2
            ->fields(array_keys($array));
188
189 2
        if (empty($array[$this->mapper->getPrimaryKey()]) || count($this->get($array[$this->mapper->getPrimaryKey()])) === 0)  {
190 1
            $array[$this->mapper->getPrimaryKey()] = $this->insert($query, $array);
191 1
            BinderObject::bindObject($array, $instance);
192 1
        } else {
193 1
            $this->update($query, $array);
194
        }
195
196 2
    }
197
198
    /**
199
     * @param Query $query
200
     * @param array $params
201
     * @return int
202
     * @throws \Exception
203
     */
204 1
    protected function insert(Query $query, array $params)
205
    {
206 1
        $sql = $query->getInsert();
207 1
        $dbFunctions = $this->getDbDriver()->getDbHelper();
208 1
        return $dbFunctions->executeAndGetInsertedId($this->getDbDriver(), $sql, $params);
209
    }
210
211
    /**
212
     * @param Query $query
213
     * @param array $params
214
     * @throws \Exception
215
     */
216 1
    protected function update(Query $query, array $params)
217
    {
218 1
        $params = array_merge($params, ['_id' => $params[$this->mapper->getPrimaryKey()]]);
219 1
        $query->where($this->mapper->getPrimaryKey() . ' = [[_id]] ', ['_id' => $params['_id']]);
220 1
        $update = $query->getUpdate();
221 1
        $sql = $update['sql'];
222
        
223 1
        $this->getDbDriver()->execute($sql, $params);
224 1
    }
225
}
226