Completed
Push — master ( f5981b...225f0a )
by Pierre
03:30
created

Orm   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 299
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 104
dl 0
loc 299
ccs 99
cts 99
cp 1
rs 9.6
c 1
b 0
f 0
wmc 35

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A find() 0 8 1
A setColumns() 0 4 1
A getSql() 0 3 1
A getQuery() 0 3 1
A buildWhere() 0 9 3
B build() 0 47 11
A update() 0 6 1
A count() 0 13 2
A getQueryBuilder() 0 3 1
B getWhereOperator() 0 19 9
A insert() 0 6 1
A setQuery() 0 4 1
A delete() 0 6 1
1
<?php
2
3
namespace App\Component\Model\Orm;
4
5
use App\Config;
6
use App\Container;
7
use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
8
use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
9
use NilPortugues\Sql\QueryBuilder\Manipulation\Update;
10
use NilPortugues\Sql\QueryBuilder\Manipulation\Insert;
11
use NilPortugues\Sql\QueryBuilder\Manipulation\Delete;
12
13
/**
14
 * Poor man orm
15
 */
16
class Orm implements IOrm
17
{
18
19
    /**
20
     * config
21
     *
22
     * @var Config
23
     */
24
    protected $config;
25
26
    /**
27
     * columns fields
28
     * @var array
29
     */
30
    protected $columns;
31
32
    /**
33
     * where criterias
34
     * @var array
35
     */
36
    protected $where;
37
38
    /**
39
     * table name
40
     * @var string
41
     */
42
    protected $tablename;
43
44
    /**
45
     * table primary key
46
     * @var string
47
     */
48
    protected $primary;
49
50
    /**
51
     * database name
52
     * @var string
53
     */
54
    protected $dbname;
55
56
    /**
57
     * pool name
58
     * @var string
59
     */
60
    protected $poolname;
61
62
    /**
63
     * query builder instance
64
     * @var GenericBuilder
65
     * @see https://github.com/nilportugues/php-sql-query-builder
66
     */
67
    protected $queryBuilder;
68
69
    /**
70
     * query from builder
71
     * @var object
72
     */
73
    protected $query;
74
75
    /**
76
     * instanciate
77
     * @param Container $container
78
     */
79 22
    public function __construct(Container $container)
80
    {
81 22
        $this->config = $container->getService(Config::class);
82 22
        $this->queryBuilder = new GenericBuilder();
83 22
        $this->query = null;
84 22
        $this->columns = [];
85 22
        $this->where = [];
86 22
        return $this;
87
    }
88
89
    /**
90
     * set required columns
91
     *
92
     * @param array $columns
93
     * @return Orm
94
     */
95 6
    public function setColumns(array $columns): Orm
96
    {
97 6
        $this->columns = $columns;
98 6
        return $this;
99
    }
100
101
    /**
102
     * find a record with columns field matching where criterias
103
     * @param array $columns
104
     * @param array $where
105
     */
106 4
    public function find(array $columns = [], array $where = []): Orm
107
    {
108 4
        $this->where = $where;
109
        $this
110 4
            ->setColumns($columns)
111 4
            ->setQuery(new Select())
112 4
            ->build($this->tablename, $this->columns, $this->where);
113 4
        return $this;
114
    }
115
116
    /**
117
     * count records matching where criterias.
118
     * aliases is formely [columnn => column_alias]
119
     *
120
     * @param array $where
121
     * @param array $aliases
122
     * @return Orm
123
     */
124 2
    public function count(array $where = [], array $aliases = []): Orm
125
    {
126 2
        $this->where = $where;
127 2
        $this->setQuery(new Select());
128 2
        if (empty($aliases)) {
129 1
            $this->query->count();
130
        } else {
131 1
            reset($aliases);
132 1
            $fistKey = key($aliases);
133 1
            $aliasValue = $aliases[$fistKey];
134 1
            $this->query->count($fistKey, $aliasValue);
135
        }
136 2
        return $this->buildWhere($this->where);
137
    }
138
139
    /**
140
     * update a record with columns fields matching where criterias
141
     * @param array $columns
142
     * @param array $where
143
     */
144 1
    public function update(array $columns = [], array $where = []): Orm
145
    {
146 1
        $this->where = $where;
147 1
        return $this->setColumns($columns)
148 1
            ->setQuery(new Update())
149 1
            ->build($this->tablename, $this->columns, $this->where);
150
    }
151
152
    /**
153
     * insert record with columns fields
154
     * @param array $columns
155
     */
156 1
    public function insert(array $columns = []): Orm
157
    {
158
        return $this
159 1
            ->setColumns($columns)
160 1
            ->setQuery(new Insert())
161 1
            ->build($this->tablename, $this->columns, []);
162
    }
163
164
    /**
165
     * delete matching where criterias
166
     * @param array $where
167
     */
168 1
    public function delete(array $where = []): Orm
169
    {
170 1
        $this->where = $where;
171
        return $this
172 1
            ->setQuery(new Delete())
173 1
            ->build($this->tablename, [], $this->where);
174
    }
175
176
    /**
177
     * builder instance
178
     * @return GenericBuilder
179
     */
180 1
    public function getQueryBuilder(): GenericBuilder
181
    {
182 1
        return $this->queryBuilder;
183
    }
184
185
    /**
186
     * query instance
187
     * @return object
188
     */
189 16
    public function getQuery()
190
    {
191 16
        return $this->query;
192
    }
193
194
    /**
195
     * set query instance
196
     *
197
     * @param Select|Update|Insert|Delete $query
198
     * @return Orm
199
     */
200 17
    public function setQuery($query): Orm
201
    {
202 17
        $this->query = $query;
203 17
        return $this;
204
    }
205
206
    /**
207
     * query sql string
208
     * @return string
209
     */
210 1
    public function getSql()
211
    {
212 1
        return $this->queryBuilder->write($this->query);
213
    }
214
215
    /**
216
     * build query
217
     *
218
     * @param string $tablename
219
     * @param array $columns
220
     * @param array $where
221
     * @return Orm
222
     */
223 10
    protected function build(string $tablename, array $columns, array $where): Orm
224
    {
225 10
        if (false === is_object($this->getQuery())) {
226 1
            throw new \Exception('Build : Invalid query instance');
227
        }
228 9
        $queryClassname = get_class($this->getQuery());
229
        $allowedClasses = [
230 9
            Update::class, Select::class, Delete::class, Insert::class
231
        ];
232 9
        if (false === in_array($queryClassname, $allowedClasses)) {
233 1
            throw new \Exception('Build : Invalid query type');
234
        }
235 8
        $this->query->setTable($tablename);
236 8
        switch ($queryClassname) {
237
            case Select::class:
238 1
                $this->query->setColumns($columns);
239 1
                break;
240
            case Update::class:
241 3
                if (empty($columns)) {
242 1
                    throw new \Exception(
243 1
                        'Build : Update requires not empty payload'
244
                    );
245
                }
246 2
                if (empty($where)) {
247 1
                    throw new \Exception(
248 1
                        'Build : Update requires at least one condition'
249
                    );
250
                }
251 1
                $this->query->setValues($columns);
252 1
                break;
253
            case Insert::class:
254 2
                if (empty($columns)) {
255 1
                    throw new \Exception(
256 1
                        'Build : Insert requires not empty payload'
257
                    );
258
                }
259 1
                $this->query->setValues($columns);
260 1
                break;
261
            case Delete::class:
262 2
                if (empty($where)) {
263 1
                    throw new \Exception(
264 1
                        'Build : Delete requires at least one condition'
265
                    );
266
                }
267 1
                break;
268
        }
269 4
        return $this->buildWhere($where);
270
        ;
271
    }
272
273
    /**
274
     * build where condition on query
275
     *
276
     * @param array $where
277
     * @return Orm
278
     */
279 1
    protected function buildWhere(array $where): Orm
280
    {
281 1
        if (false === empty($where)) {
282 1
            foreach ($where as $k => $v) {
283 1
                $whereOperator = $this->getWhereOperator($k, $v);
284 1
                $this->query->where()->{$whereOperator}($k, $v);
285
            }
286
        }
287 1
        return $this;
288
    }
289
290
    /**
291
     * check where condition ket values to find operators
292
     *
293
     * @param string $whereColumn
294
     * @return string
295
     */
296 1
    protected function getWhereOperator(string &$whereColumn, $value): string
297
    {
298 1
        $hasArray = is_array($value);
299 1
        $operator = $whereColumn[strlen($whereColumn) - 1];
300 1
        $hasOperator = in_array($operator, self::OPERATORS);
301 1
        if (false === $hasOperator) {
302 1
            return ($hasArray) ? 'in' : 'equals';
303
        }
304 1
        foreach (self::OPERATORS as $op) {
305 1
            $whereColumn = str_replace($op, '', $whereColumn);
306
        }
307 1
        if ($operator == '!') {
308 1
            return ($hasArray) ? 'notIn' : 'notEquals';
309 1
        } elseif ($operator == '<') {
310 1
            return 'lessThan';
311 1
        } elseif ($operator == '>') {
312 1
            return 'greaterThan';
313 1
        } elseif ($operator == '#') {
314 1
            return 'like';
315
        }
316
    }
317
}
318