Passed
Push — master ( 0c9312...e5eba8 )
by Igor
02:31
created

Bindings   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Test Coverage

Coverage 96.23%

Importance

Changes 0
Metric Value
wmc 22
dl 0
loc 142
ccs 51
cts 53
cp 0.9623
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A escapeString() 0 12 1
A bindParams() 0 5 2
A escapeArray() 0 14 5
A bindParam() 0 7 2
A formatStringParameter() 0 3 1
C process() 0 54 11
1
<?php
2
3
namespace ClickHouseDB\Query\Degeneration;
4
5
use DateTimeInterface;
6
use function array_map;
7
use function implode;
8
use function is_array;
9
use function is_float;
10
use function is_int;
11
use function is_string;
12
use function sprintf;
13
use function str_ireplace;
14
15
class Bindings implements \ClickHouseDB\Query\Degeneration
16
{
17
    /**
18
     * @var array
19
     */
20
    protected $bindings = [];
21
22
    /**
23
     * @param array $bindings
24
     */
25 48
    public function bindParams(array $bindings)
26
    {
27 48
        $this->bindings = [];
28 48
        foreach ($bindings as $column => $value) {
29 18
            $this->bindParam($column, $value);
30
        }
31 48
    }
32
33
    /**
34
     * @param string $column
35
     * @param mixed  $value
36
     */
37 18
    public function bindParam($column, $value)
38
    {
39 18
        if ($value instanceof DateTimeInterface) {
40
            $value = $value->format('Y-m-d H:i:s');
41
        }
42
43 18
        $this->bindings[$column] = $value;
44 18
    }
45
46
    /**
47
     * Escape an string
48
     * Can overwrite use CodeIgniter->escape_str()  https://github.com/bcit-ci/CodeIgniter/blob/develop/system/database/DB_driver.php#L920
49
     *
50
     * @param string $value
51
     * @return string
52
     */
53 13
    private function escapeString($value)
54
    {
55
//        $non_displayables = array(
56
//            '/%0[0-8bcef]/',            // url encoded 00-08, 11, 12, 14, 15
57
//            '/%1[0-9a-f]/',             // url encoded 16-31
58
//            '/[\x00-\x08]/',            // 00-08
59
//            '/\x0b/',                   // 11
60
//            '/\x0c/',                   // 12
61
//            '/[\x0e-\x1f]/'             // 14-31
62
//        );
63
//        foreach ( $non_displayables as $regex ) $data = preg_replace( $regex, '', $data );
64 13
        return addslashes($value);
65
    }
66
67
    /**
68
     * Escape an array
69
     *
70
     * @param array $values
71
     * @return array
72
     */
73 5
    private function escapeArray($values)
74
    {
75 5
        $escapedValues = [];
76 5
        foreach ($values as $value) {
77 5
            if (is_numeric($value)) {
78 4
                $escapedValues[] = $value;
79 2
            } elseif (is_string($value)) {
80 2
                $escapedValues[] = $this->escapeString($value);
81
            } elseif (is_array($value)) {
82 5
                $escapedValues[] = $this->escapeArray($value);
83
            }
84
        }
85
86 5
        return $escapedValues;
87
    }
88
89
    /**
90
     * Compile Bindings
91
     *
92
     * @param string $sql
93
     * @return mixed
94
     */
95 48
    public function process($sql)
96
    {
97
        // Can try use
98
        // CodeIgniter->bind()
99
        // https://github.com/bcit-ci/CodeIgniter/blob/develop/system/database/DB_driver.php#L920
100
101 48
        arsort($this->bindings);
102
103 48
        foreach ($this->bindings as $key => $value) {
104 18
            $valueSet           = null;
105 18
            $formattedParameter = null;
106
107 18
            if ($value === null || $value === false) {
108 1
                $formattedParameter = '';
109
            }
110
111 18
            if (is_array($value)) {
112 5
                $escapedValues = $this->escapeArray($value);
113
114 5
                $escapedValues = array_map(
115 5
                    function ($escapedValue) {
116 5
                        if (is_string($escapedValue)) {
117 4
                            return $this->formatStringParameter($escapedValue);
118
                        }
119
120 2
                        return $escapedValue;
121 5
                    },
122 5
                    $escapedValues
123
                );
124
125 5
                $formattedParameter = implode(',', $escapedValues);
126 5
                $valueSet           = implode(', ', $escapedValues);
127
            }
128
129 18
            if (is_float($value) || is_int($value)) {
130 6
                $formattedParameter = $value;
131 6
                $valueSet           = $value;
132
            }
133
134 18
            if (is_string($value)) {
135 12
                $valueSet           = $value;
136 12
                $formattedParameter = $this->formatStringParameter($this->escapeString($value));
137
            }
138
139 18
            if ($formattedParameter !== null) {
140 18
                $sql = str_ireplace(':' . $key, $formattedParameter, $sql);
141
            }
142
143 18
            if ($valueSet !== null) {
144 18
                $sql = str_ireplace('{' . $key . '}', $valueSet, $sql);
145
            }
146
        }
147
148 48
        return $sql;
149
    }
150
151
    /**
152
     * @return string
153
     */
154 15
    private function formatStringParameter($value)
155
    {
156 15
        return sprintf("'%s'", $value);
157
    }
158
}
159