Passed
Push — master ( f9244b...ce4141 )
by 世昌
02:39 queued 14s
created

WriteStatement::prepareWriteField()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace suda\database\statement;
4
5
use function implode;
6
use function is_array;
7
use function is_string;
8
use function sprintf;
9
use suda\database\Binder;
10
use suda\database\struct\TableStruct;
11
use suda\database\middleware\Middleware;
12
use suda\database\exception\SQLException;
13
14
class WriteStatement extends Statement
15
{
16
    use PrepareTrait;
17
18
    /**
19
     * 数据
20
     *
21
     * @var array|string
22
     */
23
    protected $data;
24
25
    /**
26
     * 数据表结构
27
     *
28
     * @var TableStruct
29
     */
30
    protected $struct;
31
32
    /**
33
     * 数据原始表名
34
     *
35
     * @var string
36
     */
37
    protected $table;
38
39
    /**
40
     * 模板条件条件
41
     *
42
     * @var string|null
43
     */
44
    protected $whereCondition = null;
45
46
    /**
47
     * 是否为删除
48
     *
49
     * @var bool
50
     */
51
    protected $delete = false;
52
53
54
    /**
55
     * 创建写
56
     *
57
     * @param string $rawTableName
58
     * @param TableStruct $struct
59
     * @param Middleware $middleware
60
     * @throws SQLException
61
     */
62
    public function __construct(string $rawTableName, TableStruct $struct, Middleware $middleware)
63
    {
64
        parent::__construct('');
65
        $this->type = self::WRITE;
66
        $this->struct = $struct;
67
        $this->table = $rawTableName;
68
        $this->middleware = $middleware;
69
    }
70
71
    /**
72
     * 写数据
73
     *
74
     * @param string|array $name
75
     * @param mixed $value
76
     * @return $this
77
     * @throws SQLException
78
     */
79
    public function write($name, $value = null)
80
    {
81
        $argcount = func_num_args();
82
        if (is_array($name)) {
83
            foreach ($name as $key => $value) {
84
                $this->write($key, $value);
85
            }
86
        } elseif (is_string($name) && $argcount >= 2) {
87
            $this->prepareWriteField($name, $value);
88
        } else {
89
            $this->data = $name;
90
        }
91
        return $this;
92
    }
93
94
    /**
95
     * 准备字段
96
     *
97
     * @param string $name
98
     * @param mixed $value
99
     * @return void
100
     */
101
    private function prepareWriteField(string $name, $value) {
102
        $name = $this->middleware->inputName($name);
103
        if ($this->struct->hasField($name)) {
104
            $this->data[$name] = $value;
105
        } else {
106
            throw new SQLException(sprintf('table %s has no field %s', $this->struct->getName(), $name));
107
        }
108
    }
109
110
    /**
111
     * 设置影响行数
112
     *
113
     * @return $this
114
     */
115
    public function wantRows()
116
    {
117
        $this->returnType = WriteStatement::RET_ROWS;
118
        return $this;
119
    }
120
121
    /**
122
     * 设置返回是否成功
123
     *
124
     * @return $this
125
     */
126
    public function wantOk()
127
    {
128
        $this->returnType = WriteStatement::RET_BOOL;
129
        return $this;
130
    }
131
132
    /**
133
     * 设置返回ID
134
     *
135
     * @return $this
136
     */
137
    public function wantId()
138
    {
139
        $this->returnType = WriteStatement::RET_LAST_INSERT_ID;
140
        return $this;
141
    }
142
143
    /**
144
     * 删除
145
     *
146
     * @return $this
147
     */
148
    public function delete()
149
    {
150
        $this->delete = true;
151
        return $this;
152
    }
153
154
    /**
155
     * 条件查询
156
     *
157
     * @param string|array $where
158
     * @param array $args
159
     * @return $this
160
     * @throws SQLException
161
     */
162
    public function where($where, ...$args)
163
    {
164
        if (is_string($where)) {
165
            if (count($args) > 0 && is_array($args[0])) {
166
                $whereParameter = $args[0];
167
                $this->whereCondition($where, $whereParameter);
168
            } else {
169
                list($string, $array) = $this->prepareQueryMark($where, $args);
170
                $this->whereCondition($string, $array);
171
            }
172
        } else {
173
            $this->aliasKeyField($where);
174
            $this->arrayWhereCondition($where, $args[0] ?? []);
175
        }
176
        return $this;
177
    }
178
179
    /**
180
     * 处理输入的键
181
     *
182
     * @param array $fields
183
     * @return array
184
     */
185
    protected function aliasKeyField(array $fields)
186
    {
187
        $values = [];
188
        foreach ($fields as $name => $value) {
189
            $index = $this->middleware->inputName($name);
190
            $values[$index] = $value;
191
        }
192
        return $values;
193
    }
194
195
    /**
196
     * 获取字符串
197
     *
198
     * @return Query
199
     */
200
    protected function prepareQuery(): Query
201
    {
202
        if (is_array($this->data) && $this->whereCondition === null) {
203
            return $this->parepareInsert($this->data);
204
        } else {
205
            if ($this->delete === false) {
206
                if (is_string($this->data)) {
207
                    $updateSet = trim($this->data);
208
                } else {
209
                    list($updateSet, $upBinder) = $this->prepareUpdateSet($this->data);
210
                    $this->binder = array_merge($this->binder, $upBinder);
211
                }
212
                $string = "UPDATE {$this->table} SET {$updateSet} WHERE {$this->whereCondition}";
213
                return new Query($string, $this->binder);
214
            } else {
215
                $string = "DELETE FROM {$this->table} WHERE {$this->whereCondition}";
216
                return new Query($string, $this->binder);
217
            }
218
        }
219
    }
220
221
    /**
222
     * 字符串式绑定
223
     *
224
     * @param string $where
225
     * @param array $whereParameter
226
     * @return void
227
     * @throws SQLException
228
     */
229
    protected function whereCondition(string $where, array $whereParameter)
230
    {
231
        list($this->whereCondition, $whereBinder) = $this->prepareWhereString($where, $whereParameter);
232
        $this->binder = array_merge($this->binder, $whereBinder);
233
    }
234
235
    /**
236
     * 数组条件式绑定
237
     *
238
     * @param array $where
239
     * @param array $whereParameter
240
     * @return void
241
     * @throws SQLException
242
     */
243
    protected function arrayWhereCondition(array $where, array $whereParameter)
244
    {
245
        list($this->whereCondition, $whereBinder) = $this->prepareWhere($where);
246
        $this->binder = array_merge($this->binder, $whereBinder);
247
        foreach ($whereParameter as $key => $value) {
248
            $this->binder[] = new Binder($key, $value);
249
        }
250
    }
251
252
    /**
253
     * 准备插入语句
254
     *
255
     * @param array $data
256
     * @return Query
257
     */
258
    public function parepareInsert(array $data): Query
259
    {
260
        $names = [];
261
        $binds = [];
262
        $this->binder;
263
        foreach ($data as $name => $value) {
264
            $_name = Binder::index($name);
265
            $this->binder[] = new Binder($_name, $value, $name);
266
            $names[] = "`{$name}`";
267
            $binds[] = ":{$_name}";
268
        }
269
        $i_name = implode(',', $names);
270
        $i_bind = implode(',', $binds);
271
        return new Query(sprintf('INSERT INTO %s (%s) VALUES (%s)', $this->table, $i_name, $i_bind), $this->binder);
272
    }
273
}
274