@naturalcycles/db-lib 8.38.0 → 8.40.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.
@@ -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,
@@ -410,7 +411,7 @@ class CommonDao {
410
411
  }
411
412
  async streamQueryIdsForEach(q, mapper, opt = {}) {
412
413
  q.table = opt.table || q.table;
413
- opt.errorMode = opt.errorMode || js_lib_1.ErrorMode.SUPPRESS;
414
+ opt.errorMode || (opt.errorMode = js_lib_1.ErrorMode.SUPPRESS);
414
415
  const op = `streamQueryIdsForEach(${q.pretty()})`;
415
416
  const started = this.logStarted(op, q.table, true);
416
417
  let count = 0;
@@ -450,19 +451,20 @@ 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;
457
458
  if (opt.ensureUniqueId && idWasGenerated)
458
459
  await this.ensureUniqueId(table, dbm);
459
- if (this.cfg.immutable && !opt.allowMutability) {
460
- opt.saveMethod || (opt.saveMethod = 'insert');
460
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
461
+ opt = { ...opt, saveMethod: 'insert' };
461
462
  }
462
463
  const op = `save(${dbm.id})`;
463
464
  const started = this.logSaveStarted(op, bm, table);
464
465
  await this.cfg.db.saveBatch(table, [dbm], {
465
466
  excludeFromIndexes: this.cfg.excludeFromIndexes,
467
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
466
468
  ...opt,
467
469
  });
468
470
  this.logSaveResult(started, op, table);
@@ -496,19 +498,20 @@ class CommonDao {
496
498
  // assigning id in case it misses the id
497
499
  // will override/set `updated` field, unless opts.preserveUpdated is set
498
500
  if (!opt.raw) {
499
- const idWasGenerated = !dbm.id;
501
+ const idWasGenerated = !dbm.id && this.cfg.createId;
500
502
  this.assignIdCreatedUpdated(dbm, opt); // mutates
501
503
  dbm = this.anyToDBM(dbm, opt);
502
504
  if (opt.ensureUniqueId && idWasGenerated)
503
505
  await this.ensureUniqueId(table, dbm);
504
506
  }
505
- if (this.cfg.immutable && !opt.allowMutability) {
506
- opt.saveMethod || (opt.saveMethod = 'insert');
507
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
508
+ opt = { ...opt, saveMethod: 'insert' };
507
509
  }
508
510
  const op = `saveAsDBM(${dbm.id})`;
509
511
  const started = this.logSaveStarted(op, dbm, table);
510
512
  await this.cfg.db.saveBatch(table, [dbm], {
511
513
  excludeFromIndexes: this.cfg.excludeFromIndexes,
514
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
512
515
  ...opt,
513
516
  });
514
517
  this.logSaveResult(started, op, table);
@@ -521,8 +524,8 @@ class CommonDao {
521
524
  const dbms = await this.bmsToDBM(bms, opt);
522
525
  if (opt.ensureUniqueId)
523
526
  throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
524
- if (this.cfg.immutable && !opt.allowMutability) {
525
- opt.saveMethod || (opt.saveMethod = 'insert');
527
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
528
+ opt = { ...opt, saveMethod: 'insert' };
526
529
  }
527
530
  const op = `saveBatch ${dbms.length} row(s) (${(0, js_lib_1._truncate)(dbms
528
531
  .slice(0, 10)
@@ -531,6 +534,7 @@ class CommonDao {
531
534
  const started = this.logSaveStarted(op, bms, table);
532
535
  await this.cfg.db.saveBatch(table, dbms, {
533
536
  excludeFromIndexes: this.cfg.excludeFromIndexes,
537
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
534
538
  ...opt,
535
539
  });
536
540
  this.logSaveResult(started, op, table);
@@ -545,8 +549,8 @@ class CommonDao {
545
549
  if (opt.ensureUniqueId)
546
550
  throw new js_lib_1.AppError('ensureUniqueId is not supported in saveBatch');
547
551
  }
548
- if (this.cfg.immutable && !opt.allowMutability) {
549
- opt.saveMethod || (opt.saveMethod = 'insert');
552
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
553
+ opt = { ...opt, saveMethod: 'insert' };
550
554
  }
551
555
  const op = `saveBatchAsDBM ${dbms.length} row(s) (${(0, js_lib_1._truncate)(dbms
552
556
  .slice(0, 10)
@@ -555,6 +559,7 @@ class CommonDao {
555
559
  const started = this.logSaveStarted(op, dbms, table);
556
560
  await this.cfg.db.saveBatch(table, dbms, {
557
561
  excludeFromIndexes: this.cfg.excludeFromIndexes,
562
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
558
563
  ...opt,
559
564
  });
560
565
  this.logSaveResult(started, op, table);
@@ -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.0",
45
+ "version": "8.40.0",
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,
@@ -553,7 +554,7 @@ export class CommonDao<
553
554
  opt: CommonDaoStreamForEachOptions<ID> = {},
554
555
  ): Promise<void> {
555
556
  q.table = opt.table || q.table
556
- opt.errorMode = opt.errorMode || ErrorMode.SUPPRESS
557
+ opt.errorMode ||= ErrorMode.SUPPRESS
557
558
 
558
559
  const op = `streamQueryIdsForEach(${q.pretty()})`
559
560
  const started = this.logStarted(op, q.table, true)
@@ -609,18 +610,19 @@ 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
616
617
  if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, dbm)
617
- if (this.cfg.immutable && !opt.allowMutability) {
618
- opt.saveMethod ||= 'insert'
618
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
619
+ opt = { ...opt, saveMethod: 'insert' }
619
620
  }
620
621
  const op = `save(${dbm.id})`
621
622
  const started = this.logSaveStarted(op, bm, table)
622
623
  await this.cfg.db.saveBatch(table, [dbm], {
623
624
  excludeFromIndexes: this.cfg.excludeFromIndexes,
625
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
624
626
  ...opt,
625
627
  })
626
628
 
@@ -667,18 +669,19 @@ export class CommonDao<
667
669
  // assigning id in case it misses the id
668
670
  // will override/set `updated` field, unless opts.preserveUpdated is set
669
671
  if (!opt.raw) {
670
- const idWasGenerated = !dbm.id
672
+ const idWasGenerated = !dbm.id && this.cfg.createId
671
673
  this.assignIdCreatedUpdated(dbm, opt) // mutates
672
674
  dbm = this.anyToDBM(dbm, opt)
673
675
  if (opt.ensureUniqueId && idWasGenerated) await this.ensureUniqueId(table, dbm)
674
676
  }
675
- if (this.cfg.immutable && !opt.allowMutability) {
676
- opt.saveMethod ||= 'insert'
677
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
678
+ opt = { ...opt, saveMethod: 'insert' }
677
679
  }
678
680
  const op = `saveAsDBM(${dbm.id})`
679
681
  const started = this.logSaveStarted(op, dbm, table)
680
682
  await this.cfg.db.saveBatch(table, [dbm], {
681
683
  excludeFromIndexes: this.cfg.excludeFromIndexes,
684
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
682
685
  ...opt,
683
686
  })
684
687
  this.logSaveResult(started, op, table)
@@ -691,8 +694,8 @@ export class CommonDao<
691
694
  bms.forEach(bm => this.assignIdCreatedUpdated(bm, opt))
692
695
  const dbms = await this.bmsToDBM(bms as BM[], opt)
693
696
  if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
694
- if (this.cfg.immutable && !opt.allowMutability) {
695
- opt.saveMethod ||= 'insert'
697
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
698
+ opt = { ...opt, saveMethod: 'insert' }
696
699
  }
697
700
 
698
701
  const op = `saveBatch ${dbms.length} row(s) (${_truncate(
@@ -706,6 +709,7 @@ export class CommonDao<
706
709
 
707
710
  await this.cfg.db.saveBatch(table, dbms, {
708
711
  excludeFromIndexes: this.cfg.excludeFromIndexes,
712
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
709
713
  ...opt,
710
714
  })
711
715
 
@@ -722,8 +726,8 @@ export class CommonDao<
722
726
  dbms = this.anyToDBMs(dbms, opt)
723
727
  if (opt.ensureUniqueId) throw new AppError('ensureUniqueId is not supported in saveBatch')
724
728
  }
725
- if (this.cfg.immutable && !opt.allowMutability) {
726
- opt.saveMethod ||= 'insert'
729
+ if (this.cfg.immutable && !opt.allowMutability && !opt.saveMethod) {
730
+ opt = { ...opt, saveMethod: 'insert' }
727
731
  }
728
732
  const op = `saveBatchAsDBM ${dbms.length} row(s) (${_truncate(
729
733
  dbms
@@ -736,6 +740,7 @@ export class CommonDao<
736
740
 
737
741
  await this.cfg.db.saveBatch(table, dbms, {
738
742
  excludeFromIndexes: this.cfg.excludeFromIndexes,
743
+ assignGeneratedIds: this.cfg.assignGeneratedIds,
739
744
  ...opt,
740
745
  })
741
746
 
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',