jj.js 0.8.8 → 0.10.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').KoaCtx} [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<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>}
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<*>}
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<number>}
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<number>}
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<number>}
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<number>}
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<number>}
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<(ListData|object)>}
668
+ */
429
669
  async column(field, key) {
430
670
  this._options.field = [];
431
671
  this.field(field);
@@ -447,18 +687,29 @@ 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
458
707
  const total = await this.count();
459
708
  pagination.total(total);
460
709
 
710
+ // @ts-ignore
461
711
  page ? pagination.page(page) : (page = pagination.page());
712
+ // @ts-ignore
462
713
  page_size ? pagination.pageSize(page_size) : (page_size = pagination.pageSize());
463
714
 
464
715
  if(total) {
@@ -470,6 +721,12 @@ class Db extends Context
470
721
  }
471
722
  }
472
723
 
724
+ /**
725
+ * 插入一条数据
726
+ * @public
727
+ * @param {object} data - 待插入数据
728
+ * @returns {Promise<OkPacket>}
729
+ */
473
730
  async insert(data) {
474
731
  data && (this._options.data = data);
475
732
 
@@ -489,6 +746,13 @@ class Db extends Context
489
746
  return await this.query(this._queryStr, params);
490
747
  }
491
748
 
749
+ /**
750
+ * 更新数据
751
+ * @public
752
+ * @param {object} data - 更新数据
753
+ * @param {object} condition - 更新条件
754
+ * @returns {Promise<OkPacket>}
755
+ */
492
756
  async update(data, condition) {
493
757
  data && (this._options.data = data);
494
758
  condition && (this._options.where = [], this._options.where.push([condition]));
@@ -517,18 +781,45 @@ class Db extends Context
517
781
  return await this.query(this._queryStr, params);
518
782
  }
519
783
 
784
+ /**
785
+ * 字段值增加
786
+ * @public
787
+ * @param {string} field - 字段
788
+ * @param {number} [step=1] - 增加值,默认1
789
+ * @returns {Promise<OkPacket>}
790
+ */
520
791
  async inc(field, step) {
521
792
  return await this.update({[field]: ['inc', step]});
522
793
  }
523
794
 
795
+ /**
796
+ * 字段值减少
797
+ * @public
798
+ * @param {string} field - 字段
799
+ * @param {number} [step=1] - 减少值,默认1
800
+ * @returns {Promise<OkPacket>}
801
+ */
524
802
  async dec(field, step) {
525
803
  return await this.update({[field]: ['dec', step]});
526
804
  }
527
805
 
806
+ /**
807
+ * 字段值执行自定义表达式
808
+ * @public
809
+ * @param {string} field - 字段
810
+ * @param {string} value - 自定义表达式
811
+ * @returns {Promise<OkPacket>}
812
+ */
528
813
  async exp(field, value) {
529
814
  return await this.update({[field]: ['exp', value]});
530
815
  }
531
816
 
817
+ /**
818
+ * 删除数据
819
+ * @public
820
+ * @param {object} condition - 山粗条件
821
+ * @returns {Promise<OkPacket>}
822
+ */
532
823
  async delete(condition) {
533
824
  condition && (this._options.where = [], this._options.where.push([condition]));
534
825
 
@@ -550,6 +841,14 @@ class Db extends Context
550
841
  return await this.query(this._queryStr, params);
551
842
  }
552
843
 
844
+ /**
845
+ * 执行sql查询
846
+ * @public
847
+ * @param {string} sql - sql语句或参数
848
+ * @param {*} params - sql参数
849
+ * @param {*} [reset=true] - 是否重置参数
850
+ * @returns {Promise<(OkPacket|ListData|RowData)>}
851
+ */
553
852
  async execute(sql, params, reset=true) {
554
853
  this._queryStr = sql;
555
854
  if(this._options.getSql) {
@@ -570,6 +869,12 @@ class Db extends Context
570
869
  return await this.query(this._queryStr, params, reset);
571
870
  }
572
871
 
872
+ /**
873
+ * 获取数据表信息
874
+ * @public
875
+ * @param {string} table - 表名字
876
+ * @returns {Promise<FieldInfo[]>}
877
+ */
573
878
  async tableInfo(table) {
574
879
  const get_sql = this._options.getSql;
575
880
  this._options.getSql = false;
@@ -578,11 +883,24 @@ class Db extends Context
578
883
  return table_info;
579
884
  }
580
885
 
886
+ /**
887
+ * 获取数据表字段
888
+ * @public
889
+ * @param {string} [table] - 表名字
890
+ * @returns {Promise<string[]>}
891
+ */
581
892
  async tableField(table) {
582
893
  const table_info = await this.tableInfo(table);
583
894
  return table_info.map(item => item.Field);
584
895
  }
585
896
 
897
+ /**
898
+ * 序列化sql语句
899
+ * @public
900
+ * @param {string} sql - sql语句或参数
901
+ * @param {*} params - sql参数
902
+ * @returns {string}
903
+ */
586
904
  format(sql, params) {
587
905
  params || (params = []);
588
906
  return require('mysql').format(sql, params);
@@ -740,20 +1058,41 @@ class Db extends Context
740
1058
  return this._options.data;
741
1059
  }
742
1060
 
1061
+ /**
1062
+ * 获取sql缓存
1063
+ * @param {string} [key]
1064
+ * @returns {*}
1065
+ */
743
1066
  getCache(key) {
744
1067
  return Db.cache.get(key);
745
1068
  }
746
1069
 
1070
+ /**
1071
+ * 设置sql缓存
1072
+ * @param {string} key
1073
+ */
747
1074
  setCache(key, data, cache_time) {
748
1075
  Db.cache.set(key, data, cache_time);
749
1076
  }
750
1077
 
1078
+ /**
1079
+ * 删除sql缓存
1080
+ * @param {string} [key]
1081
+ */
751
1082
  deleteCache(key) {
752
1083
  Db.cache.delete(key);
753
1084
  }
754
1085
  }
755
1086
 
1087
+ /**
1088
+ * 设置数据库缓存实例
1089
+ * @type {import('../types').Cache}
1090
+ */
1091
+ // @ts-ignore
756
1092
  Db.cache = new (require('./cache'))();
1093
+ /**
1094
+ * 开启缓存自动清理
1095
+ */
757
1096
  Db.cache.setIntervalTime(20 * 60 * 60);
758
1097
 
759
1098
  module.exports = Db;
package/lib/loader.js CHANGED
@@ -5,12 +5,17 @@ const {isFileSync, isDirSync} = require('./utils/fs');
5
5
  const nodeType = {};
6
6
 
7
7
  function loader(dir='./', ...args) {
8
- const node = {};
8
+ // @ts-ignore
9
+ dir = pt.isAbsolute(dir) ? dir : pt.join(pt.dirname(module.parent.filename), dir);
10
+ const dirPath = pt.join(dir, './');
11
+ const dirType = isFileSync(dir + '.js') ? 'file' : 'dir';
12
+ const node = dirType == 'file' ? require(dir) : {};
9
13
  const info = new Map();
10
14
  info.set(node, {
11
- path: pt.isAbsolute(dir) ? pt.join(dir, './') : pt.join(pt.dirname(module.parent.filename), dir, './'),
12
- nodeType: 'dir',
13
- isClass: false
15
+ path: dirPath,
16
+ nodeType: dirType,
17
+ // @ts-ignore
18
+ isClass: isClass(node)
14
19
  });
15
20
  return creatLoader(node);
16
21
 
@@ -51,6 +56,7 @@ function loader(dir='./', ...args) {
51
56
  info.set(_node, {
52
57
  path: _nodePath,
53
58
  nodeType: nodeType[_nodePath],
59
+ // @ts-ignore
54
60
  isClass: isClass(_node)
55
61
  });
56
62
  node[prop] = creatLoader(_node);