Completed
Push — master ( c6af74...0c144d )
by Midori
12:18
created

QueryMaker::limit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace midorikocak\querymaker;
6
7
use InvalidArgumentException;
8
9
use function array_keys;
10
use function array_map;
11
use function array_values;
12
use function implode;
13
use function in_array;
14
use function uniqid;
15
16
class QueryMaker implements QueryInterface
17
{
18
    private string $query;
19
    private string $statement;
20 21
    private array $params;
21
    private string $offset;
0 ignored issues
show
introduced by
The private property $offset is not used, and could be removed.
Loading history...
22 21
    private string $limit;
23 21
    private string $orderBy;
24 21
25 21
    private function __construct()
26
    {
27 18
        $this->query     = '';
28
        $this->statement = '';
29 18
        $this->params    = [];
30 18
31 18
        $this->limit   = '';
32 18
        $this->orderBy = '';
33
    }
34
35 3
    public static function select($table, array $columns = ['*']) : QueryInterface
36
    {
37 3
        $instance            = new QueryMaker();
38 3
        $columnsText         = implode(', ', $columns);
39 3
        $instance->statement = 'SELECT ' . $columnsText . ' FROM ' . $table;
40 3
        $instance->query     = 'SELECT ' . $columnsText . ' FROM ' . $table;
41
        return $instance;
42
    }
43 15
44
    public static function update($table, array $values) : QueryInterface
45 15
    {
46 15
        $instance            = new QueryMaker();
47
        $instance->statement = 'UPDATE ' . $table . ' SET ';
48
        $instance->query     = 'UPDATE ' . $table . ' SET ';
49 15
        $instance->prepareParams($values, ', ');
50
        return $instance;
51
    }
52 15
53 15
    public static function insert($table, array $values) : QueryInterface
54 15
    {
55 15
        $fields      = implode(', ', array_keys($values));
56
        $params      = implode(', ', array_map(fn($key) => ':' . $key, array_keys($values)));
57
        $queryValues = implode(', ', array_map(fn($value) => "'$value'", array_values($values)));
58 6
59
        $instance            = new QueryMaker();
60 6
        $instance->statement = "INSERT INTO $table ($fields) VALUES ($params)";
61 6
        $instance->query     = "INSERT INTO $table ($fields) VALUES ($queryValues)";
62 6
        $instance->params    = $values;
63 6
64
        return $instance;
65
    }
66 6
67
    public static function delete($table) : QueryInterface
68 6
    {
69 6
        $instance            = new QueryMaker();
70 6
        $instance->statement = 'DELETE FROM ' . $table;
71 6
        $instance->query     = 'DELETE FROM ' . $table;
72
        return $instance;
73
    }
74
75
    public function where($key, $value, string $operator = '=') : QueryInterface
76
    {
77
        $this->checkOperator($operator);
78
79
        $this->statement   .= ' WHERE ' . $key . $operator . ':' . $key;
80
        $this->query       .= ' WHERE ' . $key . $operator . '\'' . $value . '\'';
81
        $this->params[$key] = $value;
82
        return $this;
83
    }
84 21
85
    public function and($key, $value, string $operator = '=') : QueryInterface
86 21
    {
87
        $this->checkOperator($operator);
88
89 21
        $this->query     .= ' AND ';
90
        $this->statement .= ' AND ';
91 21
        $this->prepareParam($key, $value, 'AND', $operator);
92
        return $this;
93
    }
94
95
    public function orderBy($key, string $order = 'ASC') : QueryInterface
96
    {
97
        $this->orderBy .= ' ORDER BY ' . $key . ' ' . $order;
98
        return $this;
99 12
    }
100
101 12
    public function limit(int $limit) : QueryInterface
102 12
    {
103
        $this->limit .= ' LIMIT ' . $limit;
104 12
        return $this;
105 12
    }
106 12
107
    public function offset(int $offset) : QueryInterface
108
    {
109
        $this->limit .= ' OFFSET ' . $offset;
110 12
        return $this;
111
    }
112
113 12
    public function or($key, $value, $operator = '=') : QueryInterface
114 12
    {
115 12
        $this->checkOperator($operator);
116
117 12
        $this->query     .= " OR ";
118
        $this->statement .= " OR ";
119
        $this->prepareParam($key, $value, 'OR');
120
        return $this;
121
    }
122
123
    public function between($key, $before, $after) : QueryInterface
124
    {
125
        $this->query     .= $key . " BETWEEN $before AND $after";
126
        $this->statement .= $key . ' BETWEEN :before AND :after';
127 12
128 12
        $this->params['before'] = $before;
129 12
        $this->params['after']  = $after;
130
        return $this;
131 9
    }
132
133 9
    public function getQuery() : string
134 9
    {
135
        return $this->query . $this->orderBy . $this->limit;
136
    }
137
138
    public function getStatement() : string
139
    {
140
        return $this->statement . $this->orderBy . $this->limit;
141
    }
142
143
    public function getParams() : array
144
    {
145
        return $this->params;
146
    }
147
148
    private function prepareParams(array $values, string $glue, string $operator = '=')
149
    {
150
        $this->checkOperator($operator);
151
        $params      = [];
152
        $queryValues = [];
153
154
        foreach ($values as $key => $value) {
155
            if (!isset($this->params[$key])) {
156
                $queryValues[] = $key . $operator . '\'' . $value . '\'';
157
                $params []     = $key . $operator . ':' . $key;
158
159
                $this->params[$key] = $value;
160
            } else {
161
                $uniqid        = uniqid('', true);
162
                $queryValues[] = $key . $operator . '\'' . $value . '\'';
163
                $params []     = $key . $operator . ':' . $key . $uniqid;
164
165
                $this->params[$key . $uniqid] = $value;
166
            }
167
        }
168
169
        $this->query     .= implode($glue, $queryValues);
170
        $this->statement .= implode($glue, $params);
171
    }
172
173
    private function prepareParam(string $key, $value, string $glue, $operator = '=') : void
174
    {
175
        $this->prepareParams([$key => $value], $glue, $operator);
176
    }
177
178
    private function checkOperator(string $operator) : void
179
    {
180
        $operators = ['=', '>', '>=', '<', '<=', 'LIKE'];
181
        if (!in_array($operator, $operators, true)) {
182
            throw new InvalidArgumentException('Invalid Operator');
183
        }
184
    }
185
}
186