@naturalcycles/db-lib 8.38.1 → 8.40.1

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.
@@ -4,6 +4,7 @@ exports.queryInMemory = void 0;
4
4
  const js_lib_1 = require("@naturalcycles/js-lib");
5
5
  const FILTER_FNS = {
6
6
  '==': (v, val) => v === val,
7
+ '!=': (v, val) => v !== val,
7
8
  '<': (v, val) => v < val,
8
9
  '<=': (v, val) => v <= val,
9
10
  '>': (v, val) => v > val,
@@ -28,6 +28,7 @@ class CommonDao {
28
28
  logLevel: isGAE || isCI ? common_dao_model_1.CommonDaoLogLevel.NONE : common_dao_model_1.CommonDaoLogLevel.OPERATIONS,
29
29
  idType: 'string',
30
30
  createId: true,
31
+ assignGeneratedIds: false,
31
32
  created: true,
32
33
  updated: true,
33
34
  logger: console,
@@ -450,7 +451,7 @@ class CommonDao {
450
451
  */
451
452
  async save(bm, opt = {}) {
452
453
  this.requireWriteAccess();
453
- const idWasGenerated = !bm.id;
454
+ const idWasGenerated = !bm.id && this.cfg.createId;
454
455
  this.assignIdCreatedUpdated(bm, opt); // mutates
455
456
  const dbm = await this.bmToDBM(bm, opt);
456
457
  const table = opt.table || this.cfg.table;
@@ -461,10 +462,16 @@ class CommonDao {
461
462
  }
462
463
  const op = `save(${dbm.id})`;
463
464
  const started = this.logSaveStarted(op, bm, table);
465
+ const { excludeFromIndexes } = this.cfg;
466
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
464
467
  await this.cfg.db.saveBatch(table, [dbm], {
465
- excludeFromIndexes: this.cfg.excludeFromIndexes,
468
+ excludeFromIndexes,
469
+ assignGeneratedIds,
466
470
  ...opt,
467
471
  });
472
+ if (assignGeneratedIds) {
473
+ bm.id = dbm.id;
474
+ }
468
475
  this.logSaveResult(started, op, table);
469
476
  return bm;
470
477
  }
@@ -495,24 +502,31 @@ class CommonDao {
495
502
  const table = opt.table || this.cfg.table;
496
503
  // assigning id in case it misses the id
497
504
  // will override/set `updated` field, unless opts.preserveUpdated is set
505
+ let row = dbm;
498
506
  if (!opt.raw) {
499
- const idWasGenerated = !dbm.id;
507
+ const idWasGenerated = !dbm.id && this.cfg.createId;
500
508
  this.assignIdCreatedUpdated(dbm, opt); // mutates
501
- dbm = this.anyToDBM(dbm, opt);
509
+ row = this.anyToDBM(dbm, opt);
502
510
  if (opt.ensureUniqueId && idWasGenerated)
503
- await this.ensureUniqueId(table, dbm);
511
+ await this.ensureUniqueId(table, row);
504
512
  }
505
513
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
506
514
  opt = { ...opt, saveMethod: 'insert' };
507
515
  }
508
- const op = `saveAsDBM(${dbm.id})`;
509
- const started = this.logSaveStarted(op, dbm, table);
510
- await this.cfg.db.saveBatch(table, [dbm], {
511
- excludeFromIndexes: this.cfg.excludeFromIndexes,
516
+ const op = `saveAsDBM(${row.id})`;
517
+ const started = this.logSaveStarted(op, row, table);
518
+ const { excludeFromIndexes } = this.cfg;
519
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
520
+ await this.cfg.db.saveBatch(table, [row], {
521
+ excludeFromIndexes,
522
+ assignGeneratedIds,
512
523
  ...opt,
513
524
  });
525
+ if (assignGeneratedIds) {
526
+ dbm.id = row.id;
527
+ }
514
528
  this.logSaveResult(started, op, table);
515
- return dbm;
529
+ return row;
516
530
  }
517
531
  async saveBatch(bms, opt = {}) {
518
532
  this.requireWriteAccess();
@@ -529,36 +543,49 @@ class CommonDao {
529
543
  .map(bm => bm.id)
530
544
  .join(', '), 50)})`;
531
545
  const started = this.logSaveStarted(op, bms, table);
546
+ const { excludeFromIndexes } = this.cfg;
547
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
532
548
  await this.cfg.db.saveBatch(table, dbms, {
533
- excludeFromIndexes: this.cfg.excludeFromIndexes,
549
+ excludeFromIndexes,
550
+ assignGeneratedIds,
534
551
  ...opt,
535
552
  });
553
+ if (assignGeneratedIds) {
554
+ dbms.forEach((dbm, i) => (bms[i].id = dbm.id));
555
+ }
536
556
  this.logSaveResult(started, op, table);
537
557
  return bms;
538
558
  }
539
559
  async saveBatchAsDBM(dbms, opt = {}) {
540
560
  this.requireWriteAccess();
541
561
  const table = opt.table || this.cfg.table;
562
+ let rows = dbms;
542
563
  if (!opt.raw) {
543
564
  dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt)); // mutates
544
- dbms = this.anyToDBMs(dbms, opt);
565
+ rows = this.anyToDBMs(dbms, opt);
545
566
  if (opt.ensureUniqueId)
546
567
  throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
547
568
  }
548
569
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
549
570
  opt = { ...opt, saveMethod: 'insert' };
550
571
  }
551
- const op = `saveBatchAsDBM ${dbms.length} row(s) (${(0, js_lib_1._truncate)(dbms
572
+ const op = `saveBatchAsDBM ${rows.length} row(s) (${(0, js_lib_1._truncate)(rows
552
573
  .slice(0, 10)
553
574
  .map(bm => bm.id)
554
575
  .join(', '), 50)})`;
555
- const started = this.logSaveStarted(op, dbms, table);
556
- await this.cfg.db.saveBatch(table, dbms, {
557
- excludeFromIndexes: this.cfg.excludeFromIndexes,
576
+ const started = this.logSaveStarted(op, rows, table);
577
+ const { excludeFromIndexes } = this.cfg;
578
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds;
579
+ await this.cfg.db.saveBatch(table, rows, {
580
+ excludeFromIndexes,
581
+ assignGeneratedIds,
558
582
  ...opt,
559
583
  });
584
+ if (assignGeneratedIds) {
585
+ rows.forEach((row, i) => (dbms[i].id = row.id));
586
+ }
560
587
  this.logSaveResult(started, op, table);
561
- return dbms;
588
+ return rows;
562
589
  }
563
590
  async deleteById(id, opt = {}) {
564
591
  if (!id)
@@ -86,6 +86,11 @@ export interface CommonDaoCfg<BM extends Partial<ObjectWithId<ID>>, DBM extends
86
86
  * Useful e.g when your DB is generating ids by itself (e.g mysql auto_increment).
87
87
  */
88
88
  createId?: boolean;
89
+ /**
90
+ * See the same option in CommonDB.
91
+ * Defaults to false normally.
92
+ */
93
+ assignGeneratedIds?: boolean;
89
94
  /**
90
95
  * Defaults to true
91
96
  * Set to false to disable `created` field management.
@@ -19,6 +19,13 @@ export interface CommonDBSaveOptions<ROW extends Partial<ObjectWithId> = AnyObje
19
19
  * Default is `upsert`
20
20
  */
21
21
  saveMethod?: CommonDBSaveMethod;
22
+ /**
23
+ * Only applicable to tables where id is "auto-generated by DB", e.g `auto_increment` in MySQL.
24
+ * By default it's false, so, auto-generated id will NOT be assigned/returned.
25
+ * Setting it to true will assign and return auto-generated id (on all rows, one by one).
26
+ * It's not true by default, because getting auto-generated id incurs an overhead of doing extra call (e.g LAST_INSERT_ID() in MySQL).
27
+ */
28
+ assignGeneratedIds?: boolean;
22
29
  }
23
30
  export declare type CommonDBStreamOptions = CommonDBOptions;
24
31
  export interface CommonDBCreateOptions extends CommonDBOptions {
@@ -22,8 +22,8 @@ import { RunQueryResult } from '../db.model';
22
22
  *
23
23
  * You may also look at queryInMemory() for its implementation (it implements all those).
24
24
  */
25
- export declare type DBQueryFilterOperator = '<' | '<=' | '==' | '>=' | '>' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
26
- export declare const dbQueryFilterOperatorValues: string[];
25
+ export declare type DBQueryFilterOperator = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'in' | 'not-in' | 'array-contains' | 'array-contains-any';
26
+ export declare const dbQueryFilterOperatorValues: DBQueryFilterOperator[];
27
27
  export interface DBQueryFilter<ROW extends ObjectWithId = AnyObjectWithId> {
28
28
  name: keyof ROW;
29
29
  op: DBQueryFilterOperator;
@@ -6,6 +6,7 @@ exports.dbQueryFilterOperatorValues = [
6
6
  '<',
7
7
  '<=',
8
8
  '==',
9
+ '!=',
9
10
  '>=',
10
11
  '>',
11
12
  'in',
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "@naturalcycles/bench-lib": "^1.0.0",
13
13
  "@naturalcycles/dev-lib": "^12.0.1",
14
14
  "@types/node": "^17.0.0",
15
- "jest": "^27.0.3",
15
+ "jest": "^28.0.3",
16
16
  "weak-napi": "^2.0.2"
17
17
  },
18
18
  "files": [
@@ -42,7 +42,7 @@
42
42
  "engines": {
43
43
  "node": ">=14.15"
44
44
  },
45
- "version": "8.38.1",
45
+ "version": "8.40.1",
46
46
  "description": "Lowest Common Denominator API to supported Databases",
47
47
  "keywords": [
48
48
  "db",
@@ -4,6 +4,7 @@ import { DBQuery, DBQueryFilterOperator } from '../../query/dbQuery'
4
4
  type FilterFn = (v: any, val: any) => boolean
5
5
  const FILTER_FNS: Record<DBQueryFilterOperator, FilterFn> = {
6
6
  '==': (v, val) => v === val,
7
+ '!=': (v, val) => v !== val,
7
8
  '<': (v, val) => v < val,
8
9
  '<=': (v, val) => v <= val,
9
10
  '>': (v, val) => v > val,
@@ -119,6 +119,12 @@ export interface CommonDaoCfg<
119
119
  */
120
120
  createId?: boolean
121
121
 
122
+ /**
123
+ * See the same option in CommonDB.
124
+ * Defaults to false normally.
125
+ */
126
+ assignGeneratedIds?: boolean
127
+
122
128
  /**
123
129
  * Defaults to true
124
130
  * Set to false to disable `created` field management.
@@ -73,6 +73,7 @@ export class CommonDao<
73
73
  logLevel: isGAE || isCI ? CommonDaoLogLevel.NONE : CommonDaoLogLevel.OPERATIONS,
74
74
  idType: 'string',
75
75
  createId: true,
76
+ assignGeneratedIds: false,
76
77
  created: true,
77
78
  updated: true,
78
79
  logger: console,
@@ -609,7 +610,7 @@ export class CommonDao<
609
610
  */
610
611
  async save(bm: Unsaved<BM>, opt: CommonDaoSaveOptions<DBM> = {}): Promise<Saved<BM>> {
611
612
  this.requireWriteAccess()
612
- const idWasGenerated = !bm.id
613
+ const idWasGenerated = !bm.id && this.cfg.createId
613
614
  this.assignIdCreatedUpdated(bm, opt) // mutates
614
615
  const dbm = await this.bmToDBM(bm as BM, opt)
615
616
  const table = opt.table || this.cfg.table
@@ -619,11 +620,18 @@ export class CommonDao<
619
620
  }
620
621
  const op = `save(${dbm.id})`
621
622
  const started = this.logSaveStarted(op, bm, table)
623
+ const { excludeFromIndexes } = this.cfg
624
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
622
625
  await this.cfg.db.saveBatch(table, [dbm], {
623
- excludeFromIndexes: this.cfg.excludeFromIndexes,
626
+ excludeFromIndexes,
627
+ assignGeneratedIds,
624
628
  ...opt,
625
629
  })
626
630
 
631
+ if (assignGeneratedIds) {
632
+ bm.id = dbm.id as any
633
+ }
634
+
627
635
  this.logSaveResult(started, op, table)
628
636
  return bm as any
629
637
  }
@@ -666,23 +674,32 @@ export class CommonDao<
666
674
 
667
675
  // assigning id in case it misses the id
668
676
  // will override/set `updated` field, unless opts.preserveUpdated is set
677
+ let row = dbm
669
678
  if (!opt.raw) {
670
- const idWasGenerated = !dbm.id
679
+ const idWasGenerated = !dbm.id && this.cfg.createId
671
680
  this.assignIdCreatedUpdated(dbm, opt) // mutates
672
- dbm = this.anyToDBM(dbm, opt)
673
- if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, dbm)
681
+ row = this.anyToDBM(dbm, opt)
682
+ if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, row)
674
683
  }
675
684
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
676
685
  opt = { ...opt, saveMethod: 'insert' }
677
686
  }
678
- const op = `saveAsDBM(${dbm.id})`
679
- const started = this.logSaveStarted(op, dbm, table)
680
- await this.cfg.db.saveBatch(table, [dbm], {
681
- excludeFromIndexes: this.cfg.excludeFromIndexes,
687
+ const op = `saveAsDBM(${row.id})`
688
+ const started = this.logSaveStarted(op, row, table)
689
+ const { excludeFromIndexes } = this.cfg
690
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
691
+ await this.cfg.db.saveBatch(table, [row], {
692
+ excludeFromIndexes,
693
+ assignGeneratedIds,
682
694
  ...opt,
683
695
  })
696
+
697
+ if (assignGeneratedIds) {
698
+ dbm.id = row.id
699
+ }
700
+
684
701
  this.logSaveResult(started, op, table)
685
- return dbm
702
+ return row
686
703
  }
687
704
 
688
705
  async saveBatch(bms: Unsaved<BM>[], opt: CommonDaoSaveOptions<DBM> = {}): Promise<Saved<BM>[]> {
@@ -703,12 +720,19 @@ export class CommonDao<
703
720
  50,
704
721
  )})`
705
722
  const started = this.logSaveStarted(op, bms, table)
723
+ const { excludeFromIndexes } = this.cfg
724
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
706
725
 
707
726
  await this.cfg.db.saveBatch(table, dbms, {
708
- excludeFromIndexes: this.cfg.excludeFromIndexes,
727
+ excludeFromIndexes,
728
+ assignGeneratedIds,
709
729
  ...opt,
710
730
  })
711
731
 
732
+ if (assignGeneratedIds) {
733
+ dbms.forEach((dbm, i) => (bms[i]!.id = dbm.id as any))
734
+ }
735
+
712
736
  this.logSaveResult(started, op, table)
713
737
 
714
738
  return bms as any[]
@@ -717,30 +741,38 @@ export class CommonDao<
717
741
  async saveBatchAsDBM(dbms: DBM[], opt: CommonDaoSaveOptions<DBM> = {}): Promise<DBM[]> {
718
742
  this.requireWriteAccess()
719
743
  const table = opt.table || this.cfg.table
744
+ let rows = dbms
720
745
  if (!opt.raw) {
721
746
  dbms.forEach(dbm => this.assignIdCreatedUpdated(dbm, opt)) // mutates
722
- dbms = this.anyToDBMs(dbms, opt)
747
+ rows = this.anyToDBMs(dbms, opt)
723
748
  if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
724
749
  }
725
750
  if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
726
751
  opt = { ...opt, saveMethod: 'insert' }
727
752
  }
728
- const op = `saveBatchAsDBM ${dbms.length} row(s) (${_truncate(
729
- dbms
753
+ const op = `saveBatchAsDBM ${rows.length} row(s) (${_truncate(
754
+ rows
730
755
  .slice(0, 10)
731
756
  .map(bm => bm.id)
732
757
  .join(', '),
733
758
  50,
734
759
  )})`
735
- const started = this.logSaveStarted(op, dbms, table)
760
+ const started = this.logSaveStarted(op, rows, table)
761
+ const { excludeFromIndexes } = this.cfg
762
+ const assignGeneratedIds = opt.assignGeneratedIds || this.cfg.assignGeneratedIds
736
763
 
737
- await this.cfg.db.saveBatch(table, dbms, {
738
- excludeFromIndexes: this.cfg.excludeFromIndexes,
764
+ await this.cfg.db.saveBatch(table, rows, {
765
+ excludeFromIndexes,
766
+ assignGeneratedIds,
739
767
  ...opt,
740
768
  })
741
769
 
770
+ if (assignGeneratedIds) {
771
+ rows.forEach((row, i) => (dbms[i]!.id = row.id))
772
+ }
773
+
742
774
  this.logSaveResult(started, op, table)
743
- return dbms
775
+ return rows
744
776
  }
745
777
 
746
778
  // DELETE
package/src/db.model.ts CHANGED
@@ -24,6 +24,14 @@ export interface CommonDBSaveOptions<ROW extends Partial<ObjectWithId> = AnyObje
24
24
  * Default is `upsert`
25
25
  */
26
26
  saveMethod?: CommonDBSaveMethod
27
+
28
+ /**
29
+ * Only applicable to tables where id is "auto-generated by DB", e.g `auto_increment` in MySQL.
30
+ * By default it's false, so, auto-generated id will NOT be assigned/returned.
31
+ * Setting it to true will assign and return auto-generated id (on all rows, one by one).
32
+ * It's not true by default, because getting auto-generated id incurs an overhead of doing extra call (e.g LAST_INSERT_ID() in MySQL).
33
+ */
34
+ assignGeneratedIds?: boolean
27
35
  }
28
36
 
29
37
  export type CommonDBStreamOptions = CommonDBOptions
@@ -27,6 +27,7 @@ export type DBQueryFilterOperator =
27
27
  | '<'
28
28
  | '<='
29
29
  | '=='
30
+ | '!='
30
31
  | '>='
31
32
  | '>'
32
33
  | 'in'
@@ -34,10 +35,11 @@ export type DBQueryFilterOperator =
34
35
  | 'array-contains'
35
36
  | 'array-contains-any'
36
37
 
37
- export const dbQueryFilterOperatorValues = [
38
+ export const dbQueryFilterOperatorValues: DBQueryFilterOperator[] = [
38
39
  '<',
39
40
  '<=',
40
41
  '==',
42
+ '!=',
41
43
  '>=',
42
44
  '>',
43
45
  'in',