jj.js 0.19.0 → 0.20.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/README.md +243 -173
- package/jj.js +14 -14
- package/lib/app.js +52 -17
- package/lib/cache.js +96 -30
- package/lib/config.js +14 -4
- package/lib/context.js +18 -22
- package/lib/controller.js +36 -5
- package/lib/cookie.js +11 -15
- package/lib/ctx.js +28 -28
- package/lib/db/mongodb.js +564 -0
- package/lib/db/mysql.js +32 -28
- package/lib/db/sql.js +13 -3
- package/lib/db/sqlite.js +32 -24
- package/lib/db.js +230 -112
- package/lib/loader.js +79 -44
- package/lib/logger.js +124 -126
- package/lib/middleware.js +39 -6
- package/lib/model.js +23 -9
- package/lib/{run.js → mvc.js} +29 -22
- package/lib/pagination.js +68 -14
- package/lib/request.js +4 -4
- package/lib/response.js +70 -6
- package/lib/router.js +4 -3
- package/lib/types.js +363 -196
- package/lib/upload.js +15 -15
- package/lib/url.js +10 -2
- package/lib/utils/error.js +9 -5
- package/lib/utils/utils.js +2 -0
- package/lib/utils/validate.js +13 -0
- package/lib/view.js +54 -8
- package/logo.png +0 -0
- package/package.json +8 -4
- package/types.js +177 -83
- package/CHANGELOG.md +0 -58
- package/jsdoc.conf.js +0 -17
package/lib/db.js
CHANGED
|
@@ -4,13 +4,21 @@ const Context = require('./context');
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @typedef {import('../types').KoaCtx} KoaCtx
|
|
7
|
+
* @typedef {import('../types').DbConfigItem} DbConfigItem
|
|
7
8
|
* @typedef {import('../types').Pagination} Pagination
|
|
8
9
|
* @typedef {import('../types').PaginationInstance} PaginationInstance
|
|
9
10
|
* @typedef {import('../types').OkPacket} OkPacket
|
|
10
11
|
* @typedef {import('../types').RowData} RowData
|
|
11
12
|
* @typedef {import('../types').ListData} ListData
|
|
12
13
|
* @typedef {import('../types').FieldInfo} FieldInfo
|
|
14
|
+
* @typedef {import('../types').Link} Link
|
|
15
|
+
* @typedef {import('../types').Operator} Operator
|
|
16
|
+
* @typedef {import('../types').Where} Where
|
|
17
|
+
* @typedef {import('../types').Sql} Sql
|
|
13
18
|
* @typedef {import('../types').SqlInstance} SqlInstance
|
|
19
|
+
* @typedef {import('../types').Logger} Logger
|
|
20
|
+
* @typedef {import('../types')._DbOptions} _DbOptions
|
|
21
|
+
* @typedef {import('../types').Cache} Cache
|
|
14
22
|
*/
|
|
15
23
|
|
|
16
24
|
/**
|
|
@@ -21,24 +29,41 @@ class Db extends Context
|
|
|
21
29
|
/**
|
|
22
30
|
* Initialize a new `Db`
|
|
23
31
|
* @public
|
|
24
|
-
* @param {
|
|
25
|
-
* @param {
|
|
32
|
+
* @param {object|KoaCtx} [ctx]
|
|
33
|
+
* @param {string|DbConfigItem} [options] - 数据库配置标识或连接参数
|
|
26
34
|
*/
|
|
27
35
|
constructor(ctx, options) {
|
|
28
36
|
ctx = ctx || {};
|
|
29
37
|
super(ctx);
|
|
38
|
+
/**
|
|
39
|
+
* @type {DbConfigItem}
|
|
40
|
+
*/
|
|
41
|
+
// @ts-ignore
|
|
30
42
|
this._config = null;
|
|
31
43
|
this._table = '';
|
|
44
|
+
/**
|
|
45
|
+
* @type {_DbOptions}
|
|
46
|
+
*/
|
|
47
|
+
// @ts-ignore
|
|
32
48
|
this._options = {};
|
|
33
49
|
/**
|
|
34
50
|
* @type {string}
|
|
35
51
|
*/
|
|
36
52
|
this._queryStr = '';
|
|
37
|
-
this._tableField = {};
|
|
38
53
|
/**
|
|
39
|
-
* @type {
|
|
54
|
+
* @type {Map<string, string[]>}
|
|
55
|
+
*/
|
|
56
|
+
this._tableField = new Map();
|
|
57
|
+
/**
|
|
58
|
+
* @type {SqlInstance} sql实例
|
|
40
59
|
*/
|
|
60
|
+
// @ts-ignore
|
|
41
61
|
this._sql = null;
|
|
62
|
+
/**
|
|
63
|
+
* @type {String} sql语句
|
|
64
|
+
*/
|
|
65
|
+
this.sql = '';
|
|
66
|
+
|
|
42
67
|
this.connect(options);
|
|
43
68
|
}
|
|
44
69
|
|
|
@@ -63,13 +88,14 @@ class Db extends Context
|
|
|
63
88
|
allowField: false,
|
|
64
89
|
prefix: this._config.prefix || ''
|
|
65
90
|
};
|
|
91
|
+
this.sql = '';
|
|
66
92
|
return this;
|
|
67
93
|
}
|
|
68
94
|
|
|
69
95
|
/**
|
|
70
96
|
* 连接数据库连接池
|
|
71
97
|
* @public
|
|
72
|
-
* @param {
|
|
98
|
+
* @param {string|DbConfigItem} config - 数据库配置标识或连接参数
|
|
73
99
|
* @returns {this}
|
|
74
100
|
*/
|
|
75
101
|
connect(config='default') {
|
|
@@ -80,8 +106,9 @@ class Db extends Context
|
|
|
80
106
|
this._sql = this._config.connect(this._config);
|
|
81
107
|
} else {
|
|
82
108
|
const sqltype = this._config.type;
|
|
109
|
+
/** @class {Sql} */
|
|
83
110
|
const Sql = require(`./db/${sqltype}.js`);
|
|
84
|
-
this._sql = new Sql(this.ctx, this
|
|
111
|
+
this._sql = new Sql(this.ctx, this._$logger);
|
|
85
112
|
this._sql.connect(this._config);
|
|
86
113
|
}
|
|
87
114
|
|
|
@@ -91,10 +118,11 @@ class Db extends Context
|
|
|
91
118
|
/**
|
|
92
119
|
* 关闭数据库连接池
|
|
93
120
|
* @public
|
|
94
|
-
* @returns {Promise}
|
|
121
|
+
* @returns {Promise<this>}
|
|
95
122
|
*/
|
|
96
123
|
async close() {
|
|
97
|
-
|
|
124
|
+
await this._sql.close();
|
|
125
|
+
return this;
|
|
98
126
|
}
|
|
99
127
|
|
|
100
128
|
/**
|
|
@@ -131,7 +159,7 @@ class Db extends Context
|
|
|
131
159
|
* @param {string} sql - sql语句或参数
|
|
132
160
|
* @param {*} params - sql参数
|
|
133
161
|
* @param {*} [reset=true] - 是否重置参数
|
|
134
|
-
* @returns {Promise}
|
|
162
|
+
* @returns {Promise<*>}
|
|
135
163
|
*/
|
|
136
164
|
async query(sql, params, reset=true) {
|
|
137
165
|
params !== false && reset !== false && this.reset();
|
|
@@ -178,7 +206,7 @@ class Db extends Context
|
|
|
178
206
|
/**
|
|
179
207
|
* 设置查询字段,支持多次调用
|
|
180
208
|
* @public
|
|
181
|
-
* @param {
|
|
209
|
+
* @param {string|string[]} field - 表字段
|
|
182
210
|
* @returns {this}
|
|
183
211
|
*/
|
|
184
212
|
field(field) {
|
|
@@ -194,9 +222,9 @@ class Db extends Context
|
|
|
194
222
|
/**
|
|
195
223
|
* 设置表连接,支持多次调用
|
|
196
224
|
* @public
|
|
197
|
-
* @param {string} table -
|
|
225
|
+
* @param {string} table - 要连接的表名,不带前缀
|
|
198
226
|
* @param {string} on - 连接条件
|
|
199
|
-
* @param {string} [type=left] -
|
|
227
|
+
* @param {string} [type=left] - 连接方式,left|right|inner|outer,默认left
|
|
200
228
|
* @returns {this}
|
|
201
229
|
*/
|
|
202
230
|
join(table, on, type='left') {
|
|
@@ -209,8 +237,8 @@ class Db extends Context
|
|
|
209
237
|
/**
|
|
210
238
|
* 设置查询条件,支持多次调用
|
|
211
239
|
* @public
|
|
212
|
-
* @param {
|
|
213
|
-
* @param {
|
|
240
|
+
* @param {Where} where - 查询条件
|
|
241
|
+
* @param {Link} [logic] - 多次调用之间的连接逻辑,and|or,默认and
|
|
214
242
|
* @returns {this}
|
|
215
243
|
*/
|
|
216
244
|
where(where, logic) {
|
|
@@ -250,7 +278,7 @@ class Db extends Context
|
|
|
250
278
|
* 设置排序方式,支持多次调用
|
|
251
279
|
* @public
|
|
252
280
|
* @param {string} field - 排序字段
|
|
253
|
-
* @param {string} [order] -
|
|
281
|
+
* @param {string} [order] - 排序方式,asc|desc,默认asc
|
|
254
282
|
* @returns {this}
|
|
255
283
|
*/
|
|
256
284
|
order(field, order='asc') {
|
|
@@ -263,14 +291,16 @@ class Db extends Context
|
|
|
263
291
|
/**
|
|
264
292
|
* 设置查询数量
|
|
265
293
|
* @public
|
|
266
|
-
* @param {number} offset - 开始位置
|
|
294
|
+
* @param {number|string} offset - 开始位置
|
|
267
295
|
* @param {number} [rows] - 行数,不传,则按offset
|
|
268
296
|
* @returns {this}
|
|
269
297
|
*/
|
|
270
298
|
limit(offset, rows) {
|
|
271
299
|
if(typeof offset === 'undefined') return this;
|
|
272
|
-
|
|
273
|
-
|
|
300
|
+
// @ts-ignore
|
|
301
|
+
offset = offset ? parseInt(offset) : 0;
|
|
302
|
+
// @ts-ignore
|
|
303
|
+
rows = rows ? parseInt(rows) : null;
|
|
274
304
|
this._options.limit = 'limit ' + offset + (rows ? ',' + rows : '');
|
|
275
305
|
return this;
|
|
276
306
|
}
|
|
@@ -294,10 +324,10 @@ class Db extends Context
|
|
|
294
324
|
/**
|
|
295
325
|
* 设置查询结果缓存
|
|
296
326
|
* @public
|
|
297
|
-
* @param {number} time -
|
|
327
|
+
* @param {number} time - 单位秒,为0则不缓存
|
|
298
328
|
* @returns {this}
|
|
299
329
|
*/
|
|
300
|
-
|
|
330
|
+
withCache(time) {
|
|
301
331
|
this._options.cache_time = time;
|
|
302
332
|
return this;
|
|
303
333
|
}
|
|
@@ -305,7 +335,7 @@ class Db extends Context
|
|
|
305
335
|
/**
|
|
306
336
|
* 设置返回sql语句(最终会返回序列化后的sql,不会真实查询数据库)
|
|
307
337
|
* @public
|
|
308
|
-
* @param {boolean} [fetch] - 是否返回sql
|
|
338
|
+
* @param {boolean} [fetch] - 是否返回sql,默认true
|
|
309
339
|
* @returns {this}
|
|
310
340
|
*/
|
|
311
341
|
getSql(fetch = true) {
|
|
@@ -314,9 +344,9 @@ class Db extends Context
|
|
|
314
344
|
}
|
|
315
345
|
|
|
316
346
|
/**
|
|
317
|
-
*
|
|
347
|
+
* 设置字段过滤(新增或更新数据时)
|
|
318
348
|
* @public
|
|
319
|
-
* @param {
|
|
349
|
+
* @param {boolean|string|string[]} [field] - 允许字段,为true,则按数据表字段
|
|
320
350
|
* @returns {this}
|
|
321
351
|
*/
|
|
322
352
|
allowField(field = true) {
|
|
@@ -330,9 +360,9 @@ class Db extends Context
|
|
|
330
360
|
}
|
|
331
361
|
|
|
332
362
|
/**
|
|
333
|
-
*
|
|
363
|
+
* 设置要新增或更新的数据
|
|
334
364
|
* @public
|
|
335
|
-
* @param {
|
|
365
|
+
* @param {Object.<string, any>} data - 要新增或更新的数据
|
|
336
366
|
* @returns {this}
|
|
337
367
|
*/
|
|
338
368
|
data(data) {
|
|
@@ -345,20 +375,19 @@ class Db extends Context
|
|
|
345
375
|
/**
|
|
346
376
|
* 获取多条数据
|
|
347
377
|
* @public
|
|
348
|
-
* @param {
|
|
349
|
-
* @returns {Promise<
|
|
378
|
+
* @param {Where} [condition] - 查询条件,设置后将会替换where方法设置的条件
|
|
379
|
+
* @returns {Promise<ListData>}
|
|
350
380
|
*/
|
|
351
381
|
async select(condition) {
|
|
352
382
|
condition && (this._options.where = [], this._options.where.push([condition]));
|
|
353
383
|
|
|
354
|
-
let params = [];
|
|
355
384
|
const table = this._parseTable();
|
|
356
385
|
const distinct = this._options.distinct;
|
|
357
386
|
const field = this._parseField();
|
|
358
387
|
const join = this._parseJoin();
|
|
359
388
|
|
|
360
389
|
const where = this._parseWhere();
|
|
361
|
-
params =
|
|
390
|
+
const params = where[1];
|
|
362
391
|
|
|
363
392
|
const order = this._parseOrder();
|
|
364
393
|
|
|
@@ -370,18 +399,19 @@ class Db extends Context
|
|
|
370
399
|
|
|
371
400
|
if(this._options.getSql) {
|
|
372
401
|
this._options.getSql = false;
|
|
373
|
-
|
|
402
|
+
this.sql = this._sql.format(this._queryStr, params);
|
|
403
|
+
return;
|
|
374
404
|
}
|
|
375
405
|
|
|
376
406
|
if(this._options.cache_time) {
|
|
377
407
|
const cache_time = this._options.cache_time;
|
|
378
408
|
const cache_key = md5(this._sql.format(this._queryStr, params));
|
|
379
|
-
if(this.
|
|
409
|
+
if(this._$cache.get(cache_key)) {
|
|
380
410
|
this.reset();
|
|
381
|
-
return this.
|
|
411
|
+
return this._$cache.get(cache_key);
|
|
382
412
|
}
|
|
383
413
|
const result = await this.query(this._queryStr, params);
|
|
384
|
-
this.
|
|
414
|
+
this._$cache.set(cache_key, result, cache_time);
|
|
385
415
|
return result;
|
|
386
416
|
}
|
|
387
417
|
|
|
@@ -391,8 +421,8 @@ class Db extends Context
|
|
|
391
421
|
/**
|
|
392
422
|
* 获取一条数据
|
|
393
423
|
* @public
|
|
394
|
-
* @param {
|
|
395
|
-
* @returns {Promise
|
|
424
|
+
* @param {Where} [condition] - 查询条件
|
|
425
|
+
* @returns {Promise<(RowData|null)>}
|
|
396
426
|
*/
|
|
397
427
|
async find(condition) {
|
|
398
428
|
condition && (this._options.where = [], this._options.where.push([condition]));
|
|
@@ -409,8 +439,8 @@ class Db extends Context
|
|
|
409
439
|
/**
|
|
410
440
|
* 获取一个字段值
|
|
411
441
|
* @public
|
|
412
|
-
* @param {string} field -
|
|
413
|
-
* @returns {Promise
|
|
442
|
+
* @param {string} field - 要查询的字段
|
|
443
|
+
* @returns {Promise<(any|null)>}
|
|
414
444
|
*/
|
|
415
445
|
async value(field) {
|
|
416
446
|
this._options.field = [];
|
|
@@ -479,7 +509,7 @@ class Db extends Context
|
|
|
479
509
|
* @public
|
|
480
510
|
* @param {string} field - 数据字段
|
|
481
511
|
* @param {string} [key] - key字段,不设置返回数据数组,设置则返回{key: field}对象数组
|
|
482
|
-
* @returns {Promise<(
|
|
512
|
+
* @returns {Promise<(any[]|Object.<string, any>)>}
|
|
483
513
|
*/
|
|
484
514
|
async column(field, key) {
|
|
485
515
|
this._options.field = [];
|
|
@@ -490,34 +520,30 @@ class Db extends Context
|
|
|
490
520
|
return await this.select();
|
|
491
521
|
}
|
|
492
522
|
|
|
493
|
-
/**
|
|
494
|
-
* @type {ListData}
|
|
495
|
-
*/
|
|
496
523
|
const rows = await this.select();
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
if(key) {
|
|
524
|
+
if(key) {
|
|
525
|
+
return rows.reduce((result, row) => {
|
|
500
526
|
result[row[key]] = row[field];
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
527
|
+
return result;
|
|
528
|
+
}, {});
|
|
529
|
+
} else {
|
|
530
|
+
return rows.map(row => row[field]);
|
|
531
|
+
}
|
|
506
532
|
}
|
|
507
533
|
|
|
508
534
|
/**
|
|
509
535
|
* 获取多条数据(按分页)
|
|
510
536
|
* @public
|
|
511
537
|
* @param {object} [param0] - 分页参数
|
|
512
|
-
* @param {number} [param0.page] -
|
|
513
|
-
* @param {number} [param0.page_size] -
|
|
514
|
-
* @param {PaginationInstance} [param0.pagination] -
|
|
515
|
-
* @returns {Promise<
|
|
538
|
+
* @param {number} [param0.page] - 页码,可通过page方法配置,默认从默认分页类获取
|
|
539
|
+
* @param {number} [param0.page_size] - 每页行数,可通过page方法配置,默认从config配置获取
|
|
540
|
+
* @param {PaginationInstance} [param0.pagination] - 分页类实例,为空时使用默认分页类
|
|
541
|
+
* @returns {Promise<[ListData, PaginationInstance]>} - [ListData, PaginationInstance]
|
|
516
542
|
*/
|
|
517
|
-
async
|
|
543
|
+
async paginate({page, page_size, pagination} = {}) {
|
|
518
544
|
!page && (page = this._options.page.page);
|
|
519
545
|
!page_size && (page_size = this._options.page.pageSize);
|
|
520
|
-
!pagination && (pagination = this
|
|
546
|
+
!pagination && (pagination = this._$pagination);
|
|
521
547
|
|
|
522
548
|
const options = {...this._options}; // 暂存options
|
|
523
549
|
const total = await this.count();
|
|
@@ -530,6 +556,7 @@ class Db extends Context
|
|
|
530
556
|
|
|
531
557
|
if(total) {
|
|
532
558
|
this._options = options; // 恢复options
|
|
559
|
+
// @ts-ignore
|
|
533
560
|
const result = await this.page(page, page_size).select();
|
|
534
561
|
return [result, pagination];
|
|
535
562
|
} else {
|
|
@@ -538,10 +565,10 @@ class Db extends Context
|
|
|
538
565
|
}
|
|
539
566
|
|
|
540
567
|
/**
|
|
541
|
-
*
|
|
568
|
+
* 新增一条数据
|
|
542
569
|
* @public
|
|
543
|
-
* @param {object} data -
|
|
544
|
-
* @returns {Promise<
|
|
570
|
+
* @param {object} [data] - 待新增数据,会替换通过data方法传入的数据
|
|
571
|
+
* @returns {Promise<OkPacket>}
|
|
545
572
|
*/
|
|
546
573
|
async insert(data) {
|
|
547
574
|
data && (this._options.data = data);
|
|
@@ -553,7 +580,8 @@ class Db extends Context
|
|
|
553
580
|
this._queryStr = `insert into ${table} ${sql}`;
|
|
554
581
|
if(this._options.getSql) {
|
|
555
582
|
this._options.getSql = false;
|
|
556
|
-
|
|
583
|
+
this.sql = this._sql.format(this._queryStr, params);
|
|
584
|
+
return;
|
|
557
585
|
}
|
|
558
586
|
return await this.query(this._queryStr, params);
|
|
559
587
|
}
|
|
@@ -561,9 +589,9 @@ class Db extends Context
|
|
|
561
589
|
/**
|
|
562
590
|
* 更新数据
|
|
563
591
|
* @public
|
|
564
|
-
* @param {object} data -
|
|
565
|
-
* @param {
|
|
566
|
-
* @returns {Promise<
|
|
592
|
+
* @param {object} [data] - 更新数据,会替换通过data方法传入的数据
|
|
593
|
+
* @param {Where} [condition] - 更新条件,会替换通过where方法传入的条件
|
|
594
|
+
* @returns {Promise<OkPacket>}
|
|
567
595
|
*/
|
|
568
596
|
async update(data, condition) {
|
|
569
597
|
data && (this._options.data = data);
|
|
@@ -576,7 +604,7 @@ class Db extends Context
|
|
|
576
604
|
const [where, whereParams] = this._parseWhere();
|
|
577
605
|
if(!where[0]) {
|
|
578
606
|
const message = 'update方法必须传入where参数';
|
|
579
|
-
this
|
|
607
|
+
this._$logger.sql(message);
|
|
580
608
|
throw new Error('DbError: ' + message);
|
|
581
609
|
}
|
|
582
610
|
const params = [...dataParams, ...whereParams];
|
|
@@ -584,7 +612,8 @@ class Db extends Context
|
|
|
584
612
|
this._queryStr = `update ${table} set ${sql} ${where}`;
|
|
585
613
|
if(this._options.getSql) {
|
|
586
614
|
this._options.getSql = false;
|
|
587
|
-
|
|
615
|
+
this.sql = this._sql.format(this._queryStr, params);
|
|
616
|
+
return;
|
|
588
617
|
}
|
|
589
618
|
return await this.query(this._queryStr, params);
|
|
590
619
|
}
|
|
@@ -593,10 +622,10 @@ class Db extends Context
|
|
|
593
622
|
* 字段值增加
|
|
594
623
|
* @public
|
|
595
624
|
* @param {string} field - 字段
|
|
596
|
-
* @param {number} [step
|
|
597
|
-
* @returns {Promise<
|
|
625
|
+
* @param {number} [step] - 增加值,默认1
|
|
626
|
+
* @returns {Promise<OkPacket>}
|
|
598
627
|
*/
|
|
599
|
-
async inc(field, step) {
|
|
628
|
+
async inc(field, step = 1) {
|
|
600
629
|
return await this.update({[field]: ['inc', step]});
|
|
601
630
|
}
|
|
602
631
|
|
|
@@ -604,10 +633,10 @@ class Db extends Context
|
|
|
604
633
|
* 字段值减少
|
|
605
634
|
* @public
|
|
606
635
|
* @param {string} field - 字段
|
|
607
|
-
* @param {number} [step
|
|
608
|
-
* @returns {Promise<
|
|
636
|
+
* @param {number} [step] - 减少值,默认1
|
|
637
|
+
* @returns {Promise<OkPacket>}
|
|
609
638
|
*/
|
|
610
|
-
async dec(field, step) {
|
|
639
|
+
async dec(field, step = 1) {
|
|
611
640
|
return await this.update({[field]: ['dec', step]});
|
|
612
641
|
}
|
|
613
642
|
|
|
@@ -616,7 +645,7 @@ class Db extends Context
|
|
|
616
645
|
* @public
|
|
617
646
|
* @param {string} field - 字段
|
|
618
647
|
* @param {string} value - 自定义表达式
|
|
619
|
-
* @returns {Promise<
|
|
648
|
+
* @returns {Promise<OkPacket>}
|
|
620
649
|
*/
|
|
621
650
|
async exp(field, value) {
|
|
622
651
|
return await this.update({[field]: ['exp', value]});
|
|
@@ -625,26 +654,26 @@ class Db extends Context
|
|
|
625
654
|
/**
|
|
626
655
|
* 删除数据
|
|
627
656
|
* @public
|
|
628
|
-
* @param {
|
|
629
|
-
* @returns {Promise<
|
|
657
|
+
* @param {Where} [condition] - 删除条件,会替换通过where方法传入的条件
|
|
658
|
+
* @returns {Promise<OkPacket>}
|
|
630
659
|
*/
|
|
631
660
|
async delete(condition) {
|
|
632
661
|
condition && (this._options.where = [], this._options.where.push([condition]));
|
|
633
662
|
|
|
634
|
-
let params = [];
|
|
635
663
|
const table = this._parseTable();
|
|
636
664
|
const where = this._parseWhere();
|
|
637
665
|
if(!where[0]) {
|
|
638
666
|
const message = 'delete方法必须传入where参数';
|
|
639
|
-
this
|
|
667
|
+
this._$logger.sql(message);
|
|
640
668
|
throw new Error('DbError: ' + message);
|
|
641
669
|
}
|
|
642
|
-
params =
|
|
670
|
+
const params = where[1];
|
|
643
671
|
|
|
644
672
|
this._queryStr = `delete from ${table} ${where[0]}`;
|
|
645
673
|
if(this._options.getSql) {
|
|
646
674
|
this._options.getSql = false;
|
|
647
|
-
|
|
675
|
+
this.sql = this._sql.format(this._queryStr, params);
|
|
676
|
+
return;
|
|
648
677
|
}
|
|
649
678
|
return await this.query(this._queryStr, params);
|
|
650
679
|
}
|
|
@@ -655,23 +684,24 @@ class Db extends Context
|
|
|
655
684
|
* @param {string} sql - sql语句或参数
|
|
656
685
|
* @param {*} params - sql参数
|
|
657
686
|
* @param {*} [reset=true] - 是否重置参数
|
|
658
|
-
* @returns {Promise<
|
|
687
|
+
* @returns {Promise<OkPacket|ListData|RowData>}
|
|
659
688
|
*/
|
|
660
689
|
async execute(sql, params, reset=true) {
|
|
661
690
|
this._queryStr = sql;
|
|
662
691
|
if(this._options.getSql) {
|
|
663
692
|
this._options.getSql = false;
|
|
664
|
-
|
|
693
|
+
this.sql = this._sql.format(this._queryStr, params);
|
|
694
|
+
return;
|
|
665
695
|
}
|
|
666
696
|
|
|
667
697
|
if(this._options.cache_time) {
|
|
668
698
|
const cache_time = this._options.cache_time;
|
|
669
699
|
const cache_key = md5(this._sql.format(this._queryStr, params));
|
|
670
|
-
if(this.
|
|
671
|
-
return this.
|
|
700
|
+
if(this._$cache.get(cache_key)) {
|
|
701
|
+
return this._$cache.get(cache_key);
|
|
672
702
|
}
|
|
673
703
|
const result = await this.query(this._queryStr, params);
|
|
674
|
-
this.
|
|
704
|
+
this._$cache.set(cache_key, result, cache_time);
|
|
675
705
|
return result;
|
|
676
706
|
}
|
|
677
707
|
return await this.query(this._queryStr, params, reset);
|
|
@@ -702,11 +732,21 @@ class Db extends Context
|
|
|
702
732
|
return table_info.map(item => item.Field);
|
|
703
733
|
}
|
|
704
734
|
|
|
735
|
+
/**
|
|
736
|
+
* 解析数据表名字
|
|
737
|
+
* @public
|
|
738
|
+
* @returns {string} 包含``号的表名字
|
|
739
|
+
*/
|
|
705
740
|
_parseTable() {
|
|
706
741
|
const table = this._table.replace(' ', '` `');
|
|
707
742
|
return `\`${this._options.prefix}${table}\``;
|
|
708
743
|
}
|
|
709
744
|
|
|
745
|
+
/**
|
|
746
|
+
* 解析join
|
|
747
|
+
* @public
|
|
748
|
+
* @returns {string} join字符串
|
|
749
|
+
*/
|
|
710
750
|
_parseJoin() {
|
|
711
751
|
let join = '';
|
|
712
752
|
Object.keys(this._options.join).forEach(key => {
|
|
@@ -717,7 +757,13 @@ class Db extends Context
|
|
|
717
757
|
return join;
|
|
718
758
|
}
|
|
719
759
|
|
|
760
|
+
/**
|
|
761
|
+
* 解析字段
|
|
762
|
+
* @public
|
|
763
|
+
* @returns {string} 字段字符串
|
|
764
|
+
*/
|
|
720
765
|
_parseField() {
|
|
766
|
+
/** @type {string[]} */
|
|
721
767
|
let fields = [];
|
|
722
768
|
this._options.field.forEach(value => {
|
|
723
769
|
let field = value.split(' ');
|
|
@@ -727,21 +773,30 @@ class Db extends Context
|
|
|
727
773
|
alias = ' `' + field[length - 1] + '`';
|
|
728
774
|
field.pop();
|
|
729
775
|
}
|
|
730
|
-
|
|
776
|
+
let field_str = field.join(' ');
|
|
731
777
|
if(!~field.indexOf(')')) {
|
|
732
|
-
|
|
778
|
+
field_str = '`' + field_str.replace(/\./g, '`.`') + '`';
|
|
733
779
|
}
|
|
734
|
-
|
|
780
|
+
field_str = field_str.replace('`*`', '*');
|
|
735
781
|
fields.push(field + alias);
|
|
736
782
|
});
|
|
737
783
|
return fields.join(',') || '*';
|
|
738
784
|
}
|
|
739
785
|
|
|
786
|
+
/**
|
|
787
|
+
* 解析where参数
|
|
788
|
+
* @private
|
|
789
|
+
* @returns {[string, any[]]}
|
|
790
|
+
*/
|
|
740
791
|
_parseWhere() {
|
|
792
|
+
/** @type {Operator[]} */
|
|
741
793
|
const logic = ['=', '<>', '!=', '>', '>=', '<', '<=', 'like', 'not like', 'in', 'not in', 'between', 'not between', 'is', 'is not', 'exp'];
|
|
794
|
+
/** @type {string[]} */
|
|
742
795
|
const where = [];
|
|
796
|
+
/** @type {any[]} */
|
|
743
797
|
const params = [];
|
|
744
798
|
this._options.where.forEach(item => {
|
|
799
|
+
/** @type {Object.<string, any>} */
|
|
745
800
|
const whereList = item[0];
|
|
746
801
|
const whereLink = (item[1] && item[1].toLowerCase()) === 'or' ? 'or' : 'and';
|
|
747
802
|
let whereChild = '';
|
|
@@ -792,6 +847,11 @@ class Db extends Context
|
|
|
792
847
|
return [where.length ? 'where ' + where.join(' ') : '', params];
|
|
793
848
|
}
|
|
794
849
|
|
|
850
|
+
/**
|
|
851
|
+
* 解析order参数
|
|
852
|
+
* @private
|
|
853
|
+
* @returns {string} 返回排序,类似order by id desc
|
|
854
|
+
*/
|
|
795
855
|
_parseOrder() {
|
|
796
856
|
let order = '';
|
|
797
857
|
Object.keys(this._options.order).forEach(key => {
|
|
@@ -802,9 +862,17 @@ class Db extends Context
|
|
|
802
862
|
return order;
|
|
803
863
|
}
|
|
804
864
|
|
|
865
|
+
/**
|
|
866
|
+
* 解析insert数据
|
|
867
|
+
* @private
|
|
868
|
+
* @returns {[string, any[]]}
|
|
869
|
+
*/
|
|
805
870
|
_parseInsertData() {
|
|
871
|
+
/** @type {string[]} */
|
|
806
872
|
const fields = [];
|
|
873
|
+
/** @type {string[]} */
|
|
807
874
|
const values = [];
|
|
875
|
+
/** @type {any[]} */
|
|
808
876
|
const params = [];
|
|
809
877
|
Object.keys(this._options.data).forEach(key => {
|
|
810
878
|
const field = '`' + key.replace('.', '`.`') + '`';
|
|
@@ -816,8 +884,14 @@ class Db extends Context
|
|
|
816
884
|
return [`(${fields.join(', ')}) values (${values.join(', ')})`, params];
|
|
817
885
|
}
|
|
818
886
|
|
|
887
|
+
/**
|
|
888
|
+
* 解析update数据
|
|
889
|
+
* @private
|
|
890
|
+
* @returns {[string, any[]]}
|
|
891
|
+
*/
|
|
819
892
|
_parseUpdateData() {
|
|
820
893
|
let data = '';
|
|
894
|
+
/** @type {any[]} */
|
|
821
895
|
const params = [];
|
|
822
896
|
Object.keys(this._options.data).forEach(key => {
|
|
823
897
|
const field = '`' + key.replace('.', '`.`') + '`';
|
|
@@ -846,6 +920,11 @@ class Db extends Context
|
|
|
846
920
|
return [data, params];
|
|
847
921
|
}
|
|
848
922
|
|
|
923
|
+
/**
|
|
924
|
+
* 过滤数据
|
|
925
|
+
* @private
|
|
926
|
+
* @returns {Promise<Object.<string, any>>} 返回过滤后的数据
|
|
927
|
+
*/
|
|
849
928
|
async _filterData() {
|
|
850
929
|
if(!this._options.allowField) {
|
|
851
930
|
return this._options.data;
|
|
@@ -854,10 +933,10 @@ class Db extends Context
|
|
|
854
933
|
let allowField = this._options.allowField;
|
|
855
934
|
if(allowField === true) {
|
|
856
935
|
const table_name = this._options.prefix + this._table;
|
|
857
|
-
if(!this._tableField
|
|
858
|
-
this._tableField
|
|
936
|
+
if(!this._tableField.get(table_name)) {
|
|
937
|
+
this._tableField.set(table_name, await this.tableField());
|
|
859
938
|
}
|
|
860
|
-
allowField = this._tableField[
|
|
939
|
+
allowField = this._tableField.get(table_name) || [];
|
|
861
940
|
}
|
|
862
941
|
|
|
863
942
|
Object.keys(this._options.data).forEach(key => {
|
|
@@ -869,40 +948,79 @@ class Db extends Context
|
|
|
869
948
|
}
|
|
870
949
|
|
|
871
950
|
/**
|
|
872
|
-
*
|
|
873
|
-
* @
|
|
874
|
-
|
|
951
|
+
* @type {Logger} Logger静态类
|
|
952
|
+
* @private
|
|
953
|
+
*/
|
|
954
|
+
// @ts-ignore
|
|
955
|
+
__logger = null;
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* @type {Logger} Logger静态类
|
|
875
959
|
*/
|
|
876
|
-
|
|
877
|
-
|
|
960
|
+
get _$logger() {
|
|
961
|
+
if(this.__logger === null) {
|
|
962
|
+
if(this.$logger && this.$logger.__ISCLASS__) {
|
|
963
|
+
this.__logger = this.$logger;
|
|
964
|
+
} else if(this.$ && this.$.logger) {
|
|
965
|
+
this.__logger = this.$.logger;
|
|
966
|
+
} else {
|
|
967
|
+
this.__logger = require('./logger');
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return this.__logger;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
set _$logger(logger) {
|
|
974
|
+
this.setLogger(logger);
|
|
878
975
|
}
|
|
879
976
|
|
|
880
977
|
/**
|
|
881
|
-
*
|
|
882
|
-
* @param {
|
|
978
|
+
* 设置日志器
|
|
979
|
+
* @param {Logger} logger
|
|
980
|
+
* @returns {this}
|
|
883
981
|
*/
|
|
884
|
-
|
|
885
|
-
|
|
982
|
+
setLogger(logger) {
|
|
983
|
+
this.__logger = logger;
|
|
984
|
+
this._sql && this._sql.setLogger(logger);
|
|
985
|
+
return this;
|
|
886
986
|
}
|
|
887
987
|
|
|
888
988
|
/**
|
|
889
|
-
*
|
|
890
|
-
* @
|
|
989
|
+
* 设置数据库缓存实例
|
|
990
|
+
* @type {PaginationInstance}
|
|
891
991
|
*/
|
|
892
|
-
|
|
893
|
-
|
|
992
|
+
// @ts-ignore
|
|
993
|
+
__pagination = null;
|
|
994
|
+
|
|
995
|
+
/**
|
|
996
|
+
* 获取分页器实例
|
|
997
|
+
* @returns {PaginationInstance}
|
|
998
|
+
*/
|
|
999
|
+
get _$pagination() {
|
|
1000
|
+
if(this.$pagination && this.$pagination.__ISCLASS__) {
|
|
1001
|
+
this.__pagination = this.$pagination;
|
|
1002
|
+
} else if(this.$ && this.$.pagination) {
|
|
1003
|
+
this. __pagination = this.$.pagination;
|
|
1004
|
+
} else {
|
|
1005
|
+
this.__pagination = new (require('./pagination'))(this.ctx);
|
|
1006
|
+
}
|
|
1007
|
+
return this.__pagination;
|
|
894
1008
|
}
|
|
895
|
-
}
|
|
896
1009
|
|
|
897
|
-
/**
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
// @ts-ignore
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
1010
|
+
/**
|
|
1011
|
+
* 设置数据库缓存实例
|
|
1012
|
+
* @type {Cache}
|
|
1013
|
+
*/
|
|
1014
|
+
// @ts-ignore
|
|
1015
|
+
static cache = new (require('./cache'))(new Map());
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* 数据库拥有一个独立的数据库缓存实例
|
|
1019
|
+
* @returns {Cache}
|
|
1020
|
+
*/
|
|
1021
|
+
get _$cache() {
|
|
1022
|
+
return Db.cache;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
907
1025
|
|
|
908
1026
|
module.exports = Db;
|