Completed
Pull Request — master (#67)
by Šimon
09:32
created

Bindings::formatStringParameter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
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 41
{
17
    /**
18 41
     * @var array
19 41
     */
20 12
    protected $bindings = [];
21
22 41
    /**
23
     * @param array $bindings
24
     */
25
    public function bindParams(array $bindings)
26
    {
27
        $this->bindings = [];
28 12
        foreach ($bindings as $column => $value) {
29
            $this->bindParam($column, $value);
30 12
        }
31
    }
32
33
    /**
34 12
     * @param string $column
35 12
     * @param mixed  $value
36
     */
37
    public function bindParam($column, $value)
38
    {
39
        if ($value instanceof DateTimeInterface) {
40
            $value = $value->format('Y-m-d H:i:s');
41
        }
42
43
        $this->bindings[$column] = $value;
44 9
    }
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
    private function escapeString($value)
54
    {
55 9
//        $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 3
        return addslashes($value);
65
    }
66 3
67 3
    /**
68 3
     * Escape an array
69 2
     *
70 2
     * @param array $values
71 2
     * @return array
72
     */
73 3
    private function escapeArray($values)
74
    {
75
        $escapedValues = [];
76
        foreach ($values as $value) {
77 3
            if (is_numeric($value)) {
78
                $escapedValues[] = $value;
79
            } elseif (is_string($value)) {
80
                $escapedValues[] = $this->escapeString($value);
81
            } elseif (is_array($value)) {
82
                $escapedValues[] = $this->escapeArray($value);
83
            }
84
        }
85
86
        return $escapedValues;
87 41
    }
88
89
    /**
90
     * Compile Bindings
91
     *
92
     * @param string $sql
93 41
     * @return mixed
94
     */
95
    public function process($sql)
96 41
    {
97
        // Can try use
98
        // CodeIgniter->bind()
99 12
        // https://github.com/bcit-ci/CodeIgniter/blob/develop/system/database/DB_driver.php#L920
100 12
101
        arsort($this->bindings);
102 12
103 1
        foreach ($this->bindings as $key => $value) {
104
            $valueSet           = null;
105
            $formattedParameter = null;
106 12
107 3
            if ($value === null || $value === false) {
108 3
                $formattedParameter = '';
109 3
            }
110
111
            if (is_array($value)) {
112 12
                $escapedValues = $this->escapeArray($value);
113 8
114 8
                $escapedValues = array_map(
115
                    function ($escapedValue) {
116
                        if (is_string($escapedValue)) {
117 12
                            return $this->formatStringParameter($escapedValue);
118 8
                        }
119 8
120
                        return $escapedValue;
121
                    },
122 12
                    $escapedValues
123 12
                );
124
125
                $formattedParameter = implode(',', $escapedValues);
126 12
                $valueSet           = implode(', ', $escapedValues);
127 12
            }
128
129
            if (is_float($value) || is_int($value)) {
130
                $formattedParameter = $value;
131 41
                $valueSet           = $value;
132
            }
133
134
            if (is_string($value)) {
135
                $valueSet           = $value;
136
                $formattedParameter = $this->formatStringParameter($this->escapeString($value));
137
            }
138
139
            if ($formattedParameter !== null) {
140
                $sql = str_ireplace(':' . $key, $formattedParameter, $sql);
141
            }
142
143
            if ($valueSet !== null) {
144
                $sql = str_ireplace('{' . $key . '}', $valueSet, $sql);
145
            }
146
        }
147
148
        return $sql;
149
    }
150
151
    /**
152
     * @return string
153
     */
154
    private function formatStringParameter(string $value)
155
    {
156
        return sprintf("'%s'", $value);
157
    }
158
}
159