Passed
Push — master ( 7edc3c...559664 )
by Midori
01:49
created

QueryMaker::insert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 7
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 11
ccs 6
cts 6
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace midorikocak\querymaker;
6
7
use function array_keys;
8
use function array_map;
9
use function array_values;
10
use function implode;
11
use function preg_match;
12
use function reset;
13
use function strlen;
14
use function substr;
15
use function uniqid;
16
17
class QueryMaker implements QueryInterface
18
{
19
    private string $query;
20 21
    private string $statement;
21
    private array $params;
22 21
23 21
    private function __construct()
24 21
    {
25 21
        $this->query     = '';
26
        $this->statement = '';
27 18
        $this->params    = [];
28
    }
29 18
30 18
    public static function select($table, array $columns = ['*']) : QueryInterface
31 18
    {
32 18
        $instance            = new QueryMaker();
33
        $columnsText         = implode(', ', $columns);
34
        $instance->statement = 'SELECT ' . $columnsText . ' FROM ' . $table;
35 3
        $instance->query     = 'SELECT ' . $columnsText . ' FROM ' . $table;
36
        return $instance;
37 3
    }
38 3
39 3
    public static function update($table, array $values) : QueryInterface
40 3
    {
41
        $instance            = new QueryMaker();
42
        $instance->statement = 'UPDATE ' . $table . ' SET ';
43 15
        $instance->query     = 'UPDATE ' . $table . ' SET ';
44
        $instance->prepareParams($values, ', ');
45 15
        return $instance;
46 15
    }
47
48
    public static function insert($table, array $values) : QueryInterface
49 15
    {
50
        $fields      = implode(', ', array_keys($values));
51
        $params      = implode(', ', array_map(fn($key)=>':' . $key, array_keys($values)));
52 15
        $queryValues = implode(', ', array_map(fn($value)=> "'$value'", array_values($values)));
53 15
54 15
        $instance            = new QueryMaker();
55 15
        $instance->statement = "INSERT INTO $table ($fields) VALUES ($params)";
56
        $instance->query     = "INSERT INTO $table ($fields) VALUES ($queryValues)";
57
58 6
        return $instance;
59
    }
60 6
61 6
    public static function delete($table) : QueryInterface
62 6
    {
63 6
        $instance            = new QueryMaker();
64
        $instance->statement = 'DELETE FROM ' . $table;
65
        $instance->query     = 'DELETE FROM ' . $table;
66 6
        return $instance;
67
    }
68 6
69 6
    public function where($key, $value) : QueryInterface
70 6
    {
71 6
        $operator           = $this->getOperator($value);
72
        $this->statement   .= ' WHERE ' . $key . $operator . ':' . $key;
73
        $this->query       .= ' WHERE ' . $key . $operator . '\'' . $value . '\'';
74
        $this->params[$key] = $value;
75
        return $this;
76
    }
77
78
    public function and($key, $value) : QueryInterface
79
    {
80
        $this->query     .= " AND ";
81
        $this->statement .= " AND ";
82
        $this->prepareParam($key, $value, 'AND');
83
        return $this;
84 21
    }
85
86 21
    public function or($key, $value) : QueryInterface
87
    {
88
        $this->query     .= " OR ";
89 21
        $this->statement .= " OR ";
90
        $this->prepareParam($key, $value, 'OR');
91 21
        return $this;
92
    }
93
94
    public function between($key, $before, $after) : QueryInterface
95
    {
96
        $this->query     .= $key . " BETWEEN $before AND $after";
97
        $this->statement .= $key . ' BETWEEN :before AND :after';
98
99 12
        $this->params['before'] = $before;
100
        $this->params['after']  = $after;
101 12
        return $this;
102 12
    }
103
104 12
    public function getQuery() : string
105 12
    {
106 12
        return $this->query;
107
    }
108
109
    public function getStatement() : string
110 12
    {
111
        return $this->statement;
112
    }
113 12
114 12
    public function getParams() : array
115 12
    {
116
        return $this->params;
117 12
    }
118
119
    private function prepareParams(array $values, string $glue)
120
    {
121
        $params      = [];
122
        $queryValues = [];
123
124
        foreach ($values as $key => $value) {
125
            $operator = $this->getOperator($value);
126
            if (! isset($this->params[$key])) {
127 12
                $queryValues[] = $key . $operator . '\'' . $value . '\'';
128 12
                $params []     = $key . $operator . ':' . $key;
129 12
130
                $this->params[$key] = $value;
131 9
            } else {
132
                $uniqid        = uniqid('', true);
133 9
                $queryValues[] = $key . $operator . '\'' . $value . '\'';
134 9
                $params []     = $key . $operator . ':' . $key . $uniqid;
135
136
                $this->params[$key . $uniqid] = $value;
137
            }
138
        }
139
140
        $this->query     .= implode($glue, $queryValues);
141
        $this->statement .= implode($glue, $params);
142
    }
143
144
    private function getOperator(&$value)
145
    {
146
        $hasOperator = preg_match('~^(([<>=])+(=)*)~', (string) $value, $matches);
147
        if (! empty($hasOperator)) {
148
            $operator = reset($matches);
149
            $value    = substr($value, strlen($operator));
150
        } else {
151
            $operator = '=';
152
        }
153
154
        return $operator;
155
    }
156
157
    private function prepareParam(string $key, $value, string $glue)
158
    {
159
        $this->prepareParams([$key => $value], $glue);
160
    }
161
}
162