Passed
Push — master ( acba12...b2f89b )
by 世昌
04:15
created

ReadStatement::prepareWhere()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace suda\database\statement;
4
5
use function func_get_args;
6
use function func_num_args;
7
use function is_array;
8
use suda\database\struct\TableStruct;
9
use suda\database\middleware\Middleware;
10
use suda\database\exception\SQLException;
11
12
/**
13
 * Class ReadStatement
14
 * @package suda\database\statement
15
 */
16
class ReadStatement extends QueryStatement
17
{
18
    use PrepareTrait;
19
20
    /**
21
     * 数据表结构
22
     *
23
     * @var TableStruct
24
     */
25
    protected $struct;
26
27
    /**
28
     * 数据原始表名
29
     *
30
     * @var string
31
     */
32
    protected $table;
33
34
    /**
35
     * @var string
36
     */
37
    protected $distinct = '';
38
39
    /**
40
     * @var string
41
     */
42
    protected $select = '*';
43
44
    /**
45
     * @var string
46
     */
47
    protected $where = '';
48
49
    /**
50
     * @var string
51
     */
52
    protected $groupBy = '';
53
54
    /**
55
     * @var string
56
     */
57
    protected $having = '';
58
59
    /**
60
     * @var string
61
     */
62
    protected $orderBy = '';
63
64
    /**
65
     * @var string
66
     */
67
    protected $limit = '';
68
69
    /**
70
     * @var bool
71
     */
72
    protected $rawRead = true;
73
74
    /**
75
     * 创建写
76
     *
77
     * @param string $rawTableName
78
     * @param TableStruct $struct
79
     * @param Middleware $middleware
80
     * @throws SQLException
81
     */
82
    public function __construct(string $rawTableName, TableStruct $struct, Middleware $middleware)
83
    {
84
        parent::__construct('');
85
        $this->struct = $struct;
86
        $this->table = $rawTableName;
87
        $this->type = self::READ;
88
        $this->fetch = self::FETCH_ONE;
89
        $this->middleware = $middleware;
90
    }
91
92
    /**
93
     * 单独去重复
94
     *
95
     * @return $this
96
     */
97
    public function distinct()
98
    {
99
        $this->distinct = 'DISTINCT';
100
        return $this;
101
    }
102
103
    /**
104
     * 查询的列
105
     *
106
     * @param array|string $fields
107
     * @return $this
108
     */
109
    public function read($fields)
110
    {
111
        if (func_num_args() > 1) {
112
            $fields = func_get_args();
113
        }
114
        if (is_array($fields)) {
115
            $this->rawRead = false;
116
            foreach ($fields as $index => $name) {
117
                $fields[$index] = $this->middleware->inputName($name);
118
            }
119
        }
120
        $this->select = $this->prepareReadFields($fields);
121
        return $this;
122
    }
123
124
    /**
125
     * @return bool
126
     */
127
    public function isRawRead(): bool
128
    {
129
        return $this->rawRead;
130
    }
131
132
133
    /**
134
     * 条件
135
     * @param $where
136
     * @param mixed ...$args
137
     * @return $this
138
     * @throws SQLException
139
     */
140
    public function where($where, ...$args)
141
    {
142
        if (is_array($where)) {
143
            $this->whereArray($where, $args[0] ?? []);
144
        } elseif (count($args) > 0 && is_array($args[0])) {
145
            $this->whereStringArray($where, $args[0]);
146
        } else {
147
            list($string, $array) = $this->prepareQueryMark($where, $args);
148
            $this->whereStringArray($string, $array);
149
        }
150
        return $this;
151
    }
152
153
    /**
154
     * 处理输入的键
155
     *
156
     * @param array $fields
157
     * @return array
158
     */
159
    protected function aliasKeyField(array $fields)
160
    {
161
        $values = [];
162
        foreach ($fields as $value) {
163
            $value[0] = $this->middleware->inputName($value[0]);
164
            $values[] = $value;
165
        }
166
        return $values;
167
    }
168
169
    /**
170
     * @param array $where
171
     * @param array $binders
172
     * @throws SQLException
173
     */
174
    protected function whereArray(array $where, array $binders)
175
    {
176
        list($where, $whereBinder) = $this->prepareWhere($where);
177
        $this->whereStringArray($where, array_merge($whereBinder, $binders));
178
    }
179
180
    /**
181
     * @param array $where
182
     * @return array
183
     * @throws SQLException
184
     */
185
    public function prepareWhere(array $where)
186
    {
187
        $where = $this->normalizeWhereArray($where);
188
        $where = $this->aliasKeyField($where);
189
        return parent::prepareWhere($where);
190
    }
191
192
    /**
193
     * @param string $where
194
     * @param array $whereBinder
195
     * @throws SQLException
196
     */
197
    protected function whereStringArray(string $where, array $whereBinder)
198
    {
199
        list($where, $whereBinder) = $this->prepareWhereString($where, $whereBinder);
200
        $this->where = 'WHERE ' . $where;
201
        $this->binder = $this->mergeBinder($this->binder, $whereBinder);
202
    }
203
204
    /**
205
     * 分组
206
     *
207
     * @param string $what
208
     * @return $this
209
     */
210
    public function groupBy(string $what)
211
    {
212
        $what = $this->middleware->inputName($what);
213
        $this->groupBy = 'GROUP BY `' . $what . '`';
214
        return $this;
215
    }
216
217
    /**
218
     * 含
219
     *
220
     * @param string|array $what
221
     * @param array $args
222
     * @return $this
223
     * @throws SQLException
224
     */
225
    public function having($what, ...$args)
226
    {
227
        if (is_array($what)) {
228
            $this->havingArray($what);
229
        } elseif (is_array($args[0])) {
230
            $this->havingStringArray($what, $args[0]);
231
        } else {
232
            list($string, $array) = $this->prepareQueryMark($what, $args);
233
            $this->havingStringArray($string, $array);
234
        }
235
        return $this;
236
    }
237
238
    /**
239
     * @param array $want
240
     * @throws SQLException
241
     */
242
    protected function havingArray(array $want)
243
    {
244
        list($having, $havingBinder) = $this->prepareWhere($want);
245
        $this->havingStringArray($having, $havingBinder);
246
    }
247
248
    /**
249
     * @param string $having
250
     * @param array $havingBinder
251
     * @throws SQLException
252
     */
253
    protected function havingStringArray(string $having, array $havingBinder)
254
    {
255
        list($having, $havingBinder) = $this->prepareWhereString($having, $havingBinder);
256
        $this->having = 'HAVING ' . $having;
257
        $this->binder = $this->mergeBinder($this->binder, $havingBinder);
258
    }
259
260
    /**
261
     * 排序
262
     *
263
     * @param string $what
264
     * @param string $order
265
     * @return $this
266
     */
267
    public function orderBy(string $what, string $order = 'ASC')
268
    {
269
        $what = $this->middleware->inputName($what);
270
        $order = strtoupper($order);
271
        if (strlen($this->orderBy) > 0) {
272
            $this->orderBy .= ',`' . $what . '` ' . $order;
273
        } else {
274
            $this->orderBy = 'ORDER BY `' . $what . '` ' . $order;
275
        }
276
        return $this;
277
    }
278
279
    /**
280
     * 清除排序语句
281
     */
282
    public function clearOrderBy() {
283
        $this->orderBy = '';
284
        return $this;
285
    }
286
287
    /**
288
     * 限制
289
     *
290
     * @param int $start
291
     * @param integer $length
292
     * @return $this
293
     */
294
    public function limit(int $start, int $length = null)
295
    {
296
        $this->limit = 'LIMIT ' . $start . ($length !== null ? ',' . $length : '');
297
        return $this;
298
    }
299
300
    /**
301
     * 分页
302
     *
303
     * @param integer $page
304
     * @param integer $length
305
     * @return $this
306
     */
307
    public function page(int $page, int $length)
308
    {
309
        if ($page <= 0) {
310
            $page = 1;
311
        }
312
        $this->limit(($page - 1) * $length, $length);
313
        return $this;
314
    }
315
316
    /**
317
     * 获取字符串
318
     *
319
     * @return Query
320
     */
321
    protected function prepareQuery(): Query
322
    {
323
        $where = [$this->where, $this->groupBy, $this->having, $this->orderBy, $this->limit];
324
        $condition = implode(' ', array_filter(array_map('trim', $where), 'strlen'));
325
        $select = [$this->distinct, $this->select];
326
        $selection = implode(' ', array_filter(array_map('trim', $select), 'strlen'));
327
        $string = sprintf("SELECT %s FROM %s %s", $selection, $this->table, $condition);
328
        return new Query($string, $this->binder);
329
    }
330
}
331