Passed
Push — master ( 566a3a...fbef46 )
by 世昌
02:19
created

PrepareTrait::prepareWhereString()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 4
nop 2
dl 0
loc 17
rs 9.5555
c 0
b 0
f 0
1
<?php
2
namespace suda\database\statement;
3
4
use ArrayObject;
5
use suda\database\Binder;
6
use suda\database\exception\SQLException;
7
8
/**
9
 * Trait PrepareTrait
10
 * @package suda\orm\statement
11
 */
12
trait PrepareTrait
13
{
14
15
    /**
16
     * 准备选择列
17
     *
18
     * @param string|array $reads
19
     * @param string $table
20
     * @return string
21
     */
22
    protected function prepareReadFields($reads, string $table = ''):string
23
    {
24
        if (is_string($reads)) {
25
            $fields = $reads;
26
        } else {
27
            $field = [];
28
            $prefix = strlen($table) ?"`{$table}`." :'';
29
            foreach ($reads as $want) {
30
                $field[] = $prefix."`$want`";
31
            }
32
            $fields = implode(',', $field);
33
        }
34
        return $fields;
35
    }
36
37
    /**
38
     * 准备条件列
39
     *
40
     * @param array $where
41
     * @return array
42
     * @throws SQLException
43
     */
44
    protected function parepareWhere(array $where)
45
    {
46
        $and = [];
47
        $binders = [];
48
        foreach ($where as $name => $value) {
49
            $_name = Binder::index($name);
50
            // in cause
51
            if ($value instanceof ArrayObject) {
52
                list($sql, $in_binder) = $this->prepareIn($name, $value);
53
                $and[] = $sql;
54
                $binders = array_merge($binders, $in_binder);
55
            } elseif (is_array($value)) {
56
                list($op, $val) = $value;
57
                $op = trim($op);
58
                $and[] = "`{$name}` {$op} :{$_name}";
59
                $binders[] = new Binder($_name, $val);
60
            } else {
61
                $and[] = "`{$name}`=:{$_name}";
62
                $binders[] = new Binder($_name, $value);
63
            }
64
        }
65
        return [implode(' AND ', $and), $binders];
66
    }
67
68
    /**
69
     * @param string $where
70
     * @param array $whereBinder
71
     * @return array
72
     * @throws SQLException
73
     */
74
    protected function prepareWhereString(string $where, array $whereBinder)
75
    {
76
77
        $newWhereBinder = [];
78
        foreach ($whereBinder as $name => $value) {
79
            if (is_array($value) || $value instanceof ArrayObject) {
80
                list($inSQL, $binders) = $this->prepareInParameter($value, $name);
81
                $newWhereBinder = array_merge($newWhereBinder, $binders);
82
                $name = ltrim($name, ':');
83
                $where = str_replace(':'.$name, $inSQL, $where);
84
            } elseif($value instanceof  Binder) {
85
                $newWhereBinder[] = $value;
86
            }else{
87
                $newWhereBinder[] = new Binder($name, $value);
88
            }
89
        }
90
        return [$where, $newWhereBinder];
91
    }
92
93
94
    /**
95
     * 准备In
96
     *
97
     * @param string $name
98
     * @param ArrayObject|array $values
99
     * @return array
100
     * @throws SQLException
101
     */
102
    protected function prepareIn(string $name, $values)
103
    {
104
        list($inSQL, $binders) = $this->prepareInParameter($values, $name);
105
        $sql = $name.' IN ('.$inSQL.')';
106
        return [$sql,$binders];
107
    }
108
109
    /**
110
     * @param $values
111
     * @param string $name
112
     * @return array
113
     * @throws SQLException
114
     */
115
    protected function prepareInParameter($values, string $name)
116
    {
117
        if (count($values) <= 0) {
118
            throw new SQLException('on field '.$name.' value can\'t be empty array');
119
        }
120
        $names = [];
121
        $binders = [];
122
        foreach ($values as $value) {
123
            $_name = Binder::index($name);
124
            $binders[] = new Binder($_name, $value);
125
            $names[] = ':'.$_name;
126
        }
127
        return [implode(',', $names), $binders];
128
    }
129
130
    /**
131
     * 准备更新
132
     *
133
     * @param array $data
134
     * @return array
135
     */
136
    protected function prepareUpdateSet(array $data)
137
    {
138
        $binders = [];
139
        $sets = [];
140
        foreach ($data as $name => $value) {
141
            $_name = Binder::index($name);
142
            $binders[] = new Binder($_name, $value, $name);
143
            $sets[] = "`{$name}`=:{$_name}";
144
        }
145
        return [implode(',', $sets), $binders];
146
    }
147
148
    /**
149
     * 编译 ? 字符
150
     *
151
     * @param string $sql
152
     * @param array $parameter
153
     * @return array
154
     */
155
    protected function prepareQueryMark(string $sql, array $parameter)
156
    {
157
        $binders = [];
158
        $query = preg_replace_callback('/\?/', function ($match) use (&$binders, $parameter) {
159
            $index = count($binders);
160
            if (array_key_exists($index, $parameter)) {
161
                $name = Binder::index($index);
162
                if (is_array($parameter[$index]) || $parameter[$index] instanceof ArrayObject) {
163
                    list($inSQL, $inBinders) = $this->prepareInParameter($parameter[$index], $index);
164
                    $binders = array_merge($binders, $inBinders);
165
                    return $inSQL;
166
                } else {
167
                    $binder = new Binder($name, $parameter[$index]);
168
                    $binders[] = $binder;
169
                    return ':'.$binder->getName();
170
                }
171
            }
172
            return $match[0];
173
        }, $sql);
174
        return [$query, $binders];
175
    }
176
177
    /**
178
     * 合并绑定工具
179
     *
180
     * @param Binder[] $binder
181
     * @param array $parameter
182
     * @return Binder[]
183
     */
184
    protected function mergeBinder(array $binder, array $parameter)
185
    {
186
        foreach ($parameter as $key => $value) {
187
            if ($value instanceof Binder) {
188
                $binder[] = $value;
189
            } else {
190
                $binder[] = new Binder($key, $value);
191
            }
192
        }
193
        return $binder;
194
    }
195
}
196