@maiyunnet/kebab 4.0.2 → 5.0.0
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 +7 -2
- package/index.js +1 -1
- package/lib/cron.d.ts +4 -19
- package/lib/cron.js +16 -59
- package/lib/db/conn.d.ts +91 -0
- package/lib/db/conn.js +328 -0
- package/lib/db/pool.d.ts +61 -0
- package/lib/db/pool.js +281 -0
- package/lib/db/tran.d.ts +33 -0
- package/lib/db/tran.js +122 -0
- package/lib/db.d.ts +35 -169
- package/lib/db.js +21 -582
- package/lib/scan.js +2 -2
- package/lib/sql.d.ts +24 -25
- package/lib/sql.js +227 -132
- package/lib/time.d.ts +1 -1
- package/lib/time.js +1 -1
- package/lib/turnstile.js +1 -1
- package/lib/vector.d.ts +9 -4
- package/lib/vector.js +46 -27
- package/package.json +8 -6
- package/sys/cmd.js +29 -6
- package/sys/mod.d.ts +8 -26
- package/sys/mod.js +108 -259
- package/www/example/ctr/test.js +123 -122
- package/www/example/mod/test.js +22 -0
package/sys/mod.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Last: 2020-4-14 13:33:51, 2022-07-23 16:01:34, 2022-09-06 22:59:26, 2023-5-24 19:11:37, 2023-6-13 21:47:58, 2023-7-10 18:54:03, 2023-8-23 17:03:16, 2023-12-11 15:21:22, 2023-12-20 23:12:03, 2024-3-8 16:05:29, 2024-3-20 19:58:15, 2024-8-11 21:14:54, 2024-10-5 14:00:22, 2024-12-14 19:58:34, 2025-9-23 11:01:36, 2025-11-5 16:34:31
|
|
5
5
|
*/
|
|
6
6
|
import * as lSql from '#kebab/lib/sql.js';
|
|
7
|
-
import * as
|
|
7
|
+
import * as lDb from '#kebab/lib/db.js';
|
|
8
8
|
import * as lCore from '#kebab/lib/core.js';
|
|
9
9
|
import * as lText from '#kebab/lib/text.js';
|
|
10
10
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
@@ -54,8 +54,6 @@ export default class Mod {
|
|
|
54
54
|
static { this._$key = ''; }
|
|
55
55
|
/** --- 若使用 _$key 并且有多个 unique 索引,这里指定 _$key 的索引名 --- */
|
|
56
56
|
static { this._$index = ''; }
|
|
57
|
-
/** ---- 可开启软删软更新软新增 --- */
|
|
58
|
-
static { this._$soft = false; }
|
|
59
57
|
/**
|
|
60
58
|
* --- 构造函数 ---
|
|
61
59
|
* @param ctr Ctr 对象
|
|
@@ -81,7 +79,9 @@ export default class Mod {
|
|
|
81
79
|
/** --- 导入数据库连接 --- */
|
|
82
80
|
this._db = opt.db;
|
|
83
81
|
/** --- 新建 sql 对象 --- */
|
|
84
|
-
this._sql = lSql.get(opt.pre ?? opt.ctr
|
|
82
|
+
this._sql = lSql.get(opt.pre ?? opt.ctr, {
|
|
83
|
+
'service': this._db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
84
|
+
});
|
|
85
85
|
if (opt.index) {
|
|
86
86
|
this._index = typeof opt.index === 'string' ? [opt.index] : [...new Set(opt.index)];
|
|
87
87
|
}
|
|
@@ -102,19 +102,6 @@ export default class Mod {
|
|
|
102
102
|
(this._index !== null ? ('_' + this._index[0]) : '') +
|
|
103
103
|
(opt.alias ? ' ' + opt.alias : ''));
|
|
104
104
|
if (opt.where !== undefined) {
|
|
105
|
-
if (this.constructor._soft && !opt.raw) {
|
|
106
|
-
if (typeof opt.where === 'string') {
|
|
107
|
-
opt.where = opt.where ? ('(' + opt.where + ') AND ') : '`time_remove` = 0';
|
|
108
|
-
}
|
|
109
|
-
else if (Array.isArray(opt.where)) {
|
|
110
|
-
opt.where.push({
|
|
111
|
-
'time_remove': 0
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
opt.where['time_remove'] = 0;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
105
|
this._sql.where(opt.where);
|
|
119
106
|
}
|
|
120
107
|
}
|
|
@@ -131,7 +118,9 @@ export default class Mod {
|
|
|
131
118
|
* @param opt 选项
|
|
132
119
|
*/
|
|
133
120
|
static async insert(db, cs, vs, opt = {}) {
|
|
134
|
-
const sq = lSql.get(opt.pre
|
|
121
|
+
const sq = lSql.get(opt.pre, {
|
|
122
|
+
'service': db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
123
|
+
});
|
|
135
124
|
if (!vs) {
|
|
136
125
|
// --- 单行 ---
|
|
137
126
|
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : ''));
|
|
@@ -141,7 +130,7 @@ export default class Mod {
|
|
|
141
130
|
lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[insert, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1), '-error');
|
|
142
131
|
return false;
|
|
143
132
|
}
|
|
144
|
-
return r.packet.
|
|
133
|
+
return r.packet.affected ? true : null;
|
|
145
134
|
}
|
|
146
135
|
// --- 可能是多行 ---
|
|
147
136
|
if (vs.some(item => !Array.isArray(item))) {
|
|
@@ -161,7 +150,7 @@ export default class Mod {
|
|
|
161
150
|
lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[insert, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1), '-error');
|
|
162
151
|
return false;
|
|
163
152
|
}
|
|
164
|
-
if (r.packet.
|
|
153
|
+
if (r.packet.affected) {
|
|
165
154
|
continue;
|
|
166
155
|
}
|
|
167
156
|
return null;
|
|
@@ -170,37 +159,18 @@ export default class Mod {
|
|
|
170
159
|
}
|
|
171
160
|
/**
|
|
172
161
|
* --- 获取添加一个序列的模拟 SQL ---
|
|
162
|
+
* @param db 数据库对象
|
|
173
163
|
* @param cs 字段列表
|
|
174
164
|
* @param vs 数据列表
|
|
175
165
|
* @param opt 选项
|
|
176
166
|
*/
|
|
177
|
-
static insertSql(cs, vs, opt = {}) {
|
|
178
|
-
const sq = lSql.get(opt.pre
|
|
167
|
+
static insertSql(db, cs, vs, opt = {}) {
|
|
168
|
+
const sq = lSql.get(opt.pre, {
|
|
169
|
+
'service': db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
170
|
+
});
|
|
179
171
|
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(cs, vs);
|
|
180
172
|
return sq.format();
|
|
181
173
|
}
|
|
182
|
-
/**
|
|
183
|
-
* --- 插入数据如果唯一键冲突则更新 ---
|
|
184
|
-
* @param db 数据库对象
|
|
185
|
-
* @param data 要插入的数据
|
|
186
|
-
* @param update 要更新的数据
|
|
187
|
-
* @param opt 选项
|
|
188
|
-
*/
|
|
189
|
-
static async insertDuplicate(db, data, update, opt = {}) {
|
|
190
|
-
const sq = lSql.get(opt.pre);
|
|
191
|
-
sq.insert(this._$table + (opt.index ? ('_' + opt.index) : '')).values(data).duplicate(update);
|
|
192
|
-
const r = await db.execute(sq.getSql(), sq.getData());
|
|
193
|
-
if (r.packet === null) {
|
|
194
|
-
lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[insertDuplicate, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
if (r.packet.affectedRows > 0) {
|
|
198
|
-
return true;
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
174
|
/**
|
|
205
175
|
* --- 根据条件移除条目 ---
|
|
206
176
|
* @param db 数据库对象
|
|
@@ -208,36 +178,13 @@ export default class Mod {
|
|
|
208
178
|
* @param opt 选项
|
|
209
179
|
*/
|
|
210
180
|
static async removeByWhere(db, where, opt = {}) {
|
|
211
|
-
const tim = lTime.stamp();
|
|
212
181
|
const indexs = opt.index ? (typeof opt.index === 'string' ? [opt.index] : [...new Set(opt.index)]) : [''];
|
|
213
|
-
if (this._$soft && !opt.raw) {
|
|
214
|
-
// --- 软删除 ---
|
|
215
|
-
if (typeof where === 'string') {
|
|
216
|
-
where = '(' + where + ') AND `time_remove` = 0';
|
|
217
|
-
}
|
|
218
|
-
else if (Array.isArray(where)) {
|
|
219
|
-
where.push({
|
|
220
|
-
'time_remove': 0
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
where['time_remove'] = 0;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
182
|
let ar = 0;
|
|
228
183
|
for (const index of indexs) {
|
|
229
|
-
const sq = lSql.get(opt.pre
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
'time_remove': tim,
|
|
234
|
-
}]);
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
// --- 真删除 ---
|
|
238
|
-
sq.delete(this._$table + (index ? ('_' + index) : ''));
|
|
239
|
-
}
|
|
240
|
-
sq.where(where);
|
|
184
|
+
const sq = lSql.get(opt.pre, {
|
|
185
|
+
'service': db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
186
|
+
});
|
|
187
|
+
sq.delete(this._$table + (index ? ('_' + index) : '')).where(where);
|
|
241
188
|
if (opt.by) {
|
|
242
189
|
sq.by(opt.by[0], opt.by[1]);
|
|
243
190
|
}
|
|
@@ -246,11 +193,11 @@ export default class Mod {
|
|
|
246
193
|
}
|
|
247
194
|
const r = await db.execute(sq.getSql(), sq.getData());
|
|
248
195
|
if (r.packet === null) {
|
|
249
|
-
lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[removeByWhere
|
|
196
|
+
lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[MOD][removeByWhere] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
250
197
|
return false;
|
|
251
198
|
}
|
|
252
|
-
if (r.packet.
|
|
253
|
-
ar += r.packet.
|
|
199
|
+
if (r.packet.affected) {
|
|
200
|
+
ar += r.packet.affected;
|
|
254
201
|
}
|
|
255
202
|
}
|
|
256
203
|
return ar ? ar : null;
|
|
@@ -262,30 +209,10 @@ export default class Mod {
|
|
|
262
209
|
* @param opt 选项
|
|
263
210
|
*/
|
|
264
211
|
static removeByWhereSql(db, where, opt = {}) {
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), [{
|
|
270
|
-
'time_remove': tim
|
|
271
|
-
}]);
|
|
272
|
-
if (typeof where === 'string') {
|
|
273
|
-
where = '(' + where + ') AND `time_remove` = 0';
|
|
274
|
-
}
|
|
275
|
-
else if (Array.isArray(where)) {
|
|
276
|
-
where.push({
|
|
277
|
-
'time_remove': 0
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
where['time_remove'] = 0;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
else {
|
|
285
|
-
// --- 真删除 ---
|
|
286
|
-
sq.delete(this._$table + (opt.index ? ('_' + opt.index) : ''));
|
|
287
|
-
}
|
|
288
|
-
sq.where(where);
|
|
212
|
+
const sq = lSql.get(opt.pre, {
|
|
213
|
+
'service': db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
214
|
+
});
|
|
215
|
+
sq.delete(this._$table + (opt.index ? ('_' + opt.index) : '')).where(where);
|
|
289
216
|
if (opt.by) {
|
|
290
217
|
sq.by(opt.by[0], opt.by[1]);
|
|
291
218
|
}
|
|
@@ -303,24 +230,12 @@ export default class Mod {
|
|
|
303
230
|
*/
|
|
304
231
|
static async updateByWhere(db, data, where, opt = {}) {
|
|
305
232
|
const indexs = opt.index ? (typeof opt.index === 'string' ? [opt.index] : [...new Set(opt.index)]) : [''];
|
|
306
|
-
if (this._$soft && !opt.raw) {
|
|
307
|
-
if (typeof where === 'string') {
|
|
308
|
-
where = '(' + where + ') AND `time_remove` = 0';
|
|
309
|
-
}
|
|
310
|
-
else if (Array.isArray(where)) {
|
|
311
|
-
where.push({
|
|
312
|
-
'time_remove': 0
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
where['time_remove'] = 0;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
233
|
let ar = 0;
|
|
320
234
|
for (const index of indexs) {
|
|
321
|
-
const sq = lSql.get(opt.pre
|
|
322
|
-
|
|
323
|
-
|
|
235
|
+
const sq = lSql.get(opt.pre, {
|
|
236
|
+
'service': db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
237
|
+
});
|
|
238
|
+
sq.update(this._$table + (index ? ('_' + index) : ''), data).where(where);
|
|
324
239
|
if (opt.by) {
|
|
325
240
|
sq.by(opt.by[0], opt.by[1]);
|
|
326
241
|
}
|
|
@@ -329,38 +244,27 @@ export default class Mod {
|
|
|
329
244
|
}
|
|
330
245
|
const r = await db.execute(sq.getSql(), sq.getData());
|
|
331
246
|
if (r.packet === null) {
|
|
332
|
-
lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[updateByWhere
|
|
247
|
+
lCore.log(opt.pre instanceof sCtr.Ctr ? opt.pre : {}, '[MOD][updateByWhere] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
333
248
|
return false;
|
|
334
249
|
}
|
|
335
|
-
if (r.packet.
|
|
336
|
-
ar += r.packet.
|
|
250
|
+
if (r.packet.affected) {
|
|
251
|
+
ar += r.packet.affected;
|
|
337
252
|
}
|
|
338
253
|
}
|
|
339
254
|
return ar ? ar : null;
|
|
340
255
|
}
|
|
341
256
|
/**
|
|
342
257
|
* --- 根据条件更新数据(仅获取 SQL 对象) ---
|
|
258
|
+
* @param db 数据库对象
|
|
343
259
|
* @param data 要更新的数据
|
|
344
260
|
* @param where 筛选条件
|
|
345
261
|
* @param opt 选项
|
|
346
262
|
*/
|
|
347
|
-
static updateByWhereSql(data, where, opt = {}) {
|
|
348
|
-
const sq = lSql.get(opt.pre
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
where = '(' + where + ') AND `time_remove` = 0';
|
|
353
|
-
}
|
|
354
|
-
else if (Array.isArray(where)) {
|
|
355
|
-
where.push({
|
|
356
|
-
'time_remove': 0
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
else {
|
|
360
|
-
where['time_remove'] = 0;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
sq.where(where);
|
|
263
|
+
static updateByWhereSql(db, data, where, opt = {}) {
|
|
264
|
+
const sq = lSql.get(opt.pre, {
|
|
265
|
+
'service': db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
266
|
+
});
|
|
267
|
+
sq.update(this._$table + (opt.index ? ('_' + opt.index) : ''), data).where(where);
|
|
364
268
|
if (opt.by) {
|
|
365
269
|
sq.by(opt.by[0], opt.by[1]);
|
|
366
270
|
}
|
|
@@ -504,23 +408,9 @@ export default class Mod {
|
|
|
504
408
|
* @param opt 选项
|
|
505
409
|
*/
|
|
506
410
|
static async primarys(db, where = '', opt = {}) {
|
|
507
|
-
const sq = lSql.get(opt.pre ?? opt.ctr
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (typeof where === 'string') {
|
|
511
|
-
if (where !== '') {
|
|
512
|
-
where = '(' + where + ') AND `time_remove` = 0';
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
else if (Array.isArray(where)) {
|
|
516
|
-
where.push({
|
|
517
|
-
'time_remove': 0
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
else {
|
|
521
|
-
where['time_remove'] = 0;
|
|
522
|
-
}
|
|
523
|
-
}
|
|
411
|
+
const sq = lSql.get(opt.pre ?? opt.ctr, {
|
|
412
|
+
'service': db.getService() ?? lDb.ESERVICE.PGSQL,
|
|
413
|
+
});
|
|
524
414
|
sq.select(this._$primary, this._$table + (opt.index ? ('_' + opt.index) : '')).where(where);
|
|
525
415
|
const r = await db.query(sq.getSql(), sq.getData());
|
|
526
416
|
if (r.rows === null) {
|
|
@@ -585,16 +475,13 @@ export default class Mod {
|
|
|
585
475
|
}
|
|
586
476
|
/**
|
|
587
477
|
* --- 创建数据 ---
|
|
588
|
-
* @param notWhere 若要不存在才成功,则要传入限定条件
|
|
589
|
-
* @param table 可对限定条件传入适当的表
|
|
590
478
|
*/
|
|
591
|
-
async create(
|
|
479
|
+
async create() {
|
|
592
480
|
const cstr = this.constructor;
|
|
593
481
|
const updates = {};
|
|
594
482
|
for (const k in this._updates) {
|
|
595
483
|
updates[k] = this._data[k];
|
|
596
484
|
}
|
|
597
|
-
table ??= cstr._$table + (this._index ? ('_' + this._index[0]) : '');
|
|
598
485
|
let r = null;
|
|
599
486
|
if ((cstr._$key !== '') && (updates[cstr._$key] === undefined)) {
|
|
600
487
|
let count = 0;
|
|
@@ -606,12 +493,7 @@ export default class Mod {
|
|
|
606
493
|
this._data[cstr._$key] = updates[cstr._$key];
|
|
607
494
|
this[cstr._$key] = updates[cstr._$key];
|
|
608
495
|
this._sql.insert(cstr._$table + (this._index ? ('_' + this._index[0]) : ''));
|
|
609
|
-
|
|
610
|
-
this._sql.notExists(table, updates, notWhere);
|
|
611
|
-
}
|
|
612
|
-
else {
|
|
613
|
-
this._sql.values(updates);
|
|
614
|
-
}
|
|
496
|
+
this._sql.values(updates);
|
|
615
497
|
r = await this._db.execute(this._sql.getSql(), this._sql.getData());
|
|
616
498
|
++count;
|
|
617
499
|
if (!r.error) {
|
|
@@ -623,63 +505,45 @@ export default class Mod {
|
|
|
623
505
|
// --- 没设置 index,那就当做是本次生成的 key 重复了 ---
|
|
624
506
|
continue;
|
|
625
507
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
508
|
+
if (this._db.getService() === lDb.ESERVICE.MYSQL) {
|
|
509
|
+
// --- MYSQL ---
|
|
510
|
+
const match = /for key '([\w.]+)'/.exec(r.error.message);
|
|
511
|
+
if (match?.[1].includes(cstr._$index)) {
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
// --- PGSQL ---
|
|
517
|
+
const match = /constraint "([\w.]+)"/.exec(r.error.message);
|
|
518
|
+
if (match?.[1].includes(cstr._$index)) {
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
630
521
|
}
|
|
631
522
|
// --- 1062 非 index 冲突,那需要用户自行处理(可能不允许重复的邮箱) ---
|
|
632
523
|
return false;
|
|
633
524
|
}
|
|
634
525
|
// --- 未处理的错误 ---
|
|
635
|
-
|
|
526
|
+
const service = this._db.getService();
|
|
527
|
+
lCore.debug('[MOD][create0][' + cstr._$table + ']', service !== null ? lDb.ESERVICE[service] : 'NONE', r);
|
|
528
|
+
lCore.log(this._ctr ?? {}, '[MOD][create0][' + cstr._$table + '] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
636
529
|
return false;
|
|
637
530
|
}
|
|
638
531
|
}
|
|
639
532
|
else {
|
|
640
533
|
this._sql.insert(cstr._$table + (this._index ? ('_' + this._index[0]) : ''));
|
|
641
|
-
|
|
642
|
-
this._sql.notExists(table, updates, notWhere);
|
|
643
|
-
}
|
|
644
|
-
else {
|
|
645
|
-
this._sql.values(updates);
|
|
646
|
-
}
|
|
534
|
+
this._sql.values(updates);
|
|
647
535
|
r = await this._db.execute(this._sql.getSql(), this._sql.getData());
|
|
648
536
|
if (r.error) {
|
|
649
537
|
if (r.error.errno !== 1062) {
|
|
650
|
-
lCore.
|
|
538
|
+
lCore.debug('[MOD][create1][' + cstr._$table + ']', r);
|
|
539
|
+
lCore.log(this._ctr ?? {}, '[MOD][create1][' + cstr._$table + '] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
651
540
|
}
|
|
652
541
|
return false;
|
|
653
542
|
}
|
|
654
543
|
}
|
|
655
|
-
if (r
|
|
544
|
+
if (r.packet?.affected) {
|
|
656
545
|
this._updates = {};
|
|
657
|
-
this._data[cstr._$primary] = r.packet.
|
|
658
|
-
this[cstr._$primary] = this._data[cstr._$primary];
|
|
659
|
-
return true;
|
|
660
|
-
}
|
|
661
|
-
else {
|
|
662
|
-
return false;
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* --- 唯一键冲突则替换,不冲突则创建数据 ---
|
|
667
|
-
*/
|
|
668
|
-
async replace() {
|
|
669
|
-
const cstr = this.constructor;
|
|
670
|
-
const updates = {};
|
|
671
|
-
for (const k in this._updates) {
|
|
672
|
-
updates[k] = this._data[k];
|
|
673
|
-
}
|
|
674
|
-
this._sql.replace(cstr._$table + (this._index ? ('_' + this._index[0]) : '')).values(updates);
|
|
675
|
-
const r = await this._db.execute(this._sql.getSql(), this._sql.getData());
|
|
676
|
-
if (r.packet === null) {
|
|
677
|
-
lCore.log(this._ctr ?? {}, '[replace, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
678
|
-
return false;
|
|
679
|
-
}
|
|
680
|
-
if (r.packet.affectedRows > 0) {
|
|
681
|
-
this._updates = {};
|
|
682
|
-
this._data[cstr._$primary] = r.packet.insertId;
|
|
546
|
+
this._data[cstr._$primary] = r.packet.insert;
|
|
683
547
|
this[cstr._$primary] = this._data[cstr._$primary];
|
|
684
548
|
return true;
|
|
685
549
|
}
|
|
@@ -734,7 +598,7 @@ export default class Mod {
|
|
|
734
598
|
lCore.log(this._ctr ?? {}, '[save, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
735
599
|
return false;
|
|
736
600
|
}
|
|
737
|
-
if (r.packet.
|
|
601
|
+
if (r.packet.affected) {
|
|
738
602
|
this._updates = {};
|
|
739
603
|
return true;
|
|
740
604
|
}
|
|
@@ -744,30 +608,18 @@ export default class Mod {
|
|
|
744
608
|
}
|
|
745
609
|
/**
|
|
746
610
|
* --- 移除本条目 ---
|
|
747
|
-
* @param raw 是否真实移除
|
|
748
611
|
*/
|
|
749
|
-
async remove(
|
|
750
|
-
const tim = lTime.stamp();
|
|
612
|
+
async remove() {
|
|
751
613
|
const cstr = this.constructor;
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
}]).where([{
|
|
756
|
-
[cstr._$primary]: this._data[cstr._$primary],
|
|
757
|
-
'time_remove': 0
|
|
758
|
-
}]);
|
|
759
|
-
}
|
|
760
|
-
else {
|
|
761
|
-
this._sql.delete(cstr._$table + (this._index ? ('_' + this._index[0]) : '')).where([{
|
|
762
|
-
[cstr._$primary]: this._data[cstr._$primary]
|
|
763
|
-
}]);
|
|
764
|
-
}
|
|
614
|
+
this._sql.delete(cstr._$table + (this._index ? ('_' + this._index[0]) : '')).where([{
|
|
615
|
+
[cstr._$primary]: this._data[cstr._$primary]
|
|
616
|
+
}]);
|
|
765
617
|
const r = await this._db.execute(this._sql.getSql(), this._sql.getData());
|
|
766
618
|
if (r.packet === null) {
|
|
767
619
|
lCore.log(this._ctr ?? {}, '[remove, mod] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
768
620
|
return false;
|
|
769
621
|
}
|
|
770
|
-
if (r.packet.
|
|
622
|
+
if (r.packet.affected) {
|
|
771
623
|
return true;
|
|
772
624
|
}
|
|
773
625
|
else {
|
|
@@ -888,7 +740,7 @@ export default class Mod {
|
|
|
888
740
|
for (let i = 0; i < this._index.length; ++i) {
|
|
889
741
|
// --- 先计算 total ---
|
|
890
742
|
if (i > 0) {
|
|
891
|
-
sql = sql.replace(/(FROM [a-zA-Z0-9`_.]+?_)[0-9_]+/, '$1' + this._index[i]);
|
|
743
|
+
sql = sql.replace(/(FROM [a-zA-Z0-9`"_.]+?_)[0-9_]+/, '$1' + this._index[i]);
|
|
892
744
|
}
|
|
893
745
|
const tsql = this._formatTotal(sql);
|
|
894
746
|
const tr = await this._db.query(tsql, this._sql.getData());
|
|
@@ -914,10 +766,10 @@ export default class Mod {
|
|
|
914
766
|
continue;
|
|
915
767
|
}
|
|
916
768
|
}
|
|
917
|
-
const lsql = sql.replace(/ LIMIT [0-9 ,]
|
|
769
|
+
const lsql = sql.replace(/ LIMIT [0-9 ,]+(OFFSET [0-9]+)?/g, ` LIMIT ${remain} OFFSET ${cz}`);
|
|
918
770
|
const r = await this._db.query(lsql, this._sql.getData());
|
|
919
771
|
if (r.rows === null) {
|
|
920
|
-
lCore.log(this._ctr ?? {}, '[all
|
|
772
|
+
lCore.log(this._ctr ?? {}, '[MOD][all] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
921
773
|
return false;
|
|
922
774
|
}
|
|
923
775
|
if (key) {
|
|
@@ -927,7 +779,7 @@ export default class Mod {
|
|
|
927
779
|
'ctr': this._ctr,
|
|
928
780
|
'pre': this._sql.getPre(),
|
|
929
781
|
'row': row,
|
|
930
|
-
'index': this._index
|
|
782
|
+
'index': this._index,
|
|
931
783
|
});
|
|
932
784
|
list[row[key]] = obj;
|
|
933
785
|
--remain;
|
|
@@ -940,7 +792,7 @@ export default class Mod {
|
|
|
940
792
|
'ctr': this._ctr,
|
|
941
793
|
'pre': this._sql.getPre(),
|
|
942
794
|
'row': row,
|
|
943
|
-
'index': this._index
|
|
795
|
+
'index': this._index,
|
|
944
796
|
});
|
|
945
797
|
list.push(obj);
|
|
946
798
|
--remain;
|
|
@@ -954,7 +806,7 @@ export default class Mod {
|
|
|
954
806
|
const contain = this._contain ? lCore.clone(this._contain.list) : null;
|
|
955
807
|
const r = await this._db.query(this._sql.getSql(), this._sql.getData());
|
|
956
808
|
if (r.rows === null) {
|
|
957
|
-
lCore.log(this._ctr ?? {}, '[all
|
|
809
|
+
lCore.log(this._ctr ?? {}, '[MOD][all] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
958
810
|
return false;
|
|
959
811
|
}
|
|
960
812
|
// --- 检查没被查到的必包含项 ---
|
|
@@ -983,7 +835,7 @@ export default class Mod {
|
|
|
983
835
|
'ctr': this._ctr,
|
|
984
836
|
'pre': this._sql.getPre(),
|
|
985
837
|
'row': row,
|
|
986
|
-
'index': this._index
|
|
838
|
+
'index': this._index,
|
|
987
839
|
});
|
|
988
840
|
list[row[key]] = obj;
|
|
989
841
|
}
|
|
@@ -995,7 +847,7 @@ export default class Mod {
|
|
|
995
847
|
'ctr': this._ctr,
|
|
996
848
|
'pre': this._sql.getPre(),
|
|
997
849
|
'row': crow,
|
|
998
|
-
'index': this._index
|
|
850
|
+
'index': this._index,
|
|
999
851
|
});
|
|
1000
852
|
list[crow[key]] = obj;
|
|
1001
853
|
}
|
|
@@ -1048,7 +900,7 @@ export default class Mod {
|
|
|
1048
900
|
for (let i = 0; i < this._index.length; ++i) {
|
|
1049
901
|
// --- 先计算 total ---
|
|
1050
902
|
if (i > 0) {
|
|
1051
|
-
sql = sql.replace(/(FROM [a-zA-Z0-9`_.]+?_)[0-9_]+/, '$1' + this._index[i]);
|
|
903
|
+
sql = sql.replace(/(FROM [a-zA-Z0-9`"_.]+?_)[0-9_]+/, '$1' + this._index[i]);
|
|
1052
904
|
}
|
|
1053
905
|
const tsql = this._formatTotal(sql);
|
|
1054
906
|
const tr = await this._db.query(tsql, this._sql.getData());
|
|
@@ -1076,10 +928,10 @@ export default class Mod {
|
|
|
1076
928
|
// --- 在本表开始找之后,后面表无需再跳过 ---
|
|
1077
929
|
offset = -1;
|
|
1078
930
|
}
|
|
1079
|
-
const lsql = sql.replace(/ LIMIT [0-9 ,]
|
|
931
|
+
const lsql = sql.replace(/ LIMIT [0-9 ,]+(OFFSET [0-9]+)?/g, ` LIMIT ${remain} OFFSET ${cz}`);
|
|
1080
932
|
const r = await this._db.query(lsql, this._sql.getData());
|
|
1081
933
|
if (r.rows === null) {
|
|
1082
|
-
lCore.log(this._ctr ?? {}, '[allArray
|
|
934
|
+
lCore.log(this._ctr ?? {}, '[MOD][allArray] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
1083
935
|
return false;
|
|
1084
936
|
}
|
|
1085
937
|
if (key) {
|
|
@@ -1101,7 +953,7 @@ export default class Mod {
|
|
|
1101
953
|
const contain = this._contain ? lCore.clone(this._contain.list) : null;
|
|
1102
954
|
const r = await this._db.query(this._sql.getSql(), this._sql.getData());
|
|
1103
955
|
if (r.rows === null) {
|
|
1104
|
-
lCore.log(this._ctr ?? {}, '[allArray
|
|
956
|
+
lCore.log(this._ctr ?? {}, '[MOD][allArray] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
1105
957
|
return false;
|
|
1106
958
|
}
|
|
1107
959
|
// --- 检查没被查到的必包含项 ---
|
|
@@ -1144,32 +996,40 @@ export default class Mod {
|
|
|
1144
996
|
return r.rows;
|
|
1145
997
|
}
|
|
1146
998
|
/**
|
|
1147
|
-
* --- 获取数查询(SELECT
|
|
999
|
+
* --- 获取数查询(SELECT)扫描情况,获取字符串或对象 ---
|
|
1148
1000
|
* @param all 是否获取完全的情况,默认不获取,只返回扫描情况
|
|
1149
1001
|
*/
|
|
1150
1002
|
async explain(all = false) {
|
|
1151
1003
|
const r = await this._db.query('EXPLAIN ' + this._sql.getSql(), this._sql.getData());
|
|
1152
1004
|
if (r.rows === null) {
|
|
1153
|
-
lCore.log(this._ctr ?? {}, '[explain
|
|
1005
|
+
lCore.log(this._ctr ?? {}, '[MOD][explain] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
1154
1006
|
return false;
|
|
1155
1007
|
}
|
|
1156
1008
|
if (!r.rows[0]) {
|
|
1157
1009
|
return false;
|
|
1158
1010
|
}
|
|
1159
1011
|
if (!all) {
|
|
1160
|
-
return
|
|
1161
|
-
|
|
1162
|
-
|
|
1012
|
+
return this._db.getService() === lDb.ESERVICE.MYSQL ?
|
|
1013
|
+
r.rows[0].type :
|
|
1014
|
+
r.rows[0]['QUERY PLAN'];
|
|
1015
|
+
}
|
|
1016
|
+
return this._db.getService() === lDb.ESERVICE.MYSQL ?
|
|
1017
|
+
r.rows[0] :
|
|
1018
|
+
{
|
|
1019
|
+
'scan': r.rows[0]['QUERY PLAN'],
|
|
1020
|
+
'filter': r.rows[1]['QUERY PLAN'],
|
|
1021
|
+
};
|
|
1163
1022
|
}
|
|
1164
1023
|
_formatTotal(sql, f = '*') {
|
|
1024
|
+
const q = this._db.getService() === lDb.ESERVICE.MYSQL ? '`' : '"';
|
|
1165
1025
|
sql = sql
|
|
1166
|
-
.replace(/ LIMIT [0-9 ,]
|
|
1167
|
-
.replace(/ ORDER BY [\w
|
|
1026
|
+
.replace(/ LIMIT [0-9 ,]+(OFFSET [0-9]+)?/g, '')
|
|
1027
|
+
.replace(/ ORDER BY [\w`",. ]+(DESC|ASC)?/g, '');
|
|
1168
1028
|
if (sql.includes(' GROUP BY ')) {
|
|
1169
1029
|
return 'SELECT COUNT(0) AS `count` FROM(' + sql + ') AS `f`';
|
|
1170
1030
|
}
|
|
1171
1031
|
return sql
|
|
1172
|
-
.replace(/SELECT .+? FROM/g,
|
|
1032
|
+
.replace(/SELECT .+? FROM/g, `SELECT COUNT(${this._sql.field(f)}) AS ${q}count${q} FROM`);
|
|
1173
1033
|
}
|
|
1174
1034
|
/**
|
|
1175
1035
|
* --- 获取总条数,自动抛弃 LIMIT,仅用于获取数据的情况(select) ---
|
|
@@ -1185,7 +1045,7 @@ export default class Mod {
|
|
|
1185
1045
|
const sql = this._formatTotal(this._sql.getSql(), f);
|
|
1186
1046
|
const r = await this._db.query(sql, this._sql.getData());
|
|
1187
1047
|
if (r.rows === null) {
|
|
1188
|
-
lCore.log(this._ctr ?? {}, '[total
|
|
1048
|
+
lCore.log(this._ctr ?? {}, '[MOD][total] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
1189
1049
|
return 0;
|
|
1190
1050
|
}
|
|
1191
1051
|
let count = 0;
|
|
@@ -1198,10 +1058,12 @@ export default class Mod {
|
|
|
1198
1058
|
* --- 根据当前条件,筛选出当前条目该有的数据条数 ---
|
|
1199
1059
|
*/
|
|
1200
1060
|
async count() {
|
|
1201
|
-
const sql = this._sql.getSql().replace(/SELECT .+? FROM/,
|
|
1061
|
+
const sql = this._sql.getSql().replace(/SELECT .+? FROM/, this._db.getService() === lDb.ESERVICE.MYSQL ?
|
|
1062
|
+
'SELECT COUNT(0) AS `count` FROM' :
|
|
1063
|
+
'SELECT COUNT(0) AS "count" FROM');
|
|
1202
1064
|
const r = await this._db.query(sql, this._sql.getData());
|
|
1203
1065
|
if (r.rows === null) {
|
|
1204
|
-
lCore.log(this._ctr ?? {}, '[count
|
|
1066
|
+
lCore.log(this._ctr ?? {}, '[MOD][count] ' + lText.stringifyJson(r.error?.message ?? '').slice(1, -1).replace(/"/g, '""'), '-error');
|
|
1205
1067
|
return 0;
|
|
1206
1068
|
}
|
|
1207
1069
|
let count = 0;
|
|
@@ -1214,7 +1076,8 @@ export default class Mod {
|
|
|
1214
1076
|
* --- 获取当前条件下的 count 的 SQL 语句 ---
|
|
1215
1077
|
*/
|
|
1216
1078
|
countSql() {
|
|
1217
|
-
const sql = this._sql.getSql().replace(/SELECT .+? FROM/,
|
|
1079
|
+
const sql = this._sql.getSql().replace(/SELECT .+? FROM/, this._db.getService() === lDb.ESERVICE.MYSQL ?
|
|
1080
|
+
'SELECT COUNT(0) AS `count` FROM' : 'SELECT COUNT(0) AS "count" FROM');
|
|
1218
1081
|
return this._sql.format(sql, this._sql.getData());
|
|
1219
1082
|
}
|
|
1220
1083
|
/**
|
|
@@ -1291,21 +1154,7 @@ export default class Mod {
|
|
|
1291
1154
|
* @param s 筛选条件数组或字符串
|
|
1292
1155
|
* @param raw 是否包含已被软删除的数据
|
|
1293
1156
|
*/
|
|
1294
|
-
filter(s
|
|
1295
|
-
const cstr = this.constructor;
|
|
1296
|
-
if (cstr._soft && !raw) {
|
|
1297
|
-
if (typeof s === 'string') {
|
|
1298
|
-
s = '(' + s + ') AND `time_remove` = 0';
|
|
1299
|
-
}
|
|
1300
|
-
else if (Array.isArray(s)) {
|
|
1301
|
-
s.push({
|
|
1302
|
-
'time_remove': 0
|
|
1303
|
-
});
|
|
1304
|
-
}
|
|
1305
|
-
else {
|
|
1306
|
-
s['time_remove'] = 0;
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1157
|
+
filter(s) {
|
|
1309
1158
|
this._sql.where(s);
|
|
1310
1159
|
return this;
|
|
1311
1160
|
}
|
|
@@ -1314,8 +1163,8 @@ export default class Mod {
|
|
|
1314
1163
|
* @param s 筛选条件数组或字符串
|
|
1315
1164
|
* @param raw 是否包含已被软删除的数据
|
|
1316
1165
|
*/
|
|
1317
|
-
where(s
|
|
1318
|
-
return this.filter(s
|
|
1166
|
+
where(s) {
|
|
1167
|
+
return this.filter(s);
|
|
1319
1168
|
}
|
|
1320
1169
|
/**
|
|
1321
1170
|
* --- ORDER BY ---
|