jj.js 0.8.7 → 0.9.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
@@ -2,26 +2,60 @@ const {db: cfg_db} = require('./config');
2
2
  const md5 = require('./utils/md5');
3
3
  const Context = require('./context');
4
4
 
5
+ /**
6
+ * @typedef {import('./types').Pagination} Pagination
7
+ * @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
+ * @typedef {import('./types').OkPacket} OkPacket
13
+ * @typedef {import('./types').RowData} RowData
14
+ * @typedef {import('./types').ListData} ListData
15
+ * @typedef {import('./types').FieldInfo} FieldInfo
16
+ * @typedef {import('./types').PoolMap} PoolMap
17
+ */
18
+
5
19
  //连接池
20
+ /**
21
+ * @type {PoolMap}
22
+ */
6
23
  const pool = new Map();
7
24
  //事务连接
8
25
  const trans = new Map();
9
26
  //事务嵌套
10
27
  const nest = new Map();
11
28
 
29
+ /**
30
+ * @extends Context
31
+ */
12
32
  class Db extends Context
13
33
  {
34
+ /**
35
+ * Initialize a new `Db`
36
+ * @public
37
+ * @param {(import('./types').Context|object)} ctx
38
+ * @param {(string|PoolConfig)} [options] - 数据库配置标识或连接参数
39
+ */
14
40
  constructor(ctx, options) {
15
41
  ctx = ctx || {};
16
42
  super(ctx);
17
43
  this._config = null;
18
44
  this._table = '';
19
45
  this._options = {};
46
+ /**
47
+ * @type {string}
48
+ */
20
49
  this._queryStr = '';
21
50
  this._tableField = {};
22
51
  this.connect(options);
23
52
  }
24
53
 
54
+ /**
55
+ * 重置参数
56
+ * @public
57
+ * @returns {this}
58
+ */
25
59
  reset() {
26
60
  this._options = {
27
61
  distinct: '',
@@ -41,10 +75,19 @@ class Db extends Context
41
75
  return this;
42
76
  }
43
77
 
78
+ /**
79
+ * 连接数据库连接池
80
+ * @public
81
+ * @param {(string|PoolConfig)} options - 数据库配置标识或连接参数
82
+ * @returns {this}
83
+ */
44
84
  connect(options='default') {
45
85
  this._config = typeof options === 'string' ? cfg_db[options] : options;
46
86
  this.reset();
47
87
 
88
+ /**
89
+ * @type {Pool}
90
+ */
48
91
  let cur_pool = pool.get(this._config);
49
92
  if(!cur_pool) {
50
93
  switch(this._config.type) {
@@ -62,6 +105,11 @@ class Db extends Context
62
105
  return this;
63
106
  }
64
107
 
108
+ /**
109
+ * 关闭数据库连接池
110
+ * @public
111
+ * @returns {Promise}
112
+ */
65
113
  async close() {
66
114
  return new Promise((resolve, reject) => {
67
115
  pool.has(this._config) && pool.get(this._config).end(err => {
@@ -79,6 +127,11 @@ class Db extends Context
79
127
  });
80
128
  }
81
129
 
130
+ /**
131
+ * 释放数据库连接
132
+ * @public
133
+ * @param {PoolConnection} conn - 数据库连接
134
+ */
82
135
  release(conn) {
83
136
  try {
84
137
  conn.release();
@@ -90,6 +143,12 @@ class Db extends Context
90
143
  }
91
144
  }
92
145
 
146
+ /**
147
+ * 获取数据库连接
148
+ * @private
149
+ * @param {Pool} p
150
+ * @returns {Promise}
151
+ */
93
152
  async _creatConnect(p) {
94
153
  return new Promise((resolve, reject) => {
95
154
  p.getConnection((err, connection) => {
@@ -106,10 +165,21 @@ class Db extends Context
106
165
  });
107
166
  }
108
167
 
168
+ /**
169
+ * 获取数据库连接
170
+ * @private
171
+ * @returns {Promise<PoolConnection>}
172
+ */
109
173
  async _getConnect() {
110
174
  return trans.get(this.ctx) || await this._creatConnect(pool.get(this._config));
111
175
  }
112
176
 
177
+ /**
178
+ * 开启事务
179
+ * @public
180
+ * @param {function} [fun]
181
+ * @returns {Promise<string>}
182
+ */
113
183
  async startTrans(fun) {
114
184
  const conn = await this._getConnect();
115
185
  trans.set(this.ctx, conn);
@@ -156,6 +226,11 @@ class Db extends Context
156
226
  });
157
227
  }
158
228
 
229
+ /**
230
+ * 事务回滚
231
+ * @public
232
+ * @returns {Promise<string>}
233
+ */
159
234
  async rollback() {
160
235
  const conn = await this._getConnect();
161
236
  const trans_nest = nest.get(conn) || 0;
@@ -179,6 +254,11 @@ class Db extends Context
179
254
  });
180
255
  }
181
256
 
257
+ /**
258
+ * 提交事务
259
+ * @public
260
+ * @returns {Promise<string>}
261
+ */
182
262
  async commit() {
183
263
  const conn = await this._getConnect();
184
264
  const trans_nest = nest.get(conn) || 0;
@@ -210,10 +290,21 @@ class Db extends Context
210
290
  });
211
291
  }
212
292
 
293
+ /**
294
+ * 执行sql查询
295
+ * @public
296
+ * @param {string} sql - sql语句或参数
297
+ * @param {*} params - sql参数
298
+ * @param {*} [reset=true] - 是否重置参数
299
+ * @returns {Promise}
300
+ */
213
301
  async query(sql, params, reset=true) {
214
302
  params !== false && reset !== false && this.reset();
215
303
  params || (params = []);
216
304
 
305
+ /**
306
+ * @type {PoolConnection}
307
+ */
217
308
  const conn = await this._getConnect();
218
309
 
219
310
  return new Promise((resolve, reject) => {
@@ -234,6 +325,12 @@ class Db extends Context
234
325
  });
235
326
  }
236
327
 
328
+ /**
329
+ * 设置数据表名
330
+ * @public
331
+ * @param {string} [table] - 表名字,不带前缀
332
+ * @returns {this}
333
+ */
237
334
  table(table) {
238
335
  if(table) {
239
336
  this._table = table.trim().replace(/ +/g, ' ');
@@ -241,6 +338,12 @@ class Db extends Context
241
338
  return this;
242
339
  }
243
340
 
341
+ /**
342
+ * 设置数据表名前缀
343
+ * @public
344
+ * @param {string} prefix - 表名前缀
345
+ * @returns {this}
346
+ */
244
347
  prefix(prefix) {
245
348
  if(typeof prefix !== 'undefined') {
246
349
  this._options.prefix = prefix.trim();
@@ -248,11 +351,21 @@ class Db extends Context
248
351
  return this;
249
352
  }
250
353
 
354
+ /**
355
+ * 设置distinct查询
356
+ * @returns {this}
357
+ */
251
358
  distinct() {
252
359
  this._options.distinct = 'distinct';
253
360
  return this;
254
361
  }
255
362
 
363
+ /**
364
+ * 设置查询字段,支持多次调用
365
+ * @public
366
+ * @param {(string|array)} field - 表名前缀
367
+ * @returns {this}
368
+ */
256
369
  field(field) {
257
370
  if(field) {
258
371
  if(typeof field === 'string') {
@@ -263,6 +376,14 @@ class Db extends Context
263
376
  return this;
264
377
  }
265
378
 
379
+ /**
380
+ * 设置表连接,支持多次调用
381
+ * @public
382
+ * @param {string} table - 要连接的表名
383
+ * @param {string} on - 连接条件
384
+ * @param {string} [type=left] - 连接方式
385
+ * @returns {this}
386
+ */
266
387
  join(table, on, type='left') {
267
388
  if(table) {
268
389
  this._options.join[table.trim().replace(/ +/g, ' ')] = {on, type};
@@ -270,6 +391,13 @@ class Db extends Context
270
391
  return this;
271
392
  }
272
393
 
394
+ /**
395
+ * 设置查询条件,支持多次调用
396
+ * @public
397
+ * @param {object} where - 查询条件
398
+ * @param {object} [logic] - 多次调用之间的连接逻辑,默认and
399
+ * @returns {this}
400
+ */
273
401
  where(where, logic) {
274
402
  if(where) {
275
403
  this._options.where.push([where, logic]);
@@ -277,6 +405,12 @@ class Db extends Context
277
405
  return this;
278
406
  }
279
407
 
408
+ /**
409
+ * 设置分组查询
410
+ * @public
411
+ * @param {string} field - 分组字段
412
+ * @returns {this}
413
+ */
280
414
  group(field) {
281
415
  if(field) {
282
416
  this._options.group = 'group by `' + field.trim().replace(/\./g, '`.`') + '`';
@@ -284,13 +418,26 @@ class Db extends Context
284
418
  return this;
285
419
  }
286
420
 
287
- having(condition) {
288
- if(condition) {
289
- this._options.having = 'having ' + condition;
421
+ /**
422
+ * 设置having筛选
423
+ * @public
424
+ * @param {string} having - 筛选条件
425
+ * @returns {this}
426
+ */
427
+ having(having) {
428
+ if(having) {
429
+ this._options.having = 'having ' + having;
290
430
  }
291
431
  return this;
292
432
  }
293
433
 
434
+ /**
435
+ * 设置排序方式,支持多次调用
436
+ * @public
437
+ * @param {string} field - 排序字段
438
+ * @param {string} [order] - 排序方式,默认asc
439
+ * @returns {this}
440
+ */
294
441
  order(field, order='asc') {
295
442
  if(field) {
296
443
  this._options.order[field.trim()] = order === 'asc' ? 'asc' : 'desc';
@@ -298,33 +445,65 @@ class Db extends Context
298
445
  return this;
299
446
  }
300
447
 
448
+ /**
449
+ * 设置查询数量
450
+ * @public
451
+ * @param {number} offset - 开始位置
452
+ * @param {number} [rows] - 行数,不传,则按offset
453
+ * @returns {this}
454
+ */
301
455
  limit(offset, rows) {
302
456
  if(typeof offset === 'undefined') return this;
303
- offset = offset ? parseInt(offset) : 0;
304
- rows = rows ? parseInt(rows) : null;
457
+ offset = offset ? offset : 0;
458
+ rows = rows ? rows : null;
305
459
  this._options.limit = 'limit ' + offset + (rows ? ',' + rows : '');
306
460
  return this;
307
461
  }
308
462
 
463
+ /**
464
+ * 按分页设置查询数量
465
+ * @public
466
+ * @param {number} page - 页码
467
+ * @param {number} pageSize - 每页行数
468
+ * @returns {this}
469
+ */
309
470
  page(page, pageSize) {
310
471
  if(typeof page === 'undefined') return this;
311
- page = page ? parseInt(page) : 1;
312
- pageSize = pageSize ? parseInt(pageSize) : 10;
472
+ page = page ? page : 1;
473
+ pageSize = pageSize ? pageSize : 10;
313
474
  this.limit((page - 1) * pageSize, pageSize);
314
475
  this._options.page = {page, pageSize};
315
476
  return this;
316
477
  }
317
478
 
479
+ /**
480
+ * 设置查询结果缓存
481
+ * @public
482
+ * @param {number} time - 为0则不缓存
483
+ * @returns {this}
484
+ */
318
485
  cache(time) {
319
486
  this._options.cache_time = time;
320
487
  return this;
321
488
  }
322
489
 
490
+ /**
491
+ * 设置返回sql语句(最终会返回序列化后的sql,不会真实查询数据库)
492
+ * @public
493
+ * @param {boolean} [fetch] - 是否返回sql
494
+ * @returns {this}
495
+ */
323
496
  getSql(fetch = true) {
324
497
  this._options.getSql = fetch;
325
498
  return this;
326
499
  }
327
500
 
501
+ /**
502
+ * 设置字段过滤(插入或更新数据时)
503
+ * @public
504
+ * @param {(boolean|string|string[])} [field] - 允许保存字段,为true,则按数据表字段
505
+ * @returns {this}
506
+ */
328
507
  allowField(field = true) {
329
508
  if(!field) {
330
509
  field = false;
@@ -335,6 +514,12 @@ class Db extends Context
335
514
  return this;
336
515
  }
337
516
 
517
+ /**
518
+ * 设置要插入或更新的数据
519
+ * @public
520
+ * @param {object} data - 要插入或更新的数据
521
+ * @returns {this}
522
+ */
338
523
  data(data) {
339
524
  if(data) {
340
525
  this._options.data = {...this._options.data, ...data};
@@ -342,6 +527,12 @@ class Db extends Context
342
527
  return this;
343
528
  }
344
529
 
530
+ /**
531
+ * 获取多条数据
532
+ * @public
533
+ * @param {object} condition - 查询条件
534
+ * @returns {Promise<(string|ListData)>}
535
+ */
345
536
  async select(condition) {
346
537
  condition && (this._options.where = [], this._options.where.push([condition]));
347
538
 
@@ -379,9 +570,15 @@ class Db extends Context
379
570
  return result;
380
571
  }
381
572
 
382
- return await this.query(this._queryStr, params);
573
+ return await this.query(this._queryStr, params) || [];
383
574
  }
384
575
 
576
+ /**
577
+ * 获取一条数据
578
+ * @public
579
+ * @param {object} condition - 查询条件
580
+ * @returns {Promise<(RowData|null)>}
581
+ */
385
582
  async find(condition) {
386
583
  condition && (this._options.where = [], this._options.where.push([condition]));
387
584
  this.limit(1);
@@ -394,6 +591,12 @@ class Db extends Context
394
591
  return rows.length ? rows[0] : null;
395
592
  }
396
593
 
594
+ /**
595
+ * 获取一个字段值
596
+ * @public
597
+ * @param {string} field - 字段
598
+ * @returns {Promise<(string|number|null)>}
599
+ */
397
600
  async value(field) {
398
601
  this._options.field = [];
399
602
  this.field(field);
@@ -406,26 +609,63 @@ class Db extends Context
406
609
  return row && row[field];
407
610
  }
408
611
 
612
+ /**
613
+ * 获取总数
614
+ * @public
615
+ * @param {string} [field] - 字段
616
+ * @returns {Promise<(string|number|0)>}
617
+ */
409
618
  async count(field='*') {
410
- return await this.value(`count(${field})`);
619
+ return await this.value(`count(${field})`) || 0;
411
620
  }
412
621
 
622
+ /**
623
+ * 获取字段最大值
624
+ * @public
625
+ * @param {string} field - 字段
626
+ * @returns {Promise<(string|number|0)>}
627
+ */
413
628
  async max(field) {
414
629
  return await this.value(`max(${field})`);
415
630
  }
416
631
 
632
+ /**
633
+ * 获取字段最小值
634
+ * @public
635
+ * @param {string} field - 字段
636
+ * @returns {Promise<(string|number|0)>}
637
+ */
417
638
  async min(field) {
418
639
  return await this.value(`min(${field})`);
419
640
  }
420
641
 
642
+ /**
643
+ * 获取字段平均值
644
+ * @public
645
+ * @param {string} field - 字段
646
+ * @returns {Promise<(string|number|0)>}
647
+ */
421
648
  async avg(field) {
422
649
  return await this.value(`avg(${field})`);
423
650
  }
424
651
 
652
+ /**
653
+ * 获取字段总和
654
+ * @public
655
+ * @param {string} field - 字段
656
+ * @returns {Promise<(string|number|0)>}
657
+ */
425
658
  async sum(field) {
426
659
  return await this.value(`sum(${field})`);
427
660
  }
428
661
 
662
+ /**
663
+ * 获取字段列数据
664
+ * @public
665
+ * @param {string} field - 数据字段
666
+ * @param {string} [key] - key字段,不设置返回数据数组,设置则返回{key: field}对象数组
667
+ * @returns {Promise<(string|ListData|object)>}
668
+ */
429
669
  async column(field, key) {
430
670
  this._options.field = [];
431
671
  this.field(field);
@@ -435,7 +675,7 @@ class Db extends Context
435
675
  return await this.select();
436
676
  }
437
677
 
438
- const rows = await this.select();
678
+ const rows = /** @type {ListData} */(await this.select());
439
679
  const result = key ? {} : [];
440
680
  rows.forEach(row => {
441
681
  if(key) {
@@ -447,18 +687,31 @@ class Db extends Context
447
687
  return result;
448
688
  }
449
689
 
690
+ /**
691
+ * 获取多条数据(按分页)
692
+ * @public
693
+ * @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]
698
+ */
450
699
  async pagination({page, page_size, pagination} = {}) {
451
700
  !page && (page = this._options.page.page);
452
701
  !page_size && (page_size = this._options.page.pageSize);
453
702
  if(!pagination) {
454
- pagination = this.$pagination.__node.isClass ? this.$pagination : this.$.pagination;
703
+ pagination = this.$pagination.__node && this.$pagination.__node.isClass ? this.$pagination : this.$.pagination;
455
704
  }
456
705
 
457
706
  const options = {...this._options}; // 暂存options
707
+ // @ts-ignore
458
708
  const total = await this.count();
709
+ // @ts-ignore
459
710
  pagination.total(total);
460
711
 
712
+ // @ts-ignore
461
713
  page ? pagination.page(page) : (page = pagination.page());
714
+ // @ts-ignore
462
715
  page_size ? pagination.pageSize(page_size) : (page_size = pagination.pageSize());
463
716
 
464
717
  if(total) {
@@ -470,6 +723,12 @@ class Db extends Context
470
723
  }
471
724
  }
472
725
 
726
+ /**
727
+ * 插入一条数据
728
+ * @public
729
+ * @param {object} data - 待插入数据
730
+ * @returns {Promise<(string|OkPacket)>}
731
+ */
473
732
  async insert(data) {
474
733
  data && (this._options.data = data);
475
734
 
@@ -489,6 +748,13 @@ class Db extends Context
489
748
  return await this.query(this._queryStr, params);
490
749
  }
491
750
 
751
+ /**
752
+ * 更新数据
753
+ * @public
754
+ * @param {object} data - 更新数据
755
+ * @param {object} condition - 更新条件
756
+ * @returns {Promise<(string|OkPacket)>}
757
+ */
492
758
  async update(data, condition) {
493
759
  data && (this._options.data = data);
494
760
  condition && (this._options.where = [], this._options.where.push([condition]));
@@ -517,18 +783,45 @@ class Db extends Context
517
783
  return await this.query(this._queryStr, params);
518
784
  }
519
785
 
786
+ /**
787
+ * 字段值增加
788
+ * @public
789
+ * @param {string} field - 字段
790
+ * @param {number} [step=1] - 增加值,默认1
791
+ * @returns {Promise<(string|OkPacket)>}
792
+ */
520
793
  async inc(field, step) {
521
794
  return await this.update({[field]: ['inc', step]});
522
795
  }
523
796
 
797
+ /**
798
+ * 字段值减少
799
+ * @public
800
+ * @param {string} field - 字段
801
+ * @param {number} [step=1] - 减少值,默认1
802
+ * @returns {Promise<(string|OkPacket)>}
803
+ */
524
804
  async dec(field, step) {
525
805
  return await this.update({[field]: ['dec', step]});
526
806
  }
527
807
 
808
+ /**
809
+ * 字段值执行自定义表达式
810
+ * @public
811
+ * @param {string} field - 字段
812
+ * @param {string} value - 自定义表达式
813
+ * @returns {Promise<(string|OkPacket)>}
814
+ */
528
815
  async exp(field, value) {
529
816
  return await this.update({[field]: ['exp', value]});
530
817
  }
531
818
 
819
+ /**
820
+ * 删除数据
821
+ * @public
822
+ * @param {object} condition - 山粗条件
823
+ * @returns {Promise<(string|OkPacket)>}
824
+ */
532
825
  async delete(condition) {
533
826
  condition && (this._options.where = [], this._options.where.push([condition]));
534
827
 
@@ -550,6 +843,14 @@ class Db extends Context
550
843
  return await this.query(this._queryStr, params);
551
844
  }
552
845
 
846
+ /**
847
+ * 执行sql查询
848
+ * @public
849
+ * @param {string} sql - sql语句或参数
850
+ * @param {*} params - sql参数
851
+ * @param {*} [reset=true] - 是否重置参数
852
+ * @returns {Promise<(string|OkPacket|ListData|RowData)>}
853
+ */
553
854
  async execute(sql, params, reset=true) {
554
855
  this._queryStr = sql;
555
856
  if(this._options.getSql) {
@@ -570,6 +871,12 @@ class Db extends Context
570
871
  return await this.query(this._queryStr, params, reset);
571
872
  }
572
873
 
874
+ /**
875
+ * 获取数据表信息
876
+ * @public
877
+ * @param {string} table - 表名字
878
+ * @returns {Promise<FieldInfo[]>}
879
+ */
573
880
  async tableInfo(table) {
574
881
  const get_sql = this._options.getSql;
575
882
  this._options.getSql = false;
@@ -578,11 +885,24 @@ class Db extends Context
578
885
  return table_info;
579
886
  }
580
887
 
888
+ /**
889
+ * 获取数据表字段
890
+ * @public
891
+ * @param {string} [table] - 表名字
892
+ * @returns {Promise<string[]>}
893
+ */
581
894
  async tableField(table) {
582
895
  const table_info = await this.tableInfo(table);
583
896
  return table_info.map(item => item.Field);
584
897
  }
585
898
 
899
+ /**
900
+ * 序列化sql语句
901
+ * @public
902
+ * @param {string} sql - sql语句或参数
903
+ * @param {*} params - sql参数
904
+ * @returns {string}
905
+ */
586
906
  format(sql, params) {
587
907
  params || (params = []);
588
908
  return require('mysql').format(sql, params);
@@ -740,20 +1060,41 @@ class Db extends Context
740
1060
  return this._options.data;
741
1061
  }
742
1062
 
1063
+ /**
1064
+ * 获取sql缓存
1065
+ * @param {string} key
1066
+ * @returns {*}
1067
+ */
743
1068
  getCache(key) {
744
1069
  return Db.cache.get(key);
745
1070
  }
746
1071
 
1072
+ /**
1073
+ * 设置sql缓存
1074
+ * @param {string} key
1075
+ */
747
1076
  setCache(key, data, cache_time) {
748
1077
  Db.cache.set(key, data, cache_time);
749
1078
  }
750
1079
 
1080
+ /**
1081
+ * 删除sql缓存
1082
+ * @param {string} key
1083
+ */
751
1084
  deleteCache(key) {
752
1085
  Db.cache.delete(key);
753
1086
  }
754
1087
  }
755
1088
 
1089
+ /**
1090
+ * 设置数据库缓存实例
1091
+ * @type {typeof import('./cache')}
1092
+ */
1093
+ // @ts-ignore
756
1094
  Db.cache = new (require('./cache'))();
1095
+ /**
1096
+ * 开启缓存自动清理
1097
+ */
757
1098
  Db.cache.setIntervalTime(20 * 60 * 60);
758
1099
 
759
1100
  module.exports = Db;