electrodb 2.9.3 → 2.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/index.d.ts +81 -9
- package/package.json +13 -5
- package/src/clauses.js +262 -42
- package/src/entity.js +44 -21
- package/src/filterOperations.js +126 -0
- package/src/operations.js +38 -291
- package/src/types.js +9 -0
- package/src/update.js +3 -2
- package/src/updateOperations.js +178 -0
- package/src/util.js +1 -1
package/src/clauses.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const { QueryTypes, MethodTypes, ItemOperations, ExpressionTypes, TransactionCommitSymbol, TransactionOperations, TerminalOperation, KeyTypes, IndexTypes
|
|
1
|
+
const { QueryTypes, MethodTypes, ItemOperations, ExpressionTypes, TransactionCommitSymbol, TransactionOperations, TerminalOperation, KeyTypes, IndexTypes,
|
|
2
|
+
UpsertOperations
|
|
3
|
+
} = require("./types");
|
|
2
4
|
const {AttributeOperationProxy, UpdateOperations, FilterOperationNames, UpdateOperationNames} = require("./operations");
|
|
3
5
|
const {UpdateExpression} = require("./update");
|
|
4
6
|
const {FilterExpression} = require("./where");
|
|
@@ -6,6 +8,13 @@ const v = require("./validations");
|
|
|
6
8
|
const e = require("./errors");
|
|
7
9
|
const u = require("./util");
|
|
8
10
|
|
|
11
|
+
const methodChildren = {
|
|
12
|
+
upsert: ["upsertSet", "upsertAppend", "upsertAdd", "go", "params", "upsertSubtract", "commit", "upsertIfNotExists", "where"],
|
|
13
|
+
update: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit", "composite", "ifNotExists", "where"],
|
|
14
|
+
put: ["where", "params", "go", "commit"],
|
|
15
|
+
del: ["where", "params", "go", "commit"],
|
|
16
|
+
}
|
|
17
|
+
|
|
9
18
|
function batchAction(action, type, entity, state, payload) {
|
|
10
19
|
if (state.getError() !== null) {
|
|
11
20
|
return state;
|
|
@@ -236,7 +245,7 @@ let clauses = {
|
|
|
236
245
|
return state;
|
|
237
246
|
}
|
|
238
247
|
},
|
|
239
|
-
children:
|
|
248
|
+
children: methodChildren.del,
|
|
240
249
|
},
|
|
241
250
|
upsert: {
|
|
242
251
|
name: 'upsert',
|
|
@@ -245,33 +254,115 @@ let clauses = {
|
|
|
245
254
|
return state;
|
|
246
255
|
}
|
|
247
256
|
try {
|
|
248
|
-
|
|
249
|
-
const attributes = state.getCompositeAttributes();
|
|
250
|
-
const pkComposite = entity._expectFacets(record, attributes.pk);
|
|
251
|
-
state.addOption('_includeOnResponseItem', pkComposite);
|
|
257
|
+
|
|
252
258
|
return state
|
|
253
259
|
.setMethod(MethodTypes.upsert)
|
|
254
260
|
.setType(QueryTypes.eq)
|
|
255
|
-
.applyUpsert(
|
|
256
|
-
.
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
state.
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
261
|
+
.applyUpsert(UpsertOperations.set, payload)
|
|
262
|
+
.beforeBuildParams(({ state }) => {
|
|
263
|
+
const { upsert, update, updateProxy } = state.query;
|
|
264
|
+
|
|
265
|
+
state.query.update.set(entity.identifiers.entity, entity.getName());
|
|
266
|
+
state.query.update.set(entity.identifiers.version, entity.getVersion());
|
|
267
|
+
|
|
268
|
+
// only "set" data is used to make keys
|
|
269
|
+
const setData = {};
|
|
270
|
+
const nonSetData = {};
|
|
271
|
+
let allData = {};
|
|
272
|
+
|
|
273
|
+
for (const name in upsert.data) {
|
|
274
|
+
const { operation, value } = upsert.data[name];
|
|
275
|
+
allData[name] = value;
|
|
276
|
+
if (operation === UpsertOperations.set) {
|
|
277
|
+
setData[name] = value;
|
|
278
|
+
} else {
|
|
279
|
+
nonSetData[name] = value;
|
|
280
|
+
}
|
|
267
281
|
}
|
|
282
|
+
|
|
283
|
+
const upsertData = entity.model.schema.checkCreate({ ...allData });
|
|
284
|
+
const attributes = state.getCompositeAttributes();
|
|
285
|
+
const pkComposite = entity._expectFacets(upsertData, attributes.pk);
|
|
286
|
+
|
|
287
|
+
state
|
|
288
|
+
.addOption('_includeOnResponseItem', pkComposite)
|
|
289
|
+
.setPK(pkComposite)
|
|
290
|
+
.ifSK(() => {
|
|
291
|
+
entity._expectFacets(upsertData, attributes.sk);
|
|
292
|
+
const skComposite = entity._buildQueryFacets(upsertData, attributes.sk);
|
|
293
|
+
state.setSK(skComposite);
|
|
294
|
+
state.addOption('_includeOnResponseItem', {...skComposite, ...pkComposite});
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const appliedData = entity.model.schema.applyAttributeSetters({...upsertData});
|
|
298
|
+
|
|
299
|
+
const onlySetAppliedData = {};
|
|
300
|
+
const nonSetAppliedData = {};
|
|
301
|
+
for (const name in appliedData) {
|
|
302
|
+
const value = appliedData[name];
|
|
303
|
+
const isSetOperation = setData[name] !== undefined;
|
|
304
|
+
const cameFromApplyingSetters = allData[name] === undefined;
|
|
305
|
+
const isNotUndefined = appliedData[name] !== undefined;
|
|
306
|
+
const applyAsSet = isSetOperation || cameFromApplyingSetters;
|
|
307
|
+
if (applyAsSet && isNotUndefined) {
|
|
308
|
+
onlySetAppliedData[name] = value;
|
|
309
|
+
} else {
|
|
310
|
+
nonSetAppliedData[name] = value;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// we build this above, and set them to state, but use it here, not ideal but
|
|
315
|
+
// the way it worked out so that this could be wrapped in beforeBuildParams
|
|
316
|
+
const { pk } = state.query.keys;
|
|
317
|
+
const sk = state.query.keys.sk[0];
|
|
318
|
+
|
|
319
|
+
const { updatedKeys, setAttributes, indexKey } = entity._getPutKeys(pk, sk && sk.facets, onlySetAppliedData);
|
|
320
|
+
|
|
321
|
+
// calculated here but needs to be used when building the params
|
|
322
|
+
upsert.indexKey = indexKey;
|
|
323
|
+
|
|
324
|
+
// only "set" data is used to make keys
|
|
325
|
+
const setFields = Object.entries(entity.model.schema.translateToFields(setAttributes));
|
|
326
|
+
|
|
327
|
+
// add the keys impacted except for the table index keys; they are upserted
|
|
328
|
+
// automatically by dynamo
|
|
329
|
+
for (const key in updatedKeys) {
|
|
330
|
+
const value = updatedKeys[key];
|
|
331
|
+
if (indexKey[key] === undefined) {
|
|
332
|
+
setFields.push([key, value]);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
entity._maybeApplyUpsertUpdate({
|
|
337
|
+
fields: setFields,
|
|
338
|
+
operation: UpsertOperations.set,
|
|
339
|
+
updateProxy,
|
|
340
|
+
update,
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
for (const name in nonSetData) {
|
|
344
|
+
const value = appliedData[name];
|
|
345
|
+
if (value === undefined || upsert.data[name] === undefined) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const { operation } = upsert.data[name];
|
|
350
|
+
const fields = entity.model.schema.translateToFields({ [name]: value });
|
|
351
|
+
entity._maybeApplyUpsertUpdate({
|
|
352
|
+
fields: Object.entries(fields),
|
|
353
|
+
updateProxy,
|
|
354
|
+
operation,
|
|
355
|
+
update,
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
|
|
268
359
|
});
|
|
269
360
|
} catch(err) {
|
|
270
361
|
state.setError(err);
|
|
271
362
|
return state;
|
|
272
363
|
}
|
|
273
364
|
},
|
|
274
|
-
children:
|
|
365
|
+
children: methodChildren.upsert,
|
|
275
366
|
},
|
|
276
367
|
put: {
|
|
277
368
|
name: "put",
|
|
@@ -297,7 +388,7 @@ let clauses = {
|
|
|
297
388
|
return state;
|
|
298
389
|
}
|
|
299
390
|
},
|
|
300
|
-
children:
|
|
391
|
+
children: methodChildren.put,
|
|
301
392
|
},
|
|
302
393
|
batchPut: {
|
|
303
394
|
name: "batchPut",
|
|
@@ -333,7 +424,7 @@ let clauses = {
|
|
|
333
424
|
return state;
|
|
334
425
|
}
|
|
335
426
|
},
|
|
336
|
-
children:
|
|
427
|
+
children: methodChildren.put,
|
|
337
428
|
},
|
|
338
429
|
patch: {
|
|
339
430
|
name: "patch",
|
|
@@ -366,7 +457,7 @@ let clauses = {
|
|
|
366
457
|
return state;
|
|
367
458
|
}
|
|
368
459
|
},
|
|
369
|
-
children:
|
|
460
|
+
children: methodChildren.update,
|
|
370
461
|
},
|
|
371
462
|
update: {
|
|
372
463
|
name: "update",
|
|
@@ -393,7 +484,7 @@ let clauses = {
|
|
|
393
484
|
return state;
|
|
394
485
|
}
|
|
395
486
|
},
|
|
396
|
-
children:
|
|
487
|
+
children: methodChildren.update,
|
|
397
488
|
},
|
|
398
489
|
data: {
|
|
399
490
|
name: "data",
|
|
@@ -423,7 +514,7 @@ let clauses = {
|
|
|
423
514
|
return state;
|
|
424
515
|
}
|
|
425
516
|
},
|
|
426
|
-
children:
|
|
517
|
+
children: methodChildren.update,
|
|
427
518
|
},
|
|
428
519
|
set: {
|
|
429
520
|
name: "set",
|
|
@@ -440,7 +531,24 @@ let clauses = {
|
|
|
440
531
|
return state;
|
|
441
532
|
}
|
|
442
533
|
},
|
|
443
|
-
children:
|
|
534
|
+
children: methodChildren.update,
|
|
535
|
+
},
|
|
536
|
+
upsertSet: {
|
|
537
|
+
name: "set",
|
|
538
|
+
action(entity, state, data) {
|
|
539
|
+
if (state.getError() !== null) {
|
|
540
|
+
return state;
|
|
541
|
+
}
|
|
542
|
+
try {
|
|
543
|
+
entity.model.schema.checkUpdate(data, { allowReadOnly: true });
|
|
544
|
+
state.query.upsert.addData(UpsertOperations.set, data);
|
|
545
|
+
return state;
|
|
546
|
+
} catch(err) {
|
|
547
|
+
state.setError(err);
|
|
548
|
+
return state;
|
|
549
|
+
}
|
|
550
|
+
},
|
|
551
|
+
children: methodChildren.upsert,
|
|
444
552
|
},
|
|
445
553
|
composite: {
|
|
446
554
|
name: "composite",
|
|
@@ -465,7 +573,7 @@ let clauses = {
|
|
|
465
573
|
return state;
|
|
466
574
|
}
|
|
467
575
|
},
|
|
468
|
-
children:
|
|
576
|
+
children: methodChildren.update,
|
|
469
577
|
},
|
|
470
578
|
append: {
|
|
471
579
|
name: "append",
|
|
@@ -482,7 +590,50 @@ let clauses = {
|
|
|
482
590
|
return state;
|
|
483
591
|
}
|
|
484
592
|
},
|
|
485
|
-
children:
|
|
593
|
+
children: methodChildren.update,
|
|
594
|
+
},
|
|
595
|
+
ifNotExists: {
|
|
596
|
+
name: 'ifNotExists',
|
|
597
|
+
action(entity, state, data = {}) {
|
|
598
|
+
entity.model.schema.checkUpdate(data);
|
|
599
|
+
state.query.updateProxy.fromObject(ItemOperations.ifNotExists, data);
|
|
600
|
+
return state;
|
|
601
|
+
},
|
|
602
|
+
children: methodChildren.update,
|
|
603
|
+
},
|
|
604
|
+
upsertIfNotExists: {
|
|
605
|
+
name: 'ifNotExists',
|
|
606
|
+
action(entity, state, data = {}) {
|
|
607
|
+
if (state.getError() !== null) {
|
|
608
|
+
return state;
|
|
609
|
+
}
|
|
610
|
+
try {
|
|
611
|
+
entity.model.schema.checkUpdate(data, { allowReadOnly: true });
|
|
612
|
+
state.query.upsert.addData(UpsertOperations.ifNotExists, data);
|
|
613
|
+
return state;
|
|
614
|
+
} catch(err) {
|
|
615
|
+
state.setError(err);
|
|
616
|
+
return state;
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
children: methodChildren.upsert,
|
|
620
|
+
},
|
|
621
|
+
upsertAppend: {
|
|
622
|
+
name: "append",
|
|
623
|
+
action(entity, state, data = {}) {
|
|
624
|
+
if (state.getError() !== null) {
|
|
625
|
+
return state;
|
|
626
|
+
}
|
|
627
|
+
try {
|
|
628
|
+
entity.model.schema.checkUpdate(data, { allowReadOnly: true });
|
|
629
|
+
state.query.upsert.addData(UpsertOperations.append, data);
|
|
630
|
+
return state;
|
|
631
|
+
} catch(err) {
|
|
632
|
+
state.setError(err);
|
|
633
|
+
return state;
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
children: methodChildren.upsert,
|
|
486
637
|
},
|
|
487
638
|
updateRemove: {
|
|
488
639
|
name: "remove",
|
|
@@ -502,7 +653,7 @@ let clauses = {
|
|
|
502
653
|
return state;
|
|
503
654
|
}
|
|
504
655
|
},
|
|
505
|
-
children:
|
|
656
|
+
children: methodChildren.update
|
|
506
657
|
},
|
|
507
658
|
updateDelete: {
|
|
508
659
|
name: "delete",
|
|
@@ -519,7 +670,7 @@ let clauses = {
|
|
|
519
670
|
return state;
|
|
520
671
|
}
|
|
521
672
|
},
|
|
522
|
-
children:
|
|
673
|
+
children: methodChildren.update
|
|
523
674
|
},
|
|
524
675
|
add: {
|
|
525
676
|
name: "add",
|
|
@@ -536,7 +687,41 @@ let clauses = {
|
|
|
536
687
|
return state;
|
|
537
688
|
}
|
|
538
689
|
},
|
|
539
|
-
children:
|
|
690
|
+
children: methodChildren.update
|
|
691
|
+
},
|
|
692
|
+
upsertAdd: {
|
|
693
|
+
name: "add",
|
|
694
|
+
action(entity, state, data) {
|
|
695
|
+
if (state.getError() !== null) {
|
|
696
|
+
return state;
|
|
697
|
+
}
|
|
698
|
+
try {
|
|
699
|
+
entity.model.schema.checkUpdate(data, { allowReadOnly: true });
|
|
700
|
+
state.query.upsert.addData(UpsertOperations.add, data);
|
|
701
|
+
return state;
|
|
702
|
+
} catch(err) {
|
|
703
|
+
state.setError(err);
|
|
704
|
+
return state;
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
children: methodChildren.upsert
|
|
708
|
+
},
|
|
709
|
+
upsertSubtract: {
|
|
710
|
+
name: "subtract",
|
|
711
|
+
action(entity, state, data) {
|
|
712
|
+
if (state.getError() !== null) {
|
|
713
|
+
return state;
|
|
714
|
+
}
|
|
715
|
+
try {
|
|
716
|
+
entity.model.schema.checkUpdate(data, { allowReadOnly: true });
|
|
717
|
+
state.query.upsert.addData(UpsertOperations.subtract, data);
|
|
718
|
+
return state;
|
|
719
|
+
} catch(err) {
|
|
720
|
+
state.setError(err);
|
|
721
|
+
return state;
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
children: methodChildren.upsert
|
|
540
725
|
},
|
|
541
726
|
subtract: {
|
|
542
727
|
name: "subtract",
|
|
@@ -553,7 +738,7 @@ let clauses = {
|
|
|
553
738
|
return state;
|
|
554
739
|
}
|
|
555
740
|
},
|
|
556
|
-
children:
|
|
741
|
+
children: methodChildren.update
|
|
557
742
|
},
|
|
558
743
|
query: {
|
|
559
744
|
name: "query",
|
|
@@ -767,6 +952,7 @@ let clauses = {
|
|
|
767
952
|
});
|
|
768
953
|
|
|
769
954
|
state.applyWithOptions(normalizedOptions);
|
|
955
|
+
state.applyBeforeBuildParams(normalizedOptions);
|
|
770
956
|
|
|
771
957
|
let results;
|
|
772
958
|
switch (method) {
|
|
@@ -794,15 +980,15 @@ let clauses = {
|
|
|
794
980
|
delete results.ExpressionAttributeValues;
|
|
795
981
|
}
|
|
796
982
|
|
|
797
|
-
state.setParams(results);
|
|
798
|
-
|
|
799
983
|
if (options._returnOptions) {
|
|
800
|
-
|
|
984
|
+
results = {
|
|
801
985
|
params: results,
|
|
802
986
|
options: normalizedOptions,
|
|
803
987
|
}
|
|
804
988
|
}
|
|
805
989
|
|
|
990
|
+
state.setParams(results);
|
|
991
|
+
|
|
806
992
|
return results;
|
|
807
993
|
} catch(err) {
|
|
808
994
|
throw err;
|
|
@@ -854,7 +1040,27 @@ class ChainState {
|
|
|
854
1040
|
},
|
|
855
1041
|
upsert: {
|
|
856
1042
|
data: {},
|
|
857
|
-
|
|
1043
|
+
indexKey: null,
|
|
1044
|
+
addData(operation = UpsertOperations.set, data = {}) {
|
|
1045
|
+
for (const name of Object.keys(data)) {
|
|
1046
|
+
const value = data[name];
|
|
1047
|
+
this.data[name] = {
|
|
1048
|
+
operation,
|
|
1049
|
+
value,
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
},
|
|
1053
|
+
getData(operationFilter) {
|
|
1054
|
+
const results = {};
|
|
1055
|
+
for (const name in this.data) {
|
|
1056
|
+
const { operation, value } = this.data[name];
|
|
1057
|
+
if (!operationFilter || operationFilter === operation) {
|
|
1058
|
+
results[name] = value;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
return results;
|
|
1063
|
+
}
|
|
858
1064
|
},
|
|
859
1065
|
keys: {
|
|
860
1066
|
provided: [],
|
|
@@ -868,11 +1074,13 @@ class ChainState {
|
|
|
868
1074
|
options,
|
|
869
1075
|
};
|
|
870
1076
|
this.subStates = [];
|
|
871
|
-
this.applyAfterOptions = [];
|
|
872
1077
|
this.hasSortKey = hasSortKey;
|
|
873
1078
|
this.prev = null;
|
|
874
1079
|
this.self = null;
|
|
875
1080
|
this.params = null;
|
|
1081
|
+
this.applyAfterOptions = [];
|
|
1082
|
+
this.beforeBuildParamsOperations = [];
|
|
1083
|
+
this.beforeBuildParamsHasRan = false;
|
|
876
1084
|
}
|
|
877
1085
|
|
|
878
1086
|
getParams() {
|
|
@@ -913,6 +1121,7 @@ class ChainState {
|
|
|
913
1121
|
|
|
914
1122
|
addOption(key, value) {
|
|
915
1123
|
this.query.options[key] = value;
|
|
1124
|
+
return this;
|
|
916
1125
|
}
|
|
917
1126
|
|
|
918
1127
|
_appendProvided(type, attributes) {
|
|
@@ -1075,12 +1284,8 @@ class ChainState {
|
|
|
1075
1284
|
}
|
|
1076
1285
|
}
|
|
1077
1286
|
|
|
1078
|
-
applyUpsert(
|
|
1079
|
-
|
|
1080
|
-
this.query.upsert.ifNotExists = {...this.query.upsert.ifNotExists, ...data};
|
|
1081
|
-
} else {
|
|
1082
|
-
this.query.upsert.data = {...this.query.upsert.data, ...data};
|
|
1083
|
-
}
|
|
1287
|
+
applyUpsert(operation = UpsertOperations.set, data = {}) {
|
|
1288
|
+
this.query.upsert.addData(operation, data);
|
|
1084
1289
|
return this;
|
|
1085
1290
|
}
|
|
1086
1291
|
|
|
@@ -1100,6 +1305,21 @@ class ChainState {
|
|
|
1100
1305
|
applyWithOptions(options = {}) {
|
|
1101
1306
|
this.applyAfterOptions.forEach((fn) => fn(options));
|
|
1102
1307
|
}
|
|
1308
|
+
|
|
1309
|
+
beforeBuildParams(fn) {
|
|
1310
|
+
if (v.isFunction(fn)) {
|
|
1311
|
+
this.beforeBuildParamsOperations.push((options) => {
|
|
1312
|
+
fn({ options, state: this });
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
applyBeforeBuildParams(options = {}) {
|
|
1318
|
+
if (!this.beforeBuildParamsHasRan) {
|
|
1319
|
+
this.beforeBuildParamsHasRan = true;
|
|
1320
|
+
this.beforeBuildParamsOperations.forEach((fn) => fn(options));
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1103
1323
|
}
|
|
1104
1324
|
|
|
1105
1325
|
module.exports = {
|
package/src/entity.js
CHANGED
|
@@ -27,6 +27,7 @@ const {
|
|
|
27
27
|
MethodTypeTranslation,
|
|
28
28
|
TransactionCommitSymbol,
|
|
29
29
|
CastKeyOptions,
|
|
30
|
+
UpsertOperations,
|
|
30
31
|
} = require("./types");
|
|
31
32
|
const { FilterFactory } = require("./filters");
|
|
32
33
|
const { FilterOperations } = require("./operations");
|
|
@@ -1581,7 +1582,7 @@ class Entity {
|
|
|
1581
1582
|
}
|
|
1582
1583
|
/* istanbul ignore next */
|
|
1583
1584
|
_params(state, config = {}) {
|
|
1584
|
-
const { keys = {}, method = "", put = {}, update = {}, filter = {}, upsert } = state.query;
|
|
1585
|
+
const { keys = {}, method = "", put = {}, update = {}, filter = {}, upsert, updateProxy } = state.query;
|
|
1585
1586
|
let consolidatedQueryFacets = this._consolidateQueryFacets(keys.sk);
|
|
1586
1587
|
let params = {};
|
|
1587
1588
|
switch (method) {
|
|
@@ -1592,7 +1593,7 @@ class Entity {
|
|
|
1592
1593
|
params = this._makeSimpleIndexParams(keys.pk, ...consolidatedQueryFacets);
|
|
1593
1594
|
break;
|
|
1594
1595
|
case MethodTypes.upsert:
|
|
1595
|
-
params = this._makeUpsertParams({update, upsert}, keys.pk, ...keys.sk)
|
|
1596
|
+
params = this._makeUpsertParams({update, upsert, updateProxy}, keys.pk, ...keys.sk)
|
|
1596
1597
|
break;
|
|
1597
1598
|
case MethodTypes.put:
|
|
1598
1599
|
case MethodTypes.create:
|
|
@@ -1957,7 +1958,8 @@ class Entity {
|
|
|
1957
1958
|
|
|
1958
1959
|
/* istanbul ignore next */
|
|
1959
1960
|
_makePutParams({ data } = {}, pk, sk) {
|
|
1960
|
-
let
|
|
1961
|
+
let appliedData = this.model.schema.applyAttributeSetters(data);
|
|
1962
|
+
let { updatedKeys, setAttributes } = this._getPutKeys(pk, sk && sk.facets, appliedData);
|
|
1961
1963
|
let translatedFields = this.model.schema.translateToFields(setAttributes);
|
|
1962
1964
|
return {
|
|
1963
1965
|
Item: {
|
|
@@ -1970,31 +1972,52 @@ class Entity {
|
|
|
1970
1972
|
};
|
|
1971
1973
|
}
|
|
1972
1974
|
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1975
|
+
_maybeApplyUpsertUpdate({fields = [], operation, updateProxy, update}) {
|
|
1976
|
+
for (let [field, value] of fields) {
|
|
1977
|
+
const name = this.model.schema.translationForRetrieval[field];
|
|
1978
|
+
if (name) {
|
|
1979
|
+
const attribute = this.model.schema.attributes[name];
|
|
1980
|
+
if (this.model.schema.readOnlyAttributes.has(name) && (!attribute || !attribute.indexes || attribute.indexes.length === 0)) {
|
|
1981
|
+
/*
|
|
1982
|
+
// this should be considered but is likely overkill at best and unexpected at worst.
|
|
1983
|
+
// It also is likely symbolic of a deeper issue. That said maybe it could be helpful
|
|
1984
|
+
// in the future? It is unclear, if this were added, whether this should get the
|
|
1985
|
+
// default value and then call the setter on the defaultValue. That would at least
|
|
1986
|
+
// make parity between upsert and a create (without including the attribute) and then
|
|
1987
|
+
// an "update"
|
|
1988
|
+
|
|
1989
|
+
const defaultValue = attribute.default();
|
|
1990
|
+
const valueIsNumber = typeof value === 'number';
|
|
1991
|
+
const resolvedDefaultValue = typeof defaultValue === 'number' ? defaultValue : 0;
|
|
1992
|
+
if (operation === UpsertOperations.subtract && valueIsNumber) {
|
|
1993
|
+
value = resolvedDefaultValue - value;
|
|
1994
|
+
} else if (operation === UpsertOperations.add && valueIsNumber) {
|
|
1995
|
+
value = resolvedDefaultValue + value;
|
|
1996
|
+
// }
|
|
1997
|
+
*/
|
|
1998
|
+
update.set(field, value, ItemOperations.ifNotExists);
|
|
1999
|
+
} else {
|
|
2000
|
+
updateProxy.performOperation({
|
|
2001
|
+
value,
|
|
2002
|
+
operation,
|
|
2003
|
+
path: name,
|
|
2004
|
+
force: true
|
|
2005
|
+
});
|
|
1987
2006
|
}
|
|
2007
|
+
} else {
|
|
2008
|
+
// I think this is for keys
|
|
1988
2009
|
update.set(field, value, operation);
|
|
1989
2010
|
}
|
|
1990
2011
|
}
|
|
2012
|
+
}
|
|
1991
2013
|
|
|
2014
|
+
_makeUpsertParams({ update, upsert } = {}) {
|
|
1992
2015
|
return {
|
|
1993
2016
|
TableName: this.getTableName(),
|
|
1994
2017
|
UpdateExpression: update.build(),
|
|
1995
2018
|
ExpressionAttributeNames: update.getNames(),
|
|
1996
2019
|
ExpressionAttributeValues: update.getValues(),
|
|
1997
|
-
Key: indexKey,
|
|
2020
|
+
Key: upsert.indexKey,
|
|
1998
2021
|
};
|
|
1999
2022
|
}
|
|
2000
2023
|
|
|
@@ -2391,13 +2414,13 @@ class Entity {
|
|
|
2391
2414
|
return indexKeys;
|
|
2392
2415
|
}
|
|
2393
2416
|
|
|
2394
|
-
_getPutKeys(pk, sk, set) {
|
|
2395
|
-
let setAttributes =
|
|
2417
|
+
_getPutKeys(pk, sk, set, validationAssistance) {
|
|
2418
|
+
let setAttributes = set;
|
|
2396
2419
|
let updateIndex = TableIndex;
|
|
2397
2420
|
let keyTranslations = this.model.translations.keys;
|
|
2398
2421
|
let keyAttributes = { ...sk, ...pk };
|
|
2399
2422
|
let completeFacets = this._expectIndexFacets(
|
|
2400
|
-
{ ...setAttributes },
|
|
2423
|
+
{ ...setAttributes, ...validationAssistance },
|
|
2401
2424
|
{ ...keyAttributes },
|
|
2402
2425
|
);
|
|
2403
2426
|
|