Completed
Push — master ( d90c8e...3aab8e )
by Pierre
32:39
created

Orm::build()   B

Complexity

Conditions 11
Paths 11

Size

Total Lines 47
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
cc 11
eloc 34
nc 11
nop 0
dl 0
loc 47
ccs 0
cts 0
cp 0
crap 132
rs 7.3166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Component\Model\Orm;
4
5
use App\Config;
6
use App\Container;
7
use Exception;
8
use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
9
use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
10
use NilPortugues\Sql\QueryBuilder\Manipulation\Update;
11
use NilPortugues\Sql\QueryBuilder\Manipulation\Insert;
12
use NilPortugues\Sql\QueryBuilder\Manipulation\Delete;
13
14
/**
15
 * Poor man orm
16
 */
17
class Orm implements IOrm
18
{
19
20
    /**
21
     * config
22
     *
23
     * @var Config
24
     */
25
    protected $config;
26
27
    /**
28
     * what fields
29
     * @var array
30
     */
31
    protected $what;
32
33
    /**
34
     * where criterias
35
     * @var array
36
     */
37
    protected $where;
38
39
    /**
40
     * table name
41
     * @var string
42
     */
43
    protected $tablename;
44
45
    /**
46
     * table primary key
47
     * @var string
48
     */
49
    protected $primary;
50
51
    /**
52
     * table name
53
     * @var string
54
     */
55
    protected $dbname;
56
57
    /**
58
     * pool name
59
     * @var string
60
     */
61
    protected $poolname;
62
63
    /**
64
     * query builder instance
65
     * @var GenericBuilder
66
     * @see https://github.com/nilportugues/php-sql-query-builder
67
     */
68
    protected $queryBuilder;
69
70
    /**
71
     * query from builder
72
     * @var object
73
     */
74
    protected $query;
75
76
    /**
77
     * instanciate
78
     * @param Container $container
79
     */
80
    public function __construct(Container $container)
81
    {
82
        $this->config = $container->getService(Config::class);
83
        $this->queryBuilder = new GenericBuilder();
84
        $this->query = null;
85
        return $this;
86
    }
87
88
    /**
89
     * find a record with what field matching where criterias
90
     * @param array $what
91
     * @param array $where
92
     */
93
    public function find(array $what = [], array $where = []): Orm
94
    {
95
        $this->what = $what;
96
        $this->where = $where;
97
        $this->query = new Select();
98
        $this->build();
99
        return $this;
100
    }
101
102
    /**
103
     * count records matching where criterias.
104
     * alias is [columnn => column_alias]
105
     *
106
     * @param array $where
107
     * @param array $alias
108
     * @return Orm
109
     */
110
    public function count(array $where = [], array $alias = []): Orm
111
    {
112
        $this->where = $where;
113
        $this->query = new Select();
114
        $this->query->count($alias);
0 ignored issues
show
Bug introduced by
$alias of type array is incompatible with the type string expected by parameter $columnName of NilPortugues\Sql\QueryBu...ulation\Select::count(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

114
        $this->query->count(/** @scrutinizer ignore-type */ $alias);
Loading history...
115
        $this->buildWhere();
116
        return $this;
117
    }
118
119
    /**
120
     * update a record with what fields matching where criterias
121
     * @param array $what
122
     * @param array $where
123
     */
124
    public function update(array $what = [], array $where = []): Orm
125
    {
126
        $this->what = $what;
127
        $this->where = $where;
128
        $this->query = new Update();
129
        $this->build();
130
        return $this;
131
    }
132
133
    /**
134
     * insert record with what fields
135
     * @param array $what
136
     */
137
    public function insert(array $what = []): Orm
138
    {
139
        $this->what = $what;
140
        $this->query = new Insert();
141
        $this->build();
142
        return $this;
143
    }
144
145
    /**
146
     * delete matching where criterias
147
     * @param array $where
148
     */
149
    public function delete(array $where = []): Orm
150
    {
151
        $this->where = $where;
152
        $this->query = new Delete();
153
        $this->build();
154
        return $this;
155
    }
156
157
    /**
158
     * builder instance
159
     * @return GenericBuilder
160
     */
161
    public function getQueryBuilder(): GenericBuilder
162
    {
163
        return $this->queryBuilder;
164
    }
165
166
    /**
167
     * query instance
168
     * @return object
169
     */
170
    public function getQuery()
171
    {
172
        return $this->query;
173
    }
174
175
    /**
176
     * query sql string
177
     * @return string
178
     */
179
    public function getSql()
180
    {
181
        return $this->queryBuilder->write($this->query);
182
    }
183
184
    /**
185
     * build sql query
186
     *
187
     * @return Orm
188
     */
189
    protected function build(): Orm
190
    {
191
        if (false === is_object($this->query)) {
192
            throw new Exception('Build : Invalid query instance');
193
        }
194
        $queryClassname = get_class($this->query);
195
        if (false === class_exists($queryClassname)) {
196
            throw new Exception('Build : Invalid query type');
197
        }
198
        $this->query->setTable($this->tablename);
199
        switch ($queryClassname) {
200
            case Select::class:
201
                $this->query->setColumns($this->what);
202
                break;
203
            case Update::class:
204
                if (empty($this->what)) {
205
                    throw new Exception(
206
                        'Build : Update requires not empty payload'
207
                    );
208
                }
209
                if (empty($this->where)) {
210
                    throw new Exception(
211
                        'Build : Update requires at least one condition'
212
                    );
213
                }
214
                $this->query->setValues($this->what);
215
                break;
216
            case Insert::class:
217
                if (empty($this->what)) {
218
                    throw new Exception(
219
                        'Build : Insert requires not empty payload'
220
                    );
221
                }
222
                $this->query->setValues($this->what);
223
                break;
224
            case Delete::class:
225
                if (empty($this->where)) {
226
                    throw new Exception(
227
                        'Build : Delete requires at least one condition'
228
                    );
229
                }
230
                break;
231
            default:
232
                break;
233
        }
234
        $this->buildWhere();
235
        return $this;
236
    }
237
238
    /**
239
     * build where condition on query
240
     *
241
     * @return Orm
242
     */
243
    protected function buildWhere(): Orm
244
    {
245
        foreach ($this->where as $k => $v) {
246
            $whereOperator = $this->getWhereOperator($k, $v);
247
            $this->query->where()->{$whereOperator}($k, $v);
248
        }
249
        return $this;
250
    }
251
252
    /**
253
     * check where condition ket values to find operators
254
     *
255
     * @param string $whereColumn
256
     * @return string
257
     */
258
    protected function getWhereOperator(string &$whereColumn, $value): string
259
    {
260
        $hasArray = is_array($value);
261
        $operator = $whereColumn[strlen($whereColumn) - 1];
262
        $hasOperator = in_array($operator, self::OPERATORS);
263
        if (false === $hasOperator) {
264
            return ($hasArray) ? 'in' : 'equals';
265
        }
266
        foreach (self::OPERATORS as $op) {
267
            $whereColumn = str_replace($op, '', $whereColumn);
268
        }
269
        switch ($operator) {
270
            case '!':
271
                return ($hasArray) ? 'notIn' : 'notEquals';
272
                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...
273
            case '<':
274
                return 'lessThan';
275
                break;
276
            case '>':
277
                return 'greaterThan';
278
                break;
279
            case '#':
280
                return 'like';
281
                break;
282
        }
283
    }
284
}
285