Completed
Push — master ( 487dd2...a94887 )
by Pierre
03:06
created

Orm::find()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 7
ccs 6
cts 6
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
     * what fields
28
     * @var array
29
     */
30
    protected $what;
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
     * table 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 6
    public function __construct(Container $container)
80
    {
81 6
        $this->config = $container->getService(Config::class);
82 6
        $this->queryBuilder = new GenericBuilder();
83 6
        $this->query = null;
84 6
        return $this;
85
    }
86
87
    /**
88
     * find a record with what field matching where criterias
89
     * @param array $what
90
     * @param array $where
91
     */
92 1
    public function find(array $what = [], array $where = []): Orm
93
    {
94 1
        $this->what = $what;
95 1
        $this->where = $where;
96 1
        $this->query = new Select();
97 1
        $this->build();
98 1
        return $this;
99
    }
100
101
    /**
102
     * count records matching where criterias.
103
     * aliases is formely [columnn => column_alias]
104
     *
105
     * @param array $where
106
     * @param array $aliases
107
     * @return Orm
108
     */
109 1
    public function count(array $where = [], array $aliases = []): Orm
110
    {
111 1
        $this->where = $where;
112 1
        $this->query = new Select();
113 1
        if (empty($aliases)) {
114 1
            $this->query->count();
115
        } else {
116
            $alias = $aliases[0];
117
            $this->query->count(
118
                array_keys($alias)[0],
119
                array_values($alias)[0]
120
            );
121
        }
122 1
        $this->buildWhere();
123 1
        return $this;
124
    }
125
126
    /**
127
     * update a record with what fields matching where criterias
128
     * @param array $what
129
     * @param array $where
130
     */
131
    public function update(array $what = [], array $where = []): Orm
132
    {
133
        $this->what = $what;
134
        $this->where = $where;
135
        $this->query = new Update();
136
        $this->build();
137
        return $this;
138
    }
139
140
    /**
141
     * insert record with what fields
142
     * @param array $what
143
     */
144 3
    public function insert(array $what = []): Orm
145
    {
146 3
        $this->what = $what;
147 3
        $this->query = new Insert();
148 3
        $this->build();
149 3
        return $this;
150
    }
151
152
    /**
153
     * delete matching where criterias
154
     * @param array $where
155
     */
156
    public function delete(array $where = []): Orm
157
    {
158
        $this->where = $where;
159
        $this->query = new Delete();
160
        $this->build();
161
        return $this;
162
    }
163
164
    /**
165
     * builder instance
166
     * @return GenericBuilder
167
     */
168
    public function getQueryBuilder(): GenericBuilder
169
    {
170
        return $this->queryBuilder;
171
    }
172
173
    /**
174
     * query instance
175
     * @return object
176
     */
177
    public function getQuery()
178
    {
179
        return $this->query;
180
    }
181
182
    /**
183
     * query sql string
184
     * @return string
185
     */
186
    public function getSql()
187
    {
188
        return $this->queryBuilder->write($this->query);
189
    }
190
191
    /**
192
     * build sql query
193
     *
194
     * @return Orm
195
     */
196
    protected function build(): Orm
197
    {
198
        if (false === is_object($this->query)) {
199
            throw new \Exception('Build : Invalid query instance');
200
        }
201
        $queryClassname = get_class($this->query);
202
        if (false === class_exists($queryClassname)) {
203
            throw new \Exception('Build : Invalid query type');
204
        }
205
        $this->query->setTable($this->tablename);
206
        switch ($queryClassname) {
207
            case Select::class:
208
                $this->query->setColumns($this->what);
209
                break;
210
            case Update::class:
211
                if (empty($this->what)) {
212
                    throw new \Exception(
213
                        'Build : Update requires not empty payload'
214
                    );
215
                }
216
                if (empty($this->where)) {
217
                    throw new \Exception(
218
                        'Build : Update requires at least one condition'
219
                    );
220
                }
221
                $this->query->setValues($this->what);
222
                break;
223
            case Insert::class:
224
                if (empty($this->what)) {
225
                    throw new \Exception(
226
                        'Build : Insert requires not empty payload'
227
                    );
228
                }
229
                $this->query->setValues($this->what);
230
                break;
231
            case Delete::class:
232
                if (empty($this->where)) {
233
                    throw new \Exception(
234
                        'Build : Delete requires at least one condition'
235
                    );
236
                }
237
                break;
238
            default:
239
                break;
240
        }
241
        $this->buildWhere();
242
        return $this;
243
    }
244
245
    /**
246
     * build where condition on query
247
     *
248
     * @return Orm
249
     */
250
    protected function buildWhere(): Orm
251
    {
252
        if (false === empty($this->where)) {
253
            foreach ($this->where as $k => $v) {
254
                $whereOperator = $this->getWhereOperator($k, $v);
255
                $this->query->where()->{$whereOperator}($k, $v);
256
            }
257
        }
258
        return $this;
259
    }
260
261
    /**
262
     * check where condition ket values to find operators
263
     *
264
     * @param string $whereColumn
265
     * @return string
266
     */
267
    protected function getWhereOperator(string &$whereColumn, $value): string
268
    {
269
        $hasArray = is_array($value);
270
        $operator = $whereColumn[strlen($whereColumn) - 1];
271
        $hasOperator = in_array($operator, self::OPERATORS);
272
        if (false === $hasOperator) {
273
            return ($hasArray) ? 'in' : 'equals';
274
        }
275
        foreach (self::OPERATORS as $op) {
276
            $whereColumn = str_replace($op, '', $whereColumn);
277
        }
278
        switch ($operator) {
279
            case '!':
280
                return ($hasArray) ? 'notIn' : 'notEquals';
281
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
282
            case '<':
283
                return 'lessThan';
284
                break;
285
            case '>':
286
                return 'greaterThan';
287
                break;
288
            case '#':
289
                return 'like';
290
                break;
291
        }
292
    }
293
}
294