@maiyunnet/kebab 2.0.6 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +11 -1
- package/index.js +13 -1
- package/lib/buffer.d.ts +25 -0
- package/lib/buffer.js +30 -5
- package/lib/captcha.d.ts +15 -0
- package/lib/captcha.js +20 -0
- package/lib/consistent.d.ts +51 -0
- package/lib/consistent.js +59 -0
- package/lib/core.d.ts +134 -0
- package/lib/core.js +176 -0
- package/lib/crypto.d.ts +75 -6
- package/lib/crypto.js +206 -38
- package/lib/db.d.ts +104 -0
- package/lib/db.js +126 -0
- package/lib/dns.d.ts +51 -0
- package/lib/dns.js +54 -2
- package/lib/fs.d.ts +100 -0
- package/lib/fs.js +118 -0
- package/lib/jwt.d.ts +43 -0
- package/lib/jwt.js +45 -0
- package/lib/kv.d.ts +362 -0
- package/lib/kv.js +377 -0
- package/lib/lan.d.ts +6 -0
- package/lib/lan.js +7 -0
- package/lib/net/formdata.d.ts +38 -0
- package/lib/net/formdata.js +43 -0
- package/lib/net/request.d.ts +62 -0
- package/lib/net/request.js +57 -0
- package/lib/net/response.d.ts +21 -0
- package/lib/net/response.js +16 -0
- package/lib/net.d.ts +86 -0
- package/lib/net.js +140 -0
- package/lib/s3.d.ts +52 -0
- package/lib/s3.js +51 -0
- package/lib/scan.d.ts +52 -0
- package/lib/scan.js +84 -0
- package/lib/session.d.ts +31 -0
- package/lib/session.js +52 -1
- package/lib/sql.d.ts +176 -0
- package/lib/sql.js +287 -2
- package/lib/ssh/sftp.d.ts +106 -0
- package/lib/ssh/sftp.js +106 -0
- package/lib/ssh/shell.d.ts +37 -0
- package/lib/ssh/shell.js +31 -0
- package/lib/ssh.d.ts +32 -0
- package/lib/ssh.js +32 -0
- package/lib/text.d.ts +131 -0
- package/lib/text.js +188 -0
- package/lib/time.d.ts +53 -0
- package/lib/time.js +55 -0
- package/lib/ws.d.ts +68 -0
- package/lib/ws.js +74 -0
- package/lib/zip.d.ts +53 -0
- package/lib/zip.js +73 -0
- package/lib/zlib.d.ts +76 -0
- package/lib/zlib.js +78 -0
- package/main.d.ts +6 -1
- package/main.js +11 -1
- package/package.json +2 -2
- package/sys/child.js +104 -0
- package/sys/cmd.js +28 -0
- package/sys/ctr.d.ts +166 -0
- package/sys/ctr.js +177 -0
- package/sys/master.js +63 -0
- package/sys/mod.d.ts +266 -0
- package/sys/mod.js +335 -0
- package/sys/route.d.ts +34 -0
- package/sys/route.js +164 -0
- package/www/example/ctr/test.d.ts +3 -0
- package/www/example/ctr/test.js +63 -1
- package/www/example/mod/test.js +14 -0
- package/www/example/mod/testdata.js +9 -0
- package/www/example/ws/test.js +1 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/details.md +0 -82
- package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +0 -15
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +0 -2
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +0 -19
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +0 -22
- package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +0 -69
- package/.VSCodeCounter/2025-02-14_14-46-44/results.json +0 -1
- package/.VSCodeCounter/2025-02-14_14-46-44/results.md +0 -48
- package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +0 -118
- package/.vscode/tasks.json +0 -15
package/lib/sql.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
4
|
+
* Date: 2019-5-27 20:18:50
|
|
5
|
+
* Last: 2020-3-29 19:37:25, 2022-07-24 22:38:11, 2023-5-24 18:49:18, 2023-6-13 22:20:21, 2023-12-11 13:58:54, 2023-12-14 13:14:40, 2023-12-21 00:04:40, 2024-4-11 19:29:29, 2024-9-2 17:15:28
|
|
6
|
+
*/
|
|
2
7
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
8
|
if (k2 === undefined) k2 = k;
|
|
4
9
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -40,14 +45,22 @@ exports.aoMix = aoMix;
|
|
|
40
45
|
exports.column = column;
|
|
41
46
|
const lText = __importStar(require("../lib/text"));
|
|
42
47
|
const lCore = __importStar(require("../lib/core"));
|
|
48
|
+
// --- 第三方 ---
|
|
43
49
|
const mysql2 = __importStar(require("mysql2/promise"));
|
|
50
|
+
// --- 库和定义 ---
|
|
44
51
|
const ctr = __importStar(require("../sys/ctr"));
|
|
52
|
+
/** --- filed 用 token --- */
|
|
45
53
|
let columnToken = '';
|
|
46
54
|
class Sql {
|
|
55
|
+
// --- 实例化 ---
|
|
47
56
|
constructor(pre, opt = {}) {
|
|
57
|
+
/** --- 前置 --- */
|
|
48
58
|
this._pre = '';
|
|
59
|
+
/** --- 预拼装 Sql 数组 --- */
|
|
49
60
|
this._sql = [];
|
|
61
|
+
/** --- 所有 data 数据 --- */
|
|
50
62
|
this._data = [];
|
|
63
|
+
/** --- where 的 data 的开始处和结束处 --- */
|
|
51
64
|
this._whereDataPosition = [0, 0];
|
|
52
65
|
this._pre = pre ?? '';
|
|
53
66
|
if (opt.data) {
|
|
@@ -57,21 +70,37 @@ class Sql {
|
|
|
57
70
|
this._sql = opt.sql;
|
|
58
71
|
}
|
|
59
72
|
}
|
|
73
|
+
// --- 前导 ---
|
|
74
|
+
/**
|
|
75
|
+
* --- 插入数据前导 ---
|
|
76
|
+
* @param table 表名
|
|
77
|
+
*/
|
|
60
78
|
insert(table) {
|
|
61
79
|
this._data = [];
|
|
62
80
|
const sql = 'INSERT INTO ' + this.field(table, this._pre);
|
|
63
81
|
this._sql = [sql];
|
|
64
82
|
return this;
|
|
65
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* --- 替换已经存在的唯一索引数据,不存在则插入 ---
|
|
86
|
+
* @param table 表名
|
|
87
|
+
*/
|
|
66
88
|
replace(table) {
|
|
67
89
|
this._data = [];
|
|
68
90
|
const sql = 'REPLACE INTO ' + this.field(table, this._pre);
|
|
69
91
|
this._sql = [sql];
|
|
70
92
|
return this;
|
|
71
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* --- 实际插入数据的数据 ---
|
|
96
|
+
* @param cs [] 数据列或字段列
|
|
97
|
+
* @param vs [] | [][] 数据
|
|
98
|
+
*/
|
|
72
99
|
values(cs, vs = []) {
|
|
73
100
|
let sql = ' (';
|
|
74
101
|
if (Array.isArray(cs)) {
|
|
102
|
+
// --- ['id', 'name'], [['1', 'wow'], ['2', 'oh']] ---
|
|
103
|
+
// --- ['id', 'name'], ['1', 'wow'] ---
|
|
75
104
|
for (const i of cs) {
|
|
76
105
|
sql += this.field(i) + ', ';
|
|
77
106
|
}
|
|
@@ -79,10 +108,14 @@ class Sql {
|
|
|
79
108
|
if (!Array.isArray(vs[0])) {
|
|
80
109
|
vs = [vs];
|
|
81
110
|
}
|
|
111
|
+
// --- INSERT INTO xx (id, name) VALUES (?, ?) ---
|
|
112
|
+
// --- INSERT INTO xx (id, name) VALUES (?, ?), (?, ?) ---
|
|
82
113
|
for (const v of vs) {
|
|
83
114
|
sql += '(';
|
|
84
115
|
for (const v1 of v) {
|
|
116
|
+
// --- v1 是项目值,如 {'x': 1, 'y': 2}, 'string', 0 ---
|
|
85
117
|
if (v1 === undefined || Number.isNaN(v1)) {
|
|
118
|
+
// --- 异常情况 ---
|
|
86
119
|
lCore.log({
|
|
87
120
|
'path': '',
|
|
88
121
|
'urlFull': '',
|
|
@@ -92,6 +125,7 @@ class Sql {
|
|
|
92
125
|
'cookie': {},
|
|
93
126
|
'headers': {}
|
|
94
127
|
}, '(sql.values) value error', '-error').catch(() => {
|
|
128
|
+
//
|
|
95
129
|
});
|
|
96
130
|
sql += `'', `;
|
|
97
131
|
}
|
|
@@ -105,12 +139,14 @@ class Sql {
|
|
|
105
139
|
else if (Array.isArray(v1)) {
|
|
106
140
|
if (v1[0]?.[0]?.x === undefined && typeof v1[0] === 'string' &&
|
|
107
141
|
v1[0].includes('(') && v1[0].includes(')')) {
|
|
142
|
+
// --- v1: ['POINT(?)', ['20']] ---
|
|
108
143
|
sql += this.field(v1[0]) + ', ';
|
|
109
144
|
if (v1[1]) {
|
|
110
145
|
this._data.push(...v1[1]);
|
|
111
146
|
}
|
|
112
147
|
}
|
|
113
148
|
else if (v1[0]?.[0]?.y !== undefined) {
|
|
149
|
+
// --- v1: [[{'x': 1, 'y': 2}, { ... }], [{ ... }, { ... }]] ---
|
|
114
150
|
sql += 'ST_POLYGONFROMTEXT(?), ';
|
|
115
151
|
this._data.push(`POLYGON(${v1.map((item) => {
|
|
116
152
|
return `(${item.map((it) => {
|
|
@@ -119,28 +155,34 @@ class Sql {
|
|
|
119
155
|
}).join(', ')})`);
|
|
120
156
|
}
|
|
121
157
|
else {
|
|
158
|
+
// --- v1: json ---
|
|
122
159
|
sql += '?, ';
|
|
123
160
|
this._data.push(lText.stringifyJson(v1));
|
|
124
161
|
}
|
|
125
162
|
}
|
|
126
163
|
else if (v1.x !== undefined) {
|
|
127
164
|
if (v1.y !== undefined) {
|
|
165
|
+
// --- v1: {'x': 1, 'y': 2} ---
|
|
128
166
|
sql += 'ST_POINTFROMTEXT(?), ';
|
|
129
167
|
this._data.push(`POINT(${v1.x} ${v1.y})`);
|
|
130
168
|
}
|
|
131
169
|
else {
|
|
170
|
+
// --- v1: json ---
|
|
132
171
|
sql += '?, ';
|
|
133
172
|
this._data.push(lText.stringifyJson(v1));
|
|
134
173
|
}
|
|
135
174
|
}
|
|
136
175
|
else if (v1 instanceof Buffer) {
|
|
176
|
+
// --- Buffer ---
|
|
137
177
|
sql += '?, ';
|
|
138
178
|
this._data.push(v);
|
|
139
179
|
}
|
|
140
180
|
else if (this._isField(v1)) {
|
|
181
|
+
// --- 3 ---
|
|
141
182
|
sql += this.field(v1.value) + ', ';
|
|
142
183
|
}
|
|
143
184
|
else {
|
|
185
|
+
// --- json ---
|
|
144
186
|
sql += '?, ';
|
|
145
187
|
this._data.push(lText.stringifyJson(v1));
|
|
146
188
|
}
|
|
@@ -150,11 +192,14 @@ class Sql {
|
|
|
150
192
|
sql = sql.slice(0, -2);
|
|
151
193
|
}
|
|
152
194
|
else {
|
|
195
|
+
// --- {'id': '1', 'name': 'wow'} ---
|
|
196
|
+
// --- INSERT INTO xx (id, name) VALUES (?, ?) ---
|
|
153
197
|
let values = '';
|
|
154
198
|
for (const k in cs) {
|
|
155
199
|
const v = cs[k];
|
|
156
200
|
sql += this.field(k) + ', ';
|
|
157
201
|
if (v === undefined || Number.isNaN(v)) {
|
|
202
|
+
// --- 异常情况 ---
|
|
158
203
|
lCore.log({
|
|
159
204
|
'path': '',
|
|
160
205
|
'urlFull': '',
|
|
@@ -164,6 +209,7 @@ class Sql {
|
|
|
164
209
|
'cookie': {},
|
|
165
210
|
'headers': {}
|
|
166
211
|
}, '(sql.values) value error', '-error').catch(() => {
|
|
212
|
+
//
|
|
167
213
|
});
|
|
168
214
|
values += `'', `;
|
|
169
215
|
}
|
|
@@ -177,12 +223,14 @@ class Sql {
|
|
|
177
223
|
else if (Array.isArray(v)) {
|
|
178
224
|
if (v[0]?.[0]?.x === undefined && typeof v[0] === 'string' &&
|
|
179
225
|
v[0].includes('(') && v[0].includes(')')) {
|
|
226
|
+
// --- v: ['POINT(?)', ['20']] ---
|
|
180
227
|
values += this.field(v[0]) + ', ';
|
|
181
228
|
if (v[1] !== undefined) {
|
|
182
229
|
this._data.push(...v[1]);
|
|
183
230
|
}
|
|
184
231
|
}
|
|
185
232
|
else if (v[0]?.[0]?.y !== undefined) {
|
|
233
|
+
// --- v: [[{'x': 1, 'y': 2}, { ... }], [{ ... }, { ... }]] ---
|
|
186
234
|
values += 'ST_POLYGONFROMTEXT(?), ';
|
|
187
235
|
this._data.push(`POLYGON(${v.map((item) => {
|
|
188
236
|
return `(${item.map((it) => {
|
|
@@ -191,28 +239,34 @@ class Sql {
|
|
|
191
239
|
}).join(', ')})`);
|
|
192
240
|
}
|
|
193
241
|
else {
|
|
242
|
+
// --- v: json ---
|
|
194
243
|
values += '?, ';
|
|
195
244
|
this._data.push(lText.stringifyJson(v));
|
|
196
245
|
}
|
|
197
246
|
}
|
|
198
247
|
else if (v.x !== undefined) {
|
|
199
248
|
if (v.y !== undefined) {
|
|
249
|
+
// --- v: {'x': 1, 'y': 2} ---
|
|
200
250
|
values += 'ST_POINTFROMTEXT(?), ';
|
|
201
251
|
this._data.push(`POINT(${v.x} ${v.y})`);
|
|
202
252
|
}
|
|
203
253
|
else {
|
|
254
|
+
// --- v: json ---
|
|
204
255
|
values += '?, ';
|
|
205
256
|
this._data.push(lText.stringifyJson(v));
|
|
206
257
|
}
|
|
207
258
|
}
|
|
208
259
|
else if (v instanceof Buffer) {
|
|
260
|
+
// --- Buffer ---
|
|
209
261
|
values += '?, ';
|
|
210
262
|
this._data.push(v);
|
|
211
263
|
}
|
|
212
264
|
else if (this._isField(v)) {
|
|
265
|
+
// --- 3 ---
|
|
213
266
|
values += this.field(v.value) + ', ';
|
|
214
267
|
}
|
|
215
268
|
else {
|
|
269
|
+
// --- json ---
|
|
216
270
|
values += '?, ';
|
|
217
271
|
this._data.push(lText.stringifyJson(v));
|
|
218
272
|
}
|
|
@@ -222,6 +276,12 @@ class Sql {
|
|
|
222
276
|
this._sql.push(sql);
|
|
223
277
|
return this;
|
|
224
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* --- 不存在则插入,衔接在 insert 之后 ---
|
|
281
|
+
* @param table 表名
|
|
282
|
+
* @param insert {'xx': 'xx', 'xx': 'xx'}
|
|
283
|
+
* @param where [{'xx': 'xx', 'xx': 'xx'}], {'xx': 'xx'}
|
|
284
|
+
*/
|
|
225
285
|
notExists(table, insert, where) {
|
|
226
286
|
let sql = '(';
|
|
227
287
|
const values = [];
|
|
@@ -245,6 +305,10 @@ class Sql {
|
|
|
245
305
|
this._sql.push(sql);
|
|
246
306
|
return this;
|
|
247
307
|
}
|
|
308
|
+
/**
|
|
309
|
+
* --- 当不能 insert 时,update(仅能配合 insert 方法用) ---
|
|
310
|
+
* @param s 更新数据
|
|
311
|
+
*/
|
|
248
312
|
duplicate(s) {
|
|
249
313
|
if (Array.isArray(s) ? s.length : Object.keys(s).length) {
|
|
250
314
|
const sql = ' ON DUPLICATE KEY UPDATE ' + this._updateSub(s);
|
|
@@ -252,6 +316,11 @@ class Sql {
|
|
|
252
316
|
}
|
|
253
317
|
return this;
|
|
254
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* --- '*', 'xx' ---
|
|
321
|
+
* @param c 字段字符串或字段数组
|
|
322
|
+
* @param f 表,允许多张表
|
|
323
|
+
*/
|
|
255
324
|
select(c, f) {
|
|
256
325
|
this._data = [];
|
|
257
326
|
let sql = 'SELECT ';
|
|
@@ -259,8 +328,10 @@ class Sql {
|
|
|
259
328
|
sql += this.field(c);
|
|
260
329
|
}
|
|
261
330
|
else {
|
|
331
|
+
// --- c: ['id', 'name'] ---
|
|
262
332
|
for (const i of c) {
|
|
263
333
|
if (Array.isArray(i)) {
|
|
334
|
+
// --- i: ['xx', ['x']] ---
|
|
264
335
|
sql += this.field(i[0]) + ', ';
|
|
265
336
|
this._data.push(...i[1]);
|
|
266
337
|
}
|
|
@@ -275,6 +346,7 @@ class Sql {
|
|
|
275
346
|
sql += this.field(f, this._pre);
|
|
276
347
|
}
|
|
277
348
|
else {
|
|
349
|
+
// --- f: ['user', 'order'] ---
|
|
278
350
|
for (const i of f) {
|
|
279
351
|
sql += this.field(i, this._pre) + ', ';
|
|
280
352
|
}
|
|
@@ -283,6 +355,11 @@ class Sql {
|
|
|
283
355
|
this._sql = [sql];
|
|
284
356
|
return this;
|
|
285
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* --- UPDATE SQL 方法 ---
|
|
360
|
+
* @param f 表名
|
|
361
|
+
* @param s 设定 update 的值
|
|
362
|
+
*/
|
|
286
363
|
update(f, s) {
|
|
287
364
|
this._data = [];
|
|
288
365
|
const sql = `UPDATE ${this.field(f, this._pre)} SET ${this._updateSub(s)}`;
|
|
@@ -290,11 +367,27 @@ class Sql {
|
|
|
290
367
|
return this;
|
|
291
368
|
}
|
|
292
369
|
_updateSub(s) {
|
|
370
|
+
/*
|
|
371
|
+
[
|
|
372
|
+
['total', '+', '1'], // 1, '1' 可能也是 1 数字类型
|
|
373
|
+
{
|
|
374
|
+
'type': '6', // 2
|
|
375
|
+
'type': column('type2'), // 3
|
|
376
|
+
// 'type': ['type3'], // 4 - 此写法已被禁止,请用 (3) 代替
|
|
377
|
+
'type': ['(CASE `id` WHEN 1 THEN ? WHEN 2 THEN ? END)', ['val1', 'val2']], // 5
|
|
378
|
+
'point': { 'x': 0, 'y': 0 }, // 6
|
|
379
|
+
'polygon': [ [ { 'x': 0, 'y': 0 }, { ... } ], [ ... ] ], // 7
|
|
380
|
+
'json': { 'a': 1, 'b': { 'c': 2 }, 'c': [ { 'c': 2 } ] }, // 8 - 对象类 json,可能为空对象
|
|
381
|
+
'json2': ['abc'] // 9 - 数组类 json,可能为空数组
|
|
382
|
+
}
|
|
383
|
+
]
|
|
384
|
+
*/
|
|
293
385
|
s = aoMix(s);
|
|
294
386
|
let sql = '';
|
|
295
387
|
for (const k in s) {
|
|
296
388
|
const v = s[k];
|
|
297
389
|
if (/^[0-9]+$/.test(k)) {
|
|
390
|
+
// --- 1 ---
|
|
298
391
|
const nv = v[2];
|
|
299
392
|
const isf = this._isField(nv);
|
|
300
393
|
if (isf) {
|
|
@@ -316,8 +409,10 @@ class Sql {
|
|
|
316
409
|
}
|
|
317
410
|
}
|
|
318
411
|
else {
|
|
412
|
+
// --- 2, 3, 4, 5, 6, 7, 8 ---
|
|
319
413
|
sql += this.field(k) + ' = ';
|
|
320
414
|
if (v === undefined || Number.isNaN(v)) {
|
|
415
|
+
// --- 异常情况 ---
|
|
321
416
|
lCore.log({
|
|
322
417
|
'path': '',
|
|
323
418
|
'urlFull': '',
|
|
@@ -327,6 +422,7 @@ class Sql {
|
|
|
327
422
|
'cookie': {},
|
|
328
423
|
'headers': {}
|
|
329
424
|
}, '(sql._updateSub) value error, key: ' + k, '-error').catch(() => {
|
|
425
|
+
//
|
|
330
426
|
});
|
|
331
427
|
sql += '"", ';
|
|
332
428
|
}
|
|
@@ -334,18 +430,21 @@ class Sql {
|
|
|
334
430
|
sql += 'NULL, ';
|
|
335
431
|
}
|
|
336
432
|
else if (typeof v === 'string' || typeof v === 'number') {
|
|
433
|
+
// --- 2 ---
|
|
337
434
|
sql += '?, ';
|
|
338
435
|
this._data.push(v);
|
|
339
436
|
}
|
|
340
437
|
else if (Array.isArray(v)) {
|
|
341
438
|
if (v[0]?.[0]?.x === undefined && typeof v[0] === 'string' &&
|
|
342
439
|
v[0].includes('(') && v[0].includes(')')) {
|
|
440
|
+
// --- 4, 5: ['(CASE `id` WHEN 1 THEN ? WHEN 2 THEN ? END)', ['val1', 'val2']] ---
|
|
343
441
|
sql += this.field(v[0]) + ', ';
|
|
344
442
|
if (v[1] !== undefined) {
|
|
345
443
|
this._data.push(...v[1]);
|
|
346
444
|
}
|
|
347
445
|
}
|
|
348
446
|
else if (v[0]?.[0]?.y !== undefined) {
|
|
447
|
+
// --- 7 ---
|
|
349
448
|
sql += 'ST_POLYGONFROMTEXT(?), ';
|
|
350
449
|
this._data.push(`POLYGON(${v.map((item) => {
|
|
351
450
|
return `(${item.map((it) => {
|
|
@@ -354,33 +453,41 @@ class Sql {
|
|
|
354
453
|
}).join(', ')})`);
|
|
355
454
|
}
|
|
356
455
|
else {
|
|
456
|
+
// --- v: json ---
|
|
357
457
|
sql += '?, ';
|
|
358
458
|
this._data.push(lText.stringifyJson(v));
|
|
359
459
|
}
|
|
360
460
|
}
|
|
361
461
|
else if (v.x !== undefined) {
|
|
362
462
|
if (v.y !== undefined) {
|
|
463
|
+
// --- 6: v: {'x': 1, 'y': 2} ---
|
|
363
464
|
sql += 'ST_POINTFROMTEXT(?), ';
|
|
364
465
|
this._data.push(`POINT(${v.x} ${v.y})`);
|
|
365
466
|
}
|
|
366
467
|
else {
|
|
468
|
+
// --- v: json ---
|
|
367
469
|
if (this._isField(v)) {
|
|
470
|
+
// --- 3 ---
|
|
368
471
|
sql += this.field(v.value) + ', ';
|
|
369
472
|
}
|
|
370
473
|
else {
|
|
474
|
+
// --- 8 ---
|
|
371
475
|
sql += '?, ';
|
|
372
476
|
this._data.push(lText.stringifyJson(v));
|
|
373
477
|
}
|
|
374
478
|
}
|
|
375
479
|
}
|
|
376
480
|
else if (v instanceof Buffer) {
|
|
481
|
+
// --- Buffer ---
|
|
377
482
|
sql += '?, ';
|
|
378
483
|
this._data.push(v);
|
|
379
484
|
}
|
|
380
485
|
else if (this._isField(v)) {
|
|
486
|
+
// --- 3 ---
|
|
381
487
|
sql += this.field(v.value) + ', ';
|
|
382
488
|
}
|
|
383
489
|
else {
|
|
490
|
+
// --- json ---
|
|
384
491
|
sql += '?, ';
|
|
385
492
|
this._data.push(lText.stringifyJson(v));
|
|
386
493
|
}
|
|
@@ -389,23 +496,45 @@ class Sql {
|
|
|
389
496
|
sql = sql.slice(0, -2);
|
|
390
497
|
return sql;
|
|
391
498
|
}
|
|
499
|
+
/**
|
|
500
|
+
* --- 'xx' ---
|
|
501
|
+
* @param f 表名
|
|
502
|
+
*/
|
|
392
503
|
delete(f) {
|
|
393
504
|
this._data = [];
|
|
394
505
|
this._sql = ['DELETE FROM ' + this.field(f, this._pre)];
|
|
395
506
|
return this;
|
|
396
507
|
}
|
|
508
|
+
/**
|
|
509
|
+
* --- 联查另一个 sql 对象 ---
|
|
510
|
+
* @param sql sql 对象
|
|
511
|
+
* @param type 类型
|
|
512
|
+
*/
|
|
397
513
|
union(lsql, type = '') {
|
|
398
514
|
this._data = this._data.concat(lsql.getData());
|
|
399
515
|
this._sql.push(' UNION ' + (type ? type + ' ' : ''));
|
|
400
516
|
this._sql.push(lsql.getSql());
|
|
401
517
|
return this;
|
|
402
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* --- 所有联查另一个 sql 对象 ---
|
|
521
|
+
* @param sql sql 对象
|
|
522
|
+
*/
|
|
403
523
|
unionAll(lsql) {
|
|
404
524
|
return this.union(lsql, 'ALL');
|
|
405
525
|
}
|
|
526
|
+
/**
|
|
527
|
+
* --- join 方法 ---
|
|
528
|
+
* @param f 表名
|
|
529
|
+
* @param s ON 信息
|
|
530
|
+
* @param type 类型
|
|
531
|
+
* @param suf 表后缀
|
|
532
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
533
|
+
*/
|
|
406
534
|
join(f, s = [], type = 'INNER', suf = '', pre = '') {
|
|
407
535
|
let field = this.field(f, pre || this._pre, suf ? ('#' + suf) : '');
|
|
408
536
|
if (pre) {
|
|
537
|
+
// --- 处理不同 pre 的 as 前缀问题 ---
|
|
409
538
|
field = field.replace(new RegExp(`AS \`${pre}(.+?)\``), `AS \`${this._pre}$1\``);
|
|
410
539
|
}
|
|
411
540
|
let sql = ' ' + type + ' JOIN ' + field;
|
|
@@ -415,28 +544,68 @@ class Sql {
|
|
|
415
544
|
this._sql.push(sql);
|
|
416
545
|
return this;
|
|
417
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* --- left join 方法 ---
|
|
549
|
+
* @param f 表名
|
|
550
|
+
* @param s ON 信息
|
|
551
|
+
* @param suf 表后缀
|
|
552
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
553
|
+
*/
|
|
418
554
|
leftJoin(f, s = [], suf = '', pre = '') {
|
|
419
555
|
return this.join(f, s, 'LEFT', suf, pre);
|
|
420
556
|
}
|
|
557
|
+
/**
|
|
558
|
+
* --- right join 方法 ---
|
|
559
|
+
* @param f 表名
|
|
560
|
+
* @param s ON 信息
|
|
561
|
+
* @param suf 表后缀
|
|
562
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
563
|
+
*/
|
|
421
564
|
rightJoin(f, s = [], suf = '', pre = '') {
|
|
422
565
|
return this.join(f, s, 'RIGHT', suf, pre);
|
|
423
566
|
}
|
|
567
|
+
/**
|
|
568
|
+
* --- inner join 方法 ---
|
|
569
|
+
* @param f 表名
|
|
570
|
+
* @param s ON 信息
|
|
571
|
+
* @param suf 表后缀
|
|
572
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
573
|
+
*/
|
|
424
574
|
innerJoin(f, s = [], suf = '', pre = '') {
|
|
425
575
|
return this.join(f, s, 'INNER', suf, pre);
|
|
426
576
|
}
|
|
577
|
+
/**
|
|
578
|
+
* --- full join 方法 ---
|
|
579
|
+
* @param f 表名
|
|
580
|
+
* @param s ON 信息
|
|
581
|
+
* @param suf 表后缀
|
|
582
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
583
|
+
*/
|
|
427
584
|
fullJoin(f, s = [], suf = '', pre = '') {
|
|
428
585
|
return this.join(f, s, 'FULL', suf, pre);
|
|
429
586
|
}
|
|
587
|
+
/**
|
|
588
|
+
* --- cross join 方法 ---
|
|
589
|
+
* @param f 表名
|
|
590
|
+
* @param s ON 信息
|
|
591
|
+
* @param suf 表后缀
|
|
592
|
+
* @param pre 表前缀,仅在 join 非默认表前缀时填写
|
|
593
|
+
*/
|
|
430
594
|
crossJoin(f, s = [], suf = '', pre = '') {
|
|
431
595
|
return this.join(f, s, 'CROSS', suf, pre);
|
|
432
596
|
}
|
|
597
|
+
/**
|
|
598
|
+
* --- having 后置筛选器,用法类似 where ---
|
|
599
|
+
*/
|
|
433
600
|
having(s = '') {
|
|
434
601
|
if (typeof s === 'string') {
|
|
602
|
+
// --- string ---
|
|
435
603
|
if (s !== '') {
|
|
436
604
|
this._sql.push(' HAVING ' + s);
|
|
437
605
|
}
|
|
438
606
|
}
|
|
439
607
|
else {
|
|
608
|
+
// --- array ---
|
|
440
609
|
if (s.length) {
|
|
441
610
|
const whereSub = this._whereSub(s);
|
|
442
611
|
if (whereSub !== '') {
|
|
@@ -446,15 +615,28 @@ class Sql {
|
|
|
446
615
|
}
|
|
447
616
|
return this;
|
|
448
617
|
}
|
|
618
|
+
/**
|
|
619
|
+
* --- 筛选器 ---
|
|
620
|
+
* --- 1. 'city': 'bj', 'type': '2' ---
|
|
621
|
+
* --- 2. ['type', '>', '1'] ---
|
|
622
|
+
* --- 3. ['type', 'in', ['1', '2']] ---
|
|
623
|
+
* --- 4. 'type': ['1', '2'] ---
|
|
624
|
+
* --- 5. '$or': [{'city': 'bj'}, {'city': 'sh'}, [['age', '>', '10']]], 'type': '2' ---
|
|
625
|
+
* --- 6. 'city_in': column('city_out') ---
|
|
626
|
+
* --- 7. ['JSON_CONTAINS(`uid`, ?)', ['hello']] ---
|
|
627
|
+
* @param s 筛选数据
|
|
628
|
+
*/
|
|
449
629
|
where(s) {
|
|
450
630
|
this._whereDataPosition[0] = this._data.length;
|
|
451
631
|
if (typeof s === 'string') {
|
|
632
|
+
// --- string ---
|
|
452
633
|
if (s !== '') {
|
|
453
634
|
this._sql.push(' WHERE ' + s);
|
|
454
635
|
this._whereDataPosition[1] = this._data.length;
|
|
455
636
|
}
|
|
456
637
|
}
|
|
457
638
|
else {
|
|
639
|
+
// --- array ---
|
|
458
640
|
let go = false;
|
|
459
641
|
if (Array.isArray(s)) {
|
|
460
642
|
if (s.length) {
|
|
@@ -483,13 +665,16 @@ class Sql {
|
|
|
483
665
|
for (const k in s) {
|
|
484
666
|
const v = s[k];
|
|
485
667
|
if (/^[0-9]+$/.test(k)) {
|
|
668
|
+
// --- 2, 3, 7 ---
|
|
486
669
|
if (v[2] === undefined) {
|
|
670
|
+
// --- 7 ---
|
|
487
671
|
sql += this.field(v[0]) + ' AND ';
|
|
488
672
|
if (v[1] !== undefined) {
|
|
489
673
|
data.push(...v[1]);
|
|
490
674
|
}
|
|
491
675
|
}
|
|
492
676
|
else if (v[2] === null) {
|
|
677
|
+
// --- 3: null ---
|
|
493
678
|
let opera = v[1];
|
|
494
679
|
if (opera === '!=' || opera === '!==' || opera === '<>') {
|
|
495
680
|
opera = 'IS NOT';
|
|
@@ -503,6 +688,7 @@ class Sql {
|
|
|
503
688
|
sql += this.field(v[0]) + ' ' + opera + ' NULL AND ';
|
|
504
689
|
}
|
|
505
690
|
else if (Array.isArray(v[2])) {
|
|
691
|
+
// --- 3 ---
|
|
506
692
|
sql += this.field(v[0]) + ' ' + v[1].toUpperCase() + ' (';
|
|
507
693
|
for (const v1 of v[2]) {
|
|
508
694
|
sql += '?, ';
|
|
@@ -511,9 +697,11 @@ class Sql {
|
|
|
511
697
|
sql = sql.slice(0, -2) + ') AND ';
|
|
512
698
|
}
|
|
513
699
|
else {
|
|
700
|
+
// --- 2, 6 ---
|
|
514
701
|
const nv = v[2];
|
|
515
702
|
const isf = this._isField(nv);
|
|
516
703
|
if (isf) {
|
|
704
|
+
// --- 6. field ---
|
|
517
705
|
sql += this.field(v[0]) + ' ' + v[1] + ' ' + this.field(nv.value) + ' AND ';
|
|
518
706
|
}
|
|
519
707
|
else {
|
|
@@ -523,10 +711,13 @@ class Sql {
|
|
|
523
711
|
}
|
|
524
712
|
}
|
|
525
713
|
else {
|
|
714
|
+
// --- 1, 4, 5, 6 ---
|
|
526
715
|
if (k.startsWith('$')) {
|
|
716
|
+
// --- 5 - '$or': [{'city': 'bj'}, {'city': 'sh'}] ---
|
|
527
717
|
const sp = ' ' + k.slice(1).split('-')[0].toUpperCase() + ' ';
|
|
528
718
|
sql += '(';
|
|
529
719
|
for (let v1 of v) {
|
|
720
|
+
// --- v1 是 {'city': 'bj'} ---
|
|
530
721
|
v1 = aoMix(v1);
|
|
531
722
|
if (Object.keys(v1).length > 1) {
|
|
532
723
|
sql += '(' + this._whereSub(v1, data) + ')' + sp;
|
|
@@ -538,17 +729,21 @@ class Sql {
|
|
|
538
729
|
sql = sql.slice(0, -sp.length) + ') AND ';
|
|
539
730
|
}
|
|
540
731
|
else {
|
|
732
|
+
// --- 1, 4, 6 ---
|
|
541
733
|
if (v === null) {
|
|
542
734
|
sql += this.field(k) + ' IS NULL AND ';
|
|
543
735
|
}
|
|
544
736
|
else if (typeof v === 'string' || typeof v === 'number') {
|
|
737
|
+
// --- 1 ---
|
|
545
738
|
sql += this.field(k) + ' = ? AND ';
|
|
546
739
|
data.push(v);
|
|
547
740
|
}
|
|
548
741
|
else if (this._isField(v)) {
|
|
742
|
+
// --- 6 ---
|
|
549
743
|
sql += this.field(k) + ' = ' + this.field(v.value) + ' AND ';
|
|
550
744
|
}
|
|
551
745
|
else {
|
|
746
|
+
// --- 4 - 'type': ['1', '2'] ---
|
|
552
747
|
if (v.length > 0) {
|
|
553
748
|
sql += this.field(k) + ' IN (';
|
|
554
749
|
for (const v1 of v) {
|
|
@@ -569,6 +764,11 @@ class Sql {
|
|
|
569
764
|
}
|
|
570
765
|
return sql.slice(0, -5);
|
|
571
766
|
}
|
|
767
|
+
/**
|
|
768
|
+
* --- ORDER BY ---
|
|
769
|
+
* @param c 字段字符串或数组
|
|
770
|
+
* @param d 排序规则
|
|
771
|
+
*/
|
|
572
772
|
by(c, d = 'DESC') {
|
|
573
773
|
let sql = ' ORDER BY ';
|
|
574
774
|
if (typeof c === 'string') {
|
|
@@ -588,6 +788,10 @@ class Sql {
|
|
|
588
788
|
this._sql.push(sql);
|
|
589
789
|
return this;
|
|
590
790
|
}
|
|
791
|
+
/**
|
|
792
|
+
* --- GROUP BY ---
|
|
793
|
+
* @param c 字段字符串或数组
|
|
794
|
+
*/
|
|
591
795
|
group(c) {
|
|
592
796
|
let sql = ' GROUP BY ';
|
|
593
797
|
if (typeof c === 'string') {
|
|
@@ -602,19 +806,32 @@ class Sql {
|
|
|
602
806
|
this._sql.push(sql);
|
|
603
807
|
return this;
|
|
604
808
|
}
|
|
809
|
+
/**
|
|
810
|
+
* --- LIMIT ---
|
|
811
|
+
* @param a 起始
|
|
812
|
+
* @param b 长度
|
|
813
|
+
*/
|
|
605
814
|
limit(a, b = 0) {
|
|
606
815
|
this._sql.push(' LIMIT ' + a.toString() + (b > 0 ? ', ' + b.toString() : ''));
|
|
607
816
|
return this;
|
|
608
817
|
}
|
|
818
|
+
/**
|
|
819
|
+
* --- 追加消极锁,通常不建议使用 ---
|
|
820
|
+
*/
|
|
609
821
|
lock() {
|
|
610
822
|
this._sql.push(' FOR UPDATE');
|
|
611
823
|
return this;
|
|
612
824
|
}
|
|
825
|
+
/**
|
|
826
|
+
* --- 创建一个本对象的一个新的 sql 对象拷贝 ---
|
|
827
|
+
* @param f 可为空,可设置新对象的 table 名变化
|
|
828
|
+
*/
|
|
613
829
|
copy(f, opt = {}) {
|
|
614
830
|
const sql = lCore.clone(this._sql);
|
|
615
831
|
const data = lCore.clone(this._data);
|
|
616
832
|
if (opt.where !== undefined) {
|
|
617
833
|
if (typeof opt.where === 'string') {
|
|
834
|
+
// --- string ---
|
|
618
835
|
for (let i = 0; i < sql.length; ++i) {
|
|
619
836
|
if (!sql[i].startsWith(' WHERE ')) {
|
|
620
837
|
continue;
|
|
@@ -625,6 +842,7 @@ class Sql {
|
|
|
625
842
|
}
|
|
626
843
|
}
|
|
627
844
|
else {
|
|
845
|
+
// --- array ---
|
|
628
846
|
let go = false;
|
|
629
847
|
if (Array.isArray(opt.where)) {
|
|
630
848
|
if (opt.where.length) {
|
|
@@ -636,16 +854,19 @@ class Sql {
|
|
|
636
854
|
go = true;
|
|
637
855
|
}
|
|
638
856
|
}
|
|
857
|
+
// --- 找到原来的 where ---
|
|
639
858
|
for (let i = 0; i < sql.length; ++i) {
|
|
640
859
|
if (!sql[i].startsWith(' WHERE ')) {
|
|
641
860
|
continue;
|
|
642
861
|
}
|
|
643
862
|
if (go) {
|
|
863
|
+
// --- 修改 where ---
|
|
644
864
|
const d = [];
|
|
645
865
|
sql[i] = ' WHERE ' + this._whereSub(opt.where, d);
|
|
646
866
|
data.splice(this._whereDataPosition[0], this._whereDataPosition[1] - this._whereDataPosition[0], ...d);
|
|
647
867
|
}
|
|
648
868
|
else {
|
|
869
|
+
// --- 清除 where ---
|
|
649
870
|
sql.splice(i, 1);
|
|
650
871
|
data.splice(this._whereDataPosition[0], this._whereDataPosition[1] - this._whereDataPosition[0]);
|
|
651
872
|
}
|
|
@@ -653,12 +874,14 @@ class Sql {
|
|
|
653
874
|
}
|
|
654
875
|
}
|
|
655
876
|
}
|
|
877
|
+
// --- 替换表名 ---
|
|
656
878
|
if (f && sql[0]) {
|
|
657
879
|
let table = '';
|
|
658
880
|
if (typeof f === 'string') {
|
|
659
881
|
table = this.field(f, this._pre);
|
|
660
882
|
}
|
|
661
883
|
else {
|
|
884
|
+
// --- f: ['user', 'order'] ---
|
|
662
885
|
for (const i of f) {
|
|
663
886
|
table += this.field(i, this._pre) + ', ';
|
|
664
887
|
}
|
|
@@ -671,22 +894,48 @@ class Sql {
|
|
|
671
894
|
'sql': sql
|
|
672
895
|
});
|
|
673
896
|
}
|
|
897
|
+
// --- 操作 ---
|
|
898
|
+
/**
|
|
899
|
+
* --- 获取 sql 语句 ---
|
|
900
|
+
*/
|
|
674
901
|
getSql() {
|
|
675
902
|
return this._sql.join('');
|
|
676
903
|
}
|
|
904
|
+
/**
|
|
905
|
+
* --- 获取全部 data ---
|
|
906
|
+
*/
|
|
677
907
|
getData() {
|
|
678
908
|
return this._data;
|
|
679
909
|
}
|
|
910
|
+
/**
|
|
911
|
+
* --- 获取定义的 pre ---
|
|
912
|
+
*/
|
|
680
913
|
getPre() {
|
|
681
914
|
return this._pre;
|
|
682
915
|
}
|
|
916
|
+
/**
|
|
917
|
+
* --- 获取带 data 的 sql 语句 ---
|
|
918
|
+
* @param sql
|
|
919
|
+
* @param data
|
|
920
|
+
*/
|
|
683
921
|
format(sql, data) {
|
|
684
922
|
return mysql2.format(sql ?? this.getSql(), data ?? this.getData());
|
|
685
923
|
}
|
|
924
|
+
// --- 特殊方法 ---
|
|
925
|
+
/**
|
|
926
|
+
* --- 在 sql 最后追加字符串 ---
|
|
927
|
+
* @param sql
|
|
928
|
+
*/
|
|
686
929
|
append(sql) {
|
|
687
930
|
this._sql.push(sql);
|
|
688
931
|
return this;
|
|
689
932
|
}
|
|
933
|
+
/**
|
|
934
|
+
* --- 对字段进行包裹 ---
|
|
935
|
+
* @param str
|
|
936
|
+
* @param pre 表前缀,仅请在 field 表名时倒入前缀
|
|
937
|
+
* @param suf 表后缀,仅请在 field 表名时倒入后缀,前面加 # 代表要强制 AS
|
|
938
|
+
*/
|
|
690
939
|
field(str, pre = '', suf = '') {
|
|
691
940
|
let left = '';
|
|
692
941
|
let right = '';
|
|
@@ -697,26 +946,33 @@ class Sql {
|
|
|
697
946
|
if (typeof str === 'number') {
|
|
698
947
|
str = str.toString();
|
|
699
948
|
}
|
|
700
|
-
str = str.trim();
|
|
701
|
-
str = str.replace(/ {2,}/g, ' ');
|
|
949
|
+
str = str.trim(); // --- 去除前导尾随 ---
|
|
950
|
+
str = str.replace(/ {2,}/g, ' '); // --- 去除多余的空格 ---
|
|
702
951
|
str = str.replace(/ +([),])/g, ' $1');
|
|
703
952
|
str = str.replace(/([(,]) +/g, '$1 ');
|
|
704
953
|
str = str.replace(/(\W)(JOIN|WHERE|UNION)(\W)/ig, '$1$3');
|
|
954
|
+
// --- 先判断 suf 强制性 AS ---
|
|
705
955
|
let sufAs = false;
|
|
706
956
|
if (suf.startsWith('#')) {
|
|
957
|
+
// --- 强制 AS ---
|
|
707
958
|
suf = suf.slice(1);
|
|
708
959
|
sufAs = true;
|
|
709
960
|
}
|
|
961
|
+
// --- 先判断有没有别名(也就是 as) ---
|
|
710
962
|
const loStr = str.toLowerCase();
|
|
711
963
|
const asPos = loStr.indexOf(' as ');
|
|
712
964
|
if (asPos === -1) {
|
|
965
|
+
// --- 没有 as ---
|
|
713
966
|
let spacePos = str.lastIndexOf(' ');
|
|
967
|
+
// --- 有可能有 aa + bb + cc + 10 这种情况 ---
|
|
714
968
|
if (!/^[a-zA-Z_)]$/.test(str[spacePos - 1])) {
|
|
969
|
+
// --- 连接符 ---
|
|
715
970
|
spacePos = -1;
|
|
716
971
|
}
|
|
717
972
|
if (spacePos !== -1) {
|
|
718
973
|
const spaceRight = str.slice(spacePos + 1);
|
|
719
974
|
if (/^[a-zA-Z_`][\w`]*$/.test(spaceRight)) {
|
|
975
|
+
// --- OK ---
|
|
720
976
|
left = str.slice(0, spacePos);
|
|
721
977
|
right = spaceRight;
|
|
722
978
|
}
|
|
@@ -731,10 +987,12 @@ class Sql {
|
|
|
731
987
|
}
|
|
732
988
|
}
|
|
733
989
|
else {
|
|
990
|
+
// --- 有 as ---
|
|
734
991
|
left = str.slice(0, asPos);
|
|
735
992
|
right = str.slice(asPos + 4);
|
|
736
993
|
}
|
|
737
994
|
if (right) {
|
|
995
|
+
// --- 处理右侧 ---
|
|
738
996
|
if (right.startsWith('`')) {
|
|
739
997
|
right = '`' + pre + right.slice(1);
|
|
740
998
|
}
|
|
@@ -744,10 +1002,13 @@ class Sql {
|
|
|
744
1002
|
right = ' AS ' + right;
|
|
745
1003
|
}
|
|
746
1004
|
else {
|
|
1005
|
+
// --- 没有右侧 ---
|
|
747
1006
|
if (sufAs) {
|
|
1007
|
+
// --- 强制 AS ---
|
|
748
1008
|
right = ' AS ' + this.field(left, pre);
|
|
749
1009
|
}
|
|
750
1010
|
}
|
|
1011
|
+
// --- 处理 left ---
|
|
751
1012
|
if (/^[\w`_.*]+$/.test(left)) {
|
|
752
1013
|
const l = left.split('.');
|
|
753
1014
|
if (l[0] === '*') {
|
|
@@ -757,20 +1018,29 @@ class Sql {
|
|
|
757
1018
|
l[0] = l[0].replace(/`/g, '');
|
|
758
1019
|
}
|
|
759
1020
|
if (l[1] === undefined) {
|
|
1021
|
+
// --- xxx ---
|
|
760
1022
|
if (/^[A-Z0-9_]+$/.test(l[0])) {
|
|
1023
|
+
// --- 纯大写是内置函数,不能加 ` ---
|
|
761
1024
|
return l[0] + right;
|
|
762
1025
|
}
|
|
763
1026
|
return '`' + pre + l[0] + suf + '`' + right;
|
|
764
1027
|
}
|
|
1028
|
+
// --- x.xxx ---
|
|
1029
|
+
// --- 只有在此模式才知道 . 前面的一定是表名,因此自动加 sql 级的 _pre ---
|
|
765
1030
|
const w = l[1] === '*' ? '*' : (l[1].startsWith('`') ? l[1] : ('`' + l[1] + '`'));
|
|
766
1031
|
return '`' + this._pre + l[0] + suf + '`.' + w + right;
|
|
767
1032
|
}
|
|
768
1033
|
else {
|
|
1034
|
+
// return left.replace(/([(, ])([a-zA-Z`_][\w`_.]*)(?=[), ])/g, (
|
|
769
1035
|
return left.replace(/(^|[(, ])([a-zA-Z`_][\w`_.]*)(?=[), ]|$)/g, (t, t1, t2) => {
|
|
770
1036
|
return t1 + this.field(t2, pre, suf);
|
|
771
1037
|
}) + right;
|
|
772
1038
|
}
|
|
773
1039
|
}
|
|
1040
|
+
/**
|
|
1041
|
+
* --- 判断传入值是否是 field,还是别的对象 ---
|
|
1042
|
+
* @param str
|
|
1043
|
+
*/
|
|
774
1044
|
_isField(arg) {
|
|
775
1045
|
if (arg.type !== 'column' || arg.token !== columnToken || arg.value === undefined) {
|
|
776
1046
|
return false;
|
|
@@ -779,12 +1049,26 @@ class Sql {
|
|
|
779
1049
|
}
|
|
780
1050
|
}
|
|
781
1051
|
exports.Sql = Sql;
|
|
1052
|
+
/**
|
|
1053
|
+
* --- 创建 sql 对象 ---
|
|
1054
|
+
* @param ctrPre ctr 对象或 pre 表前缀
|
|
1055
|
+
* @param opt 参数
|
|
1056
|
+
*/
|
|
782
1057
|
function get(ctrPre, opt = {}) {
|
|
783
1058
|
return new Sql(ctrPre instanceof ctr.Ctr ? ctrPre.getPrototype('_config').sql.pre : ctrPre, opt);
|
|
784
1059
|
}
|
|
1060
|
+
/**
|
|
1061
|
+
* --- 返回代入后的完整 SQL 字符串 ---
|
|
1062
|
+
* @param sql SQL 字符串
|
|
1063
|
+
* @param data DATA 数据
|
|
1064
|
+
*/
|
|
785
1065
|
function format(sql, data) {
|
|
786
1066
|
return mysql2.format(sql, data);
|
|
787
1067
|
}
|
|
1068
|
+
/**
|
|
1069
|
+
* --- 将数组兑换为组合的对象(Array/Object mix) ---
|
|
1070
|
+
* @param arr 要转换的数组
|
|
1071
|
+
*/
|
|
788
1072
|
function aoMix(arr) {
|
|
789
1073
|
if (!Array.isArray(arr)) {
|
|
790
1074
|
return arr;
|
|
@@ -804,6 +1088,7 @@ function aoMix(arr) {
|
|
|
804
1088
|
}
|
|
805
1089
|
return mix;
|
|
806
1090
|
}
|
|
1091
|
+
/** --- 创建字段对象 --- */
|
|
807
1092
|
function column(field) {
|
|
808
1093
|
if (!columnToken) {
|
|
809
1094
|
columnToken = lCore.random(8, lCore.RANDOM_LUNS);
|