Passed
Pull Request — master (#67)
by Šimon
02:34
created

Bindings::escapeString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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