jj.js 0.18.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/lib/db.js CHANGED
@@ -3,29 +3,24 @@ const md5 = require('./utils/md5');
3
3
  const Context = require('./context');
4
4
 
5
5
  /**
6
+ * @typedef {import('../types').KoaCtx} KoaCtx
7
+ * @typedef {import('../types').DbConfigItem} DbConfigItem
6
8
  * @typedef {import('../types').Pagination} Pagination
7
9
  * @typedef {import('../types').PaginationInstance} PaginationInstance
8
- * @typedef {import('../types').Pool} Pool
9
- * @typedef {import('../types').PoolConfig} PoolConfig
10
- * @typedef {import('../types').PoolConnection} PoolConnection
11
- * @typedef {import('../types').QueryOptions} QueryOptions
12
10
  * @typedef {import('../types').OkPacket} OkPacket
13
11
  * @typedef {import('../types').RowData} RowData
14
12
  * @typedef {import('../types').ListData} ListData
15
13
  * @typedef {import('../types').FieldInfo} FieldInfo
16
- * @typedef {import('../types').PoolMap} PoolMap
14
+ * @typedef {import('../types').Link} Link
15
+ * @typedef {import('../types').Operator} Operator
16
+ * @typedef {import('../types').Where} Where
17
+ * @typedef {import('../types').Sql} Sql
18
+ * @typedef {import('../types').SqlInstance} SqlInstance
19
+ * @typedef {import('../types').Logger} Logger
20
+ * @typedef {import('../types')._DbOptions} _DbOptions
21
+ * @typedef {import('../types').Cache} Cache
17
22
  */
18
23
 
19
- //连接池
20
- /**
21
- * @type {PoolMap}
22
- */
23
- const pool = new Map();
24
- //事务连接
25
- const trans = new Map();
26
- //事务嵌套
27
- const nest = new Map();
28
-
29
24
  /**
30
25
  * @extends Context
31
26
  */
@@ -34,20 +29,41 @@ class Db extends Context
34
29
  /**
35
30
  * Initialize a new `Db`
36
31
  * @public
37
- * @param {import('../types').KoaCtx} [ctx]
38
- * @param {(string|PoolConfig)} [options] - 数据库配置标识或连接参数
32
+ * @param {object|KoaCtx} [ctx]
33
+ * @param {string|DbConfigItem} [options] - 数据库配置标识或连接参数
39
34
  */
40
35
  constructor(ctx, options) {
41
36
  ctx = ctx || {};
42
37
  super(ctx);
38
+ /**
39
+ * @type {DbConfigItem}
40
+ */
41
+ // @ts-ignore
43
42
  this._config = null;
44
43
  this._table = '';
44
+ /**
45
+ * @type {_DbOptions}
46
+ */
47
+ // @ts-ignore
45
48
  this._options = {};
46
49
  /**
47
50
  * @type {string}
48
51
  */
49
52
  this._queryStr = '';
50
- this._tableField = {};
53
+ /**
54
+ * @type {Map<string, string[]>}
55
+ */
56
+ this._tableField = new Map();
57
+ /**
58
+ * @type {SqlInstance} sql实例
59
+ */
60
+ // @ts-ignore
61
+ this._sql = null;
62
+ /**
63
+ * @type {String} sql语句
64
+ */
65
+ this.sql = '';
66
+
51
67
  this.connect(options);
52
68
  }
53
69
 
@@ -72,34 +88,28 @@ class Db extends Context
72
88
  allowField: false,
73
89
  prefix: this._config.prefix || ''
74
90
  };
91
+ this.sql = '';
75
92
  return this;
76
93
  }
77
94
 
78
95
  /**
79
96
  * 连接数据库连接池
80
97
  * @public
81
- * @param {(string|PoolConfig)} options - 数据库配置标识或连接参数
98
+ * @param {string|DbConfigItem} config - 数据库配置标识或连接参数
82
99
  * @returns {this}
83
100
  */
84
- connect(options='default') {
85
- this._config = typeof options === 'string' ? cfg_db[options] : options;
101
+ connect(config='default') {
102
+ this._config = typeof config === 'string' ? cfg_db[config] : config;
86
103
  this.reset();
87
104
 
88
- /**
89
- * @type {Pool}
90
- */
91
- let cur_pool = pool.get(this._config);
92
- if(!cur_pool) {
93
- switch(this._config.type) {
94
- case 'mysql':
95
- cur_pool = require('mysql').createPool(this._config);
96
- break;
97
- default:
98
- //other database, please provide database driver and implement the connection method
99
- cur_pool = this._config.connect(this._config);
100
- }
101
- pool.set(this._config, cur_pool);
102
- this.$logger.sql(`连接池创建成功:{all: ${pool.size}}`);
105
+ if(this._config.connect) {
106
+ this._sql = this._config.connect(this._config);
107
+ } else {
108
+ const sqltype = this._config.type;
109
+ /** @class {Sql} */
110
+ const Sql = require(`./db/${sqltype}.js`);
111
+ this._sql = new Sql(this.ctx, this._$logger);
112
+ this._sql.connect(this._config);
103
113
  }
104
114
 
105
115
  return this;
@@ -108,70 +118,11 @@ class Db extends Context
108
118
  /**
109
119
  * 关闭数据库连接池
110
120
  * @public
111
- * @returns {Promise}
121
+ * @returns {Promise<this>}
112
122
  */
113
123
  async close() {
114
- return new Promise((resolve, reject) => {
115
- pool.has(this._config) && pool.get(this._config).end(err => {
116
- if(err) {
117
- const message = '连接池销毁失败:' + err.message;
118
- this.$logger.sql(message);
119
- this.$logger.error(message);
120
- reject(new Error('DbError: ' + message));
121
- } else {
122
- pool.delete(this._config);
123
- this.$logger.sql(`连接池销毁成功:{poolTotal: ${pool.size}}`);
124
- resolve(this);
125
- }
126
- });
127
- });
128
- }
129
-
130
- /**
131
- * 释放数据库连接
132
- * @public
133
- * @param {PoolConnection} conn - 数据库连接
134
- */
135
- release(conn) {
136
- try {
137
- conn.release();
138
- this.$logger.sql('释放数据库连接!');
139
- } catch(e) {
140
- const message = '释放数据库出错:' + e.message;
141
- this.$logger.sql(message);
142
- this.$logger.error(message);
143
- }
144
- }
145
-
146
- /**
147
- * 获取数据库连接
148
- * @private
149
- * @param {Pool} p
150
- * @returns {Promise}
151
- */
152
- async _creatConnect(p) {
153
- return new Promise((resolve, reject) => {
154
- p.getConnection((err, connection) => {
155
- if(err) {
156
- const message = '获取数据库连接失败:' + err.message;
157
- this.$logger.sql(message);
158
- this.$logger.error(message);
159
- reject(new Error('DbError: ' + message));
160
- } else {
161
- this.$logger.sql(`获取数据库连接:{limit: ${p.config.connectionLimit}, all: ${p._allConnections.length}, acquiring: ${p._acquiringConnections.length}, free: ${p._freeConnections.length}, queue: ${p._connectionQueue.length}}`);
162
- resolve(connection);
163
- }
164
- });
165
- });
166
- }
167
-
168
- /**
169
- * 获取数据库连接
170
- * @private
171
- * @returns {Promise<PoolConnection>}
172
- */
173
- async _getConnect() {
174
- return trans.get(this.ctx) || await this._creatConnect(pool.get(this._config));
124
+ await this._sql.close();
125
+ return this;
175
126
  }
176
127
 
177
128
  /**
@@ -181,49 +132,7 @@ class Db extends Context
181
132
  * @returns {Promise<string>}
182
133
  */
183
134
  async startTrans(fun) {
184
- const conn = await this._getConnect();
185
- trans.set(this.ctx, conn);
186
- let trans_nest = nest.get(conn) || 0;
187
- nest.set(conn, ++trans_nest);
188
- if(trans_nest > 1) {
189
- const message = `开启事务成功:{nest:${trans_nest}}`;
190
- this.$logger.sql(message);
191
- if(typeof fun === 'function') {
192
- try {
193
- await fun();
194
- await this.commit();
195
- } catch(e) {
196
- await this.rollback();
197
- throw e;
198
- }
199
- }
200
- return message;
201
- }
202
-
203
- return new Promise((resolve, reject) => {
204
- conn.beginTransaction(async (err) => {
205
- if(err) {
206
- const message = '开启事务失败:' + err.message;
207
- this.$logger.sql(message);
208
- this.$logger.error(message);
209
- reject(new Error('DbError: ' + message));
210
- } else {
211
- const message = '开启事务成功!';
212
- this.$logger.sql(message);
213
- if(typeof fun === 'function') {
214
- try {
215
- await fun();
216
- await this.commit();
217
- resolve('事务执行成功!');
218
- } catch(e) {
219
- await this.rollback();
220
- reject(e);
221
- }
222
- }
223
- resolve(message);
224
- }
225
- });
226
- });
135
+ return await this._sql.startTrans(fun);
227
136
  }
228
137
 
229
138
  /**
@@ -232,26 +141,7 @@ class Db extends Context
232
141
  * @returns {Promise<string>}
233
142
  */
234
143
  async rollback() {
235
- const conn = await this._getConnect();
236
- const trans_nest = nest.get(conn) || 0;
237
- if(trans_nest > 1) {
238
- nest.set(conn, trans_nest - 1);
239
- const message = `事务回滚成功:{nest:${trans_nest}}`;
240
- this.$logger.sql(message);
241
- return message;
242
- } else {
243
- nest.delete(conn);
244
- }
245
-
246
- return new Promise((resolve) => {
247
- conn.rollback(() => {
248
- trans.delete(this.ctx);
249
- const message = '事务回滚成功!';
250
- this.$logger.sql(message);
251
- this.release(conn);
252
- resolve(message);
253
- });
254
- });
144
+ return await this._sql.rollback();
255
145
  }
256
146
 
257
147
  /**
@@ -260,34 +150,7 @@ class Db extends Context
260
150
  * @returns {Promise<string>}
261
151
  */
262
152
  async commit() {
263
- const conn = await this._getConnect();
264
- const trans_nest = nest.get(conn) || 0;
265
- if(trans_nest > 1) {
266
- nest.set(conn, trans_nest - 1);
267
- const message = `事务提交成功:{nest:${trans_nest}}`;
268
- this.$logger.sql(message);
269
- return message;
270
- } else {
271
- nest.delete(conn);
272
- }
273
-
274
- return new Promise((resolve, reject) => {
275
- conn.commit((err) => {
276
- if(err) {
277
- const message = '事务提交失败:' + err.message;
278
- this.$logger.sql(message);
279
- this.$logger.error(message);
280
- this.rollback();
281
- reject(new Error('DbError: ' + message));
282
- } else {
283
- trans.delete(this.ctx);
284
- const message = '事务提交成功!';
285
- this.$logger.sql(message);
286
- this.release(conn);
287
- resolve(message);
288
- }
289
- });
290
- });
153
+ return await this._sql.commit();
291
154
  }
292
155
 
293
156
  /**
@@ -296,33 +159,13 @@ class Db extends Context
296
159
  * @param {string} sql - sql语句或参数
297
160
  * @param {*} params - sql参数
298
161
  * @param {*} [reset=true] - 是否重置参数
299
- * @returns {Promise}
162
+ * @returns {Promise<*>}
300
163
  */
301
164
  async query(sql, params, reset=true) {
302
165
  params !== false && reset !== false && this.reset();
303
166
  params || (params = []);
304
167
 
305
- /**
306
- * @type {PoolConnection}
307
- */
308
- const conn = await this._getConnect();
309
-
310
- return new Promise((resolve, reject) => {
311
- conn.query(sql, params, (err, data) => {
312
- if(err) {
313
- const message = '数据操作失败,' + err.message + "\r\nSQL:" + this.format(sql, params);
314
- this.$logger.sql(message);
315
- this.$logger.error(message);
316
- reject(new Error('DbError: ' + message));
317
- } else {
318
- this.$logger.sql('数据操作成功,SQL:' + this.format(sql, params));
319
- resolve(data);
320
- }
321
- if(!trans.has(this.ctx)) {
322
- this.release(conn);
323
- }
324
- });
325
- });
168
+ return await this._sql.query(sql, params);
326
169
  }
327
170
 
328
171
  /**
@@ -363,7 +206,7 @@ class Db extends Context
363
206
  /**
364
207
  * 设置查询字段,支持多次调用
365
208
  * @public
366
- * @param {(string|array)} field - 表名前缀
209
+ * @param {string|string[]} field - 表字段
367
210
  * @returns {this}
368
211
  */
369
212
  field(field) {
@@ -379,9 +222,9 @@ class Db extends Context
379
222
  /**
380
223
  * 设置表连接,支持多次调用
381
224
  * @public
382
- * @param {string} table - 要连接的表名
225
+ * @param {string} table - 要连接的表名,不带前缀
383
226
  * @param {string} on - 连接条件
384
- * @param {string} [type=left] - 连接方式
227
+ * @param {string} [type=left] - 连接方式,left|right|inner|outer,默认left
385
228
  * @returns {this}
386
229
  */
387
230
  join(table, on, type='left') {
@@ -394,8 +237,8 @@ class Db extends Context
394
237
  /**
395
238
  * 设置查询条件,支持多次调用
396
239
  * @public
397
- * @param {object} where - 查询条件
398
- * @param {object} [logic] - 多次调用之间的连接逻辑,默认and
240
+ * @param {Where} where - 查询条件
241
+ * @param {Link} [logic] - 多次调用之间的连接逻辑,and|or,默认and
399
242
  * @returns {this}
400
243
  */
401
244
  where(where, logic) {
@@ -435,7 +278,7 @@ class Db extends Context
435
278
  * 设置排序方式,支持多次调用
436
279
  * @public
437
280
  * @param {string} field - 排序字段
438
- * @param {string} [order] - 排序方式,默认asc
281
+ * @param {string} [order] - 排序方式,asc|desc,默认asc
439
282
  * @returns {this}
440
283
  */
441
284
  order(field, order='asc') {
@@ -448,14 +291,16 @@ class Db extends Context
448
291
  /**
449
292
  * 设置查询数量
450
293
  * @public
451
- * @param {number} offset - 开始位置
294
+ * @param {number|string} offset - 开始位置
452
295
  * @param {number} [rows] - 行数,不传,则按offset
453
296
  * @returns {this}
454
297
  */
455
298
  limit(offset, rows) {
456
299
  if(typeof offset === 'undefined') return this;
457
- offset = offset ? offset : 0;
458
- rows = rows ? rows : null;
300
+ // @ts-ignore
301
+ offset = offset ? parseInt(offset) : 0;
302
+ // @ts-ignore
303
+ rows = rows ? parseInt(rows) : null;
459
304
  this._options.limit = 'limit ' + offset + (rows ? ',' + rows : '');
460
305
  return this;
461
306
  }
@@ -479,10 +324,10 @@ class Db extends Context
479
324
  /**
480
325
  * 设置查询结果缓存
481
326
  * @public
482
- * @param {number} time - 0则不缓存
327
+ * @param {number} time - 单位秒,为0则不缓存
483
328
  * @returns {this}
484
329
  */
485
- cache(time) {
330
+ withCache(time) {
486
331
  this._options.cache_time = time;
487
332
  return this;
488
333
  }
@@ -490,7 +335,7 @@ class Db extends Context
490
335
  /**
491
336
  * 设置返回sql语句(最终会返回序列化后的sql,不会真实查询数据库)
492
337
  * @public
493
- * @param {boolean} [fetch] - 是否返回sql
338
+ * @param {boolean} [fetch] - 是否返回sql,默认true
494
339
  * @returns {this}
495
340
  */
496
341
  getSql(fetch = true) {
@@ -499,9 +344,9 @@ class Db extends Context
499
344
  }
500
345
 
501
346
  /**
502
- * 设置字段过滤(插入或更新数据时)
347
+ * 设置字段过滤(新增或更新数据时)
503
348
  * @public
504
- * @param {(boolean|string|string[])} [field] - 允许保存字段,为true,则按数据表字段
349
+ * @param {boolean|string|string[]} [field] - 允许字段,为true,则按数据表字段
505
350
  * @returns {this}
506
351
  */
507
352
  allowField(field = true) {
@@ -515,9 +360,9 @@ class Db extends Context
515
360
  }
516
361
 
517
362
  /**
518
- * 设置要插入或更新的数据
363
+ * 设置要新增或更新的数据
519
364
  * @public
520
- * @param {object} data - 要插入或更新的数据
365
+ * @param {Object.<string, any>} data - 要新增或更新的数据
521
366
  * @returns {this}
522
367
  */
523
368
  data(data) {
@@ -530,20 +375,19 @@ class Db extends Context
530
375
  /**
531
376
  * 获取多条数据
532
377
  * @public
533
- * @param {object} condition - 查询条件
378
+ * @param {Where} [condition] - 查询条件,设置后将会替换where方法设置的条件
534
379
  * @returns {Promise<ListData>}
535
380
  */
536
381
  async select(condition) {
537
382
  condition && (this._options.where = [], this._options.where.push([condition]));
538
383
 
539
- let params = [];
540
384
  const table = this._parseTable();
541
385
  const distinct = this._options.distinct;
542
386
  const field = this._parseField();
543
387
  const join = this._parseJoin();
544
388
 
545
389
  const where = this._parseWhere();
546
- params = params.concat(where[1]);
390
+ const params = where[1];
547
391
 
548
392
  const order = this._parseOrder();
549
393
 
@@ -555,18 +399,19 @@ class Db extends Context
555
399
 
556
400
  if(this._options.getSql) {
557
401
  this._options.getSql = false;
558
- return this.format(this._queryStr, params);
402
+ this.sql = this._sql.format(this._queryStr, params);
403
+ return;
559
404
  }
560
405
 
561
406
  if(this._options.cache_time) {
562
407
  const cache_time = this._options.cache_time;
563
- const cache_key = md5(this.format(this._queryStr, params));
564
- if(this.getCache(cache_key)) {
408
+ const cache_key = md5(this._sql.format(this._queryStr, params));
409
+ if(this._$cache.get(cache_key)) {
565
410
  this.reset();
566
- return this.getCache(cache_key);
411
+ return this._$cache.get(cache_key);
567
412
  }
568
413
  const result = await this.query(this._queryStr, params);
569
- this.setCache(cache_key, result, cache_time);
414
+ this._$cache.set(cache_key, result, cache_time);
570
415
  return result;
571
416
  }
572
417
 
@@ -576,8 +421,8 @@ class Db extends Context
576
421
  /**
577
422
  * 获取一条数据
578
423
  * @public
579
- * @param {object} condition - 查询条件
580
- * @returns {Promise<?RowData>}
424
+ * @param {Where} [condition] - 查询条件
425
+ * @returns {Promise<(RowData|null)>}
581
426
  */
582
427
  async find(condition) {
583
428
  condition && (this._options.where = [], this._options.where.push([condition]));
@@ -594,8 +439,8 @@ class Db extends Context
594
439
  /**
595
440
  * 获取一个字段值
596
441
  * @public
597
- * @param {string} field - 字段
598
- * @returns {Promise<*>}
442
+ * @param {string} field - 要查询的字段
443
+ * @returns {Promise<(any|null)>}
599
444
  */
600
445
  async value(field) {
601
446
  this._options.field = [];
@@ -664,7 +509,7 @@ class Db extends Context
664
509
  * @public
665
510
  * @param {string} field - 数据字段
666
511
  * @param {string} [key] - key字段,不设置返回数据数组,设置则返回{key: field}对象数组
667
- * @returns {Promise<(ListData|object)>}
512
+ * @returns {Promise<(any[]|Object.<string, any>)>}
668
513
  */
669
514
  async column(field, key) {
670
515
  this._options.field = [];
@@ -676,30 +521,29 @@ class Db extends Context
676
521
  }
677
522
 
678
523
  const rows = await this.select();
679
- const result = key ? {} : [];
680
- rows.forEach(row => {
681
- if(key) {
524
+ if(key) {
525
+ return rows.reduce((result, row) => {
682
526
  result[row[key]] = row[field];
683
- } else {
684
- result.push(row[field]);
685
- }
686
- });
687
- return result;
527
+ return result;
528
+ }, {});
529
+ } else {
530
+ return rows.map(row => row[field]);
531
+ }
688
532
  }
689
533
 
690
534
  /**
691
535
  * 获取多条数据(按分页)
692
536
  * @public
693
537
  * @param {object} [param0] - 分页参数
694
- * @param {number} [param0.page] - 页码
695
- * @param {number} [param0.page_size] - 每页行数
696
- * @param {PaginationInstance} [param0.pagination] - 分页类实例
697
- * @returns {Promise<array>} - [ListData, PaginationInstance]
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]
698
542
  */
699
- async pagination({page, page_size, pagination} = {}) {
543
+ async paginate({page, page_size, pagination} = {}) {
700
544
  !page && (page = this._options.page.page);
701
545
  !page_size && (page_size = this._options.page.pageSize);
702
- !pagination && (pagination = this.$pagination);
546
+ !pagination && (pagination = this._$pagination);
703
547
 
704
548
  const options = {...this._options}; // 暂存options
705
549
  const total = await this.count();
@@ -712,6 +556,7 @@ class Db extends Context
712
556
 
713
557
  if(total) {
714
558
  this._options = options; // 恢复options
559
+ // @ts-ignore
715
560
  const result = await this.page(page, page_size).select();
716
561
  return [result, pagination];
717
562
  } else {
@@ -720,26 +565,23 @@ class Db extends Context
720
565
  }
721
566
 
722
567
  /**
723
- * 插入一条数据
568
+ * 新增一条数据
724
569
  * @public
725
- * @param {object} data - 待插入数据
570
+ * @param {object} [data] - 待新增数据,会替换通过data方法传入的数据
726
571
  * @returns {Promise<OkPacket>}
727
572
  */
728
573
  async insert(data) {
729
574
  data && (this._options.data = data);
730
575
 
731
- let params = [];
732
576
  const table = this._parseTable();
733
-
734
577
  await this._filterData();
578
+ const [sql, params] = this._parseInsertData();
735
579
 
736
- data = this._parseData();
737
- params = params.concat(data[1]);
738
-
739
- this._queryStr = `insert into ${table} set ${data[0]}`;
580
+ this._queryStr = `insert into ${table} ${sql}`;
740
581
  if(this._options.getSql) {
741
582
  this._options.getSql = false;
742
- return this.format(this._queryStr, params);
583
+ this.sql = this._sql.format(this._queryStr, params);
584
+ return;
743
585
  }
744
586
  return await this.query(this._queryStr, params);
745
587
  }
@@ -747,34 +589,31 @@ class Db extends Context
747
589
  /**
748
590
  * 更新数据
749
591
  * @public
750
- * @param {object} data - 更新数据
751
- * @param {object} condition - 更新条件
592
+ * @param {object} [data] - 更新数据,会替换通过data方法传入的数据
593
+ * @param {Where} [condition] - 更新条件,会替换通过where方法传入的条件
752
594
  * @returns {Promise<OkPacket>}
753
595
  */
754
596
  async update(data, condition) {
755
597
  data && (this._options.data = data);
756
598
  condition && (this._options.where = [], this._options.where.push([condition]));
757
599
 
758
- let params = [];
759
600
  const table = this._parseTable();
760
-
761
601
  await this._filterData();
602
+ const [sql, dataParams] = this._parseUpdateData();
762
603
 
763
- data = this._parseData();
764
- params = params.concat(data[1]);
765
-
766
- const where = this._parseWhere();
604
+ const [where, whereParams] = this._parseWhere();
767
605
  if(!where[0]) {
768
606
  const message = 'update方法必须传入where参数';
769
- this.$logger.sql(message);
607
+ this._$logger.sql(message);
770
608
  throw new Error('DbError: ' + message);
771
609
  }
772
- params = params.concat(where[1]);
610
+ const params = [...dataParams, ...whereParams];
773
611
 
774
- this._queryStr = `update ${table} set ${data[0]} ${where[0]}`;
612
+ this._queryStr = `update ${table} set ${sql} ${where}`;
775
613
  if(this._options.getSql) {
776
614
  this._options.getSql = false;
777
- return this.format(this._queryStr, params);
615
+ this.sql = this._sql.format(this._queryStr, params);
616
+ return;
778
617
  }
779
618
  return await this.query(this._queryStr, params);
780
619
  }
@@ -783,10 +622,10 @@ class Db extends Context
783
622
  * 字段值增加
784
623
  * @public
785
624
  * @param {string} field - 字段
786
- * @param {number} [step=1] - 增加值,默认1
625
+ * @param {number} [step] - 增加值,默认1
787
626
  * @returns {Promise<OkPacket>}
788
627
  */
789
- async inc(field, step) {
628
+ async inc(field, step = 1) {
790
629
  return await this.update({[field]: ['inc', step]});
791
630
  }
792
631
 
@@ -794,10 +633,10 @@ class Db extends Context
794
633
  * 字段值减少
795
634
  * @public
796
635
  * @param {string} field - 字段
797
- * @param {number} [step=1] - 减少值,默认1
636
+ * @param {number} [step] - 减少值,默认1
798
637
  * @returns {Promise<OkPacket>}
799
638
  */
800
- async dec(field, step) {
639
+ async dec(field, step = 1) {
801
640
  return await this.update({[field]: ['dec', step]});
802
641
  }
803
642
 
@@ -815,26 +654,26 @@ class Db extends Context
815
654
  /**
816
655
  * 删除数据
817
656
  * @public
818
- * @param {object} condition - 山粗条件
657
+ * @param {Where} [condition] - 删除条件,会替换通过where方法传入的条件
819
658
  * @returns {Promise<OkPacket>}
820
659
  */
821
660
  async delete(condition) {
822
661
  condition && (this._options.where = [], this._options.where.push([condition]));
823
662
 
824
- let params = [];
825
663
  const table = this._parseTable();
826
664
  const where = this._parseWhere();
827
665
  if(!where[0]) {
828
666
  const message = 'delete方法必须传入where参数';
829
- this.$logger.sql(message);
667
+ this._$logger.sql(message);
830
668
  throw new Error('DbError: ' + message);
831
669
  }
832
- params = params.concat(where[1]);
670
+ const params = where[1];
833
671
 
834
672
  this._queryStr = `delete from ${table} ${where[0]}`;
835
673
  if(this._options.getSql) {
836
674
  this._options.getSql = false;
837
- return this.format(this._queryStr, params);
675
+ this.sql = this._sql.format(this._queryStr, params);
676
+ return;
838
677
  }
839
678
  return await this.query(this._queryStr, params);
840
679
  }
@@ -845,23 +684,24 @@ class Db extends Context
845
684
  * @param {string} sql - sql语句或参数
846
685
  * @param {*} params - sql参数
847
686
  * @param {*} [reset=true] - 是否重置参数
848
- * @returns {Promise<(OkPacket|ListData|RowData)>}
687
+ * @returns {Promise<OkPacket|ListData|RowData>}
849
688
  */
850
689
  async execute(sql, params, reset=true) {
851
690
  this._queryStr = sql;
852
691
  if(this._options.getSql) {
853
692
  this._options.getSql = false;
854
- return this.format(this._queryStr, params);
693
+ this.sql = this._sql.format(this._queryStr, params);
694
+ return;
855
695
  }
856
696
 
857
697
  if(this._options.cache_time) {
858
698
  const cache_time = this._options.cache_time;
859
- const cache_key = md5(this.format(this._queryStr, params));
860
- if(this.getCache(cache_key)) {
861
- return this.getCache(cache_key);
699
+ const cache_key = md5(this._sql.format(this._queryStr, params));
700
+ if(this._$cache.get(cache_key)) {
701
+ return this._$cache.get(cache_key);
862
702
  }
863
703
  const result = await this.query(this._queryStr, params);
864
- this.setCache(cache_key, result, cache_time);
704
+ this._$cache.set(cache_key, result, cache_time);
865
705
  return result;
866
706
  }
867
707
  return await this.query(this._queryStr, params, reset);
@@ -876,7 +716,7 @@ class Db extends Context
876
716
  async tableInfo(table) {
877
717
  const get_sql = this._options.getSql;
878
718
  this._options.getSql = false;
879
- const table_info = await this.table(table).execute(`show columns from ${this._parseTable()}`, false);
719
+ const table_info = await this.table(table)._sql.tableInfo(this._parseTable());
880
720
  this._options.getSql = get_sql;
881
721
  return table_info;
882
722
  }
@@ -893,22 +733,20 @@ class Db extends Context
893
733
  }
894
734
 
895
735
  /**
896
- * 序列化sql语句
736
+ * 解析数据表名字
897
737
  * @public
898
- * @param {string} sql - sql语句或参数
899
- * @param {*} params - sql参数
900
- * @returns {string}
738
+ * @returns {string} 包含``号的表名字
901
739
  */
902
- format(sql, params) {
903
- params || (params = []);
904
- return require('mysql').format(sql, params);
905
- }
906
-
907
740
  _parseTable() {
908
741
  const table = this._table.replace(' ', '` `');
909
742
  return `\`${this._options.prefix}${table}\``;
910
743
  }
911
744
 
745
+ /**
746
+ * 解析join
747
+ * @public
748
+ * @returns {string} join字符串
749
+ */
912
750
  _parseJoin() {
913
751
  let join = '';
914
752
  Object.keys(this._options.join).forEach(key => {
@@ -919,7 +757,13 @@ class Db extends Context
919
757
  return join;
920
758
  }
921
759
 
760
+ /**
761
+ * 解析字段
762
+ * @public
763
+ * @returns {string} 字段字符串
764
+ */
922
765
  _parseField() {
766
+ /** @type {string[]} */
923
767
  let fields = [];
924
768
  this._options.field.forEach(value => {
925
769
  let field = value.split(' ');
@@ -929,21 +773,30 @@ class Db extends Context
929
773
  alias = ' `' + field[length - 1] + '`';
930
774
  field.pop();
931
775
  }
932
- field = field.join(' ');
776
+ let field_str = field.join(' ');
933
777
  if(!~field.indexOf(')')) {
934
- field = '`' + field.replace(/\./g, '`.`') + '`';
778
+ field_str = '`' + field_str.replace(/\./g, '`.`') + '`';
935
779
  }
936
- field = field.replace('`*`', '*');
780
+ field_str = field_str.replace('`*`', '*');
937
781
  fields.push(field + alias);
938
782
  });
939
783
  return fields.join(',') || '*';
940
784
  }
941
785
 
786
+ /**
787
+ * 解析where参数
788
+ * @private
789
+ * @returns {[string, any[]]}
790
+ */
942
791
  _parseWhere() {
792
+ /** @type {Operator[]} */
943
793
  const logic = ['=', '<>', '!=', '>', '>=', '<', '<=', 'like', 'not like', 'in', 'not in', 'between', 'not between', 'is', 'is not', 'exp'];
794
+ /** @type {string[]} */
944
795
  const where = [];
796
+ /** @type {any[]} */
945
797
  const params = [];
946
798
  this._options.where.forEach(item => {
799
+ /** @type {Object.<string, any>} */
947
800
  const whereList = item[0];
948
801
  const whereLink = (item[1] && item[1].toLowerCase()) === 'or' ? 'or' : 'and';
949
802
  let whereChild = '';
@@ -994,6 +847,11 @@ class Db extends Context
994
847
  return [where.length ? 'where ' + where.join(' ') : '', params];
995
848
  }
996
849
 
850
+ /**
851
+ * 解析order参数
852
+ * @private
853
+ * @returns {string} 返回排序,类似order by id desc
854
+ */
997
855
  _parseOrder() {
998
856
  let order = '';
999
857
  Object.keys(this._options.order).forEach(key => {
@@ -1004,8 +862,36 @@ class Db extends Context
1004
862
  return order;
1005
863
  }
1006
864
 
1007
- _parseData() {
865
+ /**
866
+ * 解析insert数据
867
+ * @private
868
+ * @returns {[string, any[]]}
869
+ */
870
+ _parseInsertData() {
871
+ /** @type {string[]} */
872
+ const fields = [];
873
+ /** @type {string[]} */
874
+ const values = [];
875
+ /** @type {any[]} */
876
+ const params = [];
877
+ Object.keys(this._options.data).forEach(key => {
878
+ const field = '`' + key.replace('.', '`.`') + '`';
879
+ fields.push(field);
880
+ values.push('?');
881
+ const value = this._options.data[key];
882
+ params.push(value);
883
+ });
884
+ return [`(${fields.join(', ')}) values (${values.join(', ')})`, params];
885
+ }
886
+
887
+ /**
888
+ * 解析update数据
889
+ * @private
890
+ * @returns {[string, any[]]}
891
+ */
892
+ _parseUpdateData() {
1008
893
  let data = '';
894
+ /** @type {any[]} */
1009
895
  const params = [];
1010
896
  Object.keys(this._options.data).forEach(key => {
1011
897
  const field = '`' + key.replace('.', '`.`') + '`';
@@ -1034,6 +920,11 @@ class Db extends Context
1034
920
  return [data, params];
1035
921
  }
1036
922
 
923
+ /**
924
+ * 过滤数据
925
+ * @private
926
+ * @returns {Promise<Object.<string, any>>} 返回过滤后的数据
927
+ */
1037
928
  async _filterData() {
1038
929
  if(!this._options.allowField) {
1039
930
  return this._options.data;
@@ -1042,10 +933,10 @@ class Db extends Context
1042
933
  let allowField = this._options.allowField;
1043
934
  if(allowField === true) {
1044
935
  const table_name = this._options.prefix + this._table;
1045
- if(!this._tableField[table_name]) {
1046
- this._tableField[table_name] = await this.tableField();
936
+ if(!this._tableField.get(table_name)) {
937
+ this._tableField.set(table_name, await this.tableField());
1047
938
  }
1048
- allowField = this._tableField[table_name];
939
+ allowField = this._tableField.get(table_name) || [];
1049
940
  }
1050
941
 
1051
942
  Object.keys(this._options.data).forEach(key => {
@@ -1057,40 +948,79 @@ class Db extends Context
1057
948
  }
1058
949
 
1059
950
  /**
1060
- * 获取sql缓存
1061
- * @param {string} [key]
1062
- * @returns {*}
951
+ * @type {Logger} Logger静态类
952
+ * @private
1063
953
  */
1064
- getCache(key) {
1065
- return Db.cache.get(key);
954
+ // @ts-ignore
955
+ __logger = null;
956
+
957
+ /**
958
+ * @type {Logger} Logger静态类
959
+ */
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);
1066
975
  }
1067
976
 
1068
977
  /**
1069
- * 设置sql缓存
1070
- * @param {string} key
978
+ * 设置日志器
979
+ * @param {Logger} logger
980
+ * @returns {this}
1071
981
  */
1072
- setCache(key, data, cache_time) {
1073
- Db.cache.set(key, data, cache_time);
982
+ setLogger(logger) {
983
+ this.__logger = logger;
984
+ this._sql && this._sql.setLogger(logger);
985
+ return this;
1074
986
  }
1075
987
 
1076
988
  /**
1077
- * 删除sql缓存
1078
- * @param {string} [key]
989
+ * 设置数据库缓存实例
990
+ * @type {PaginationInstance}
1079
991
  */
1080
- deleteCache(key) {
1081
- Db.cache.delete(key);
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;
1082
1008
  }
1083
- }
1084
1009
 
1085
- /**
1086
- * 设置数据库缓存实例
1087
- * @type {import('../types').Cache}
1088
- */
1089
- // @ts-ignore
1090
- Db.cache = new (require('./cache'))();
1091
- /**
1092
- * 开启缓存自动清理
1093
- */
1094
- Db.cache.setIntervalTime(20 * 60 * 60);
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
+ }
1095
1025
 
1096
1026
  module.exports = Db;