@awsless/dynamodb-server 0.1.2 → 0.1.4
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/dist/index.js +43 -38
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -251,6 +251,9 @@ function listTables(store, input) {
|
|
|
251
251
|
};
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
// src/expressions/condition.ts
|
|
255
|
+
import { cmp, parse } from "@awsless/big-float";
|
|
256
|
+
|
|
254
257
|
// src/expressions/path.ts
|
|
255
258
|
function parsePath(path, attributeNames) {
|
|
256
259
|
const segments = [];
|
|
@@ -691,17 +694,16 @@ function evaluateCondition(expression, item, context) {
|
|
|
691
694
|
consume("RPAREN");
|
|
692
695
|
const segments = parsePath(pathToken.value, context.expressionAttributeNames);
|
|
693
696
|
const value = getValueAtPath(item, segments);
|
|
694
|
-
if (!value) {
|
|
695
|
-
return false;
|
|
696
|
-
}
|
|
697
697
|
let size = 0;
|
|
698
|
-
if (
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
698
|
+
if (value) {
|
|
699
|
+
if ("S" in value) size = value.S.length;
|
|
700
|
+
else if ("B" in value) size = value.B.length;
|
|
701
|
+
else if ("SS" in value) size = value.SS.length;
|
|
702
|
+
else if ("NS" in value) size = value.NS.length;
|
|
703
|
+
else if ("BS" in value) size = value.BS.length;
|
|
704
|
+
else if ("L" in value) size = value.L.length;
|
|
705
|
+
else if ("M" in value) size = Object.keys(value.M).length;
|
|
706
|
+
}
|
|
705
707
|
const nextToken = current();
|
|
706
708
|
if (nextToken?.type === "COMPARATOR") {
|
|
707
709
|
consume("COMPARATOR");
|
|
@@ -710,7 +712,7 @@ function evaluateCondition(expression, item, context) {
|
|
|
710
712
|
if (!rightValue || !("N" in rightValue)) {
|
|
711
713
|
throw new ValidationException("Size comparison requires numeric operand");
|
|
712
714
|
}
|
|
713
|
-
return compareNumbers(size,
|
|
715
|
+
return compareNumbers(size, Number(rightValue.N), nextToken.value);
|
|
714
716
|
}
|
|
715
717
|
return size > 0;
|
|
716
718
|
}
|
|
@@ -778,20 +780,20 @@ function evaluateCondition(expression, item, context) {
|
|
|
778
780
|
}
|
|
779
781
|
return false;
|
|
780
782
|
}
|
|
781
|
-
const
|
|
783
|
+
const cmp5 = compareValues(left, right);
|
|
782
784
|
switch (op) {
|
|
783
785
|
case "=":
|
|
784
|
-
return
|
|
786
|
+
return cmp5 === 0;
|
|
785
787
|
case "<>":
|
|
786
|
-
return
|
|
788
|
+
return cmp5 !== 0;
|
|
787
789
|
case "<":
|
|
788
|
-
return
|
|
790
|
+
return cmp5 < 0;
|
|
789
791
|
case "<=":
|
|
790
|
-
return
|
|
792
|
+
return cmp5 <= 0;
|
|
791
793
|
case ">":
|
|
792
|
-
return
|
|
794
|
+
return cmp5 > 0;
|
|
793
795
|
case ">=":
|
|
794
|
-
return
|
|
796
|
+
return cmp5 >= 0;
|
|
795
797
|
default:
|
|
796
798
|
return false;
|
|
797
799
|
}
|
|
@@ -821,7 +823,7 @@ function compareValues(a, b) {
|
|
|
821
823
|
return a.S.localeCompare(b.S);
|
|
822
824
|
}
|
|
823
825
|
if ("N" in a && "N" in b) {
|
|
824
|
-
return
|
|
826
|
+
return cmp(parse(a.N), parse(b.N));
|
|
825
827
|
}
|
|
826
828
|
if ("B" in a && "B" in b) {
|
|
827
829
|
return a.B.localeCompare(b.B);
|
|
@@ -837,7 +839,11 @@ function compareValues(a, b) {
|
|
|
837
839
|
return aStr.localeCompare(bStr);
|
|
838
840
|
}
|
|
839
841
|
|
|
842
|
+
// src/expressions/key-condition.ts
|
|
843
|
+
import { cmp as cmp3, parse as parse3 } from "@awsless/big-float";
|
|
844
|
+
|
|
840
845
|
// src/store/item.ts
|
|
846
|
+
import { cmp as cmp2, parse as parse2 } from "@awsless/big-float";
|
|
841
847
|
function extractKey(item, keySchema) {
|
|
842
848
|
const key = {};
|
|
843
849
|
for (const element of keySchema) {
|
|
@@ -1009,21 +1015,21 @@ function matchesKeyCondition(item, condition) {
|
|
|
1009
1015
|
return true;
|
|
1010
1016
|
}
|
|
1011
1017
|
function matchesRangeCondition(value, condition) {
|
|
1012
|
-
const
|
|
1018
|
+
const cmp5 = compareValues2(value, condition.value);
|
|
1013
1019
|
switch (condition.operator) {
|
|
1014
1020
|
case "=":
|
|
1015
|
-
return
|
|
1021
|
+
return cmp5 === 0;
|
|
1016
1022
|
case "<":
|
|
1017
|
-
return
|
|
1023
|
+
return cmp5 < 0;
|
|
1018
1024
|
case "<=":
|
|
1019
|
-
return
|
|
1025
|
+
return cmp5 <= 0;
|
|
1020
1026
|
case ">":
|
|
1021
|
-
return
|
|
1027
|
+
return cmp5 > 0;
|
|
1022
1028
|
case ">=":
|
|
1023
|
-
return
|
|
1029
|
+
return cmp5 >= 0;
|
|
1024
1030
|
case "BETWEEN":
|
|
1025
1031
|
if (!condition.value2) return false;
|
|
1026
|
-
return
|
|
1032
|
+
return cmp5 >= 0 && compareValues2(value, condition.value2) <= 0;
|
|
1027
1033
|
case "begins_with":
|
|
1028
1034
|
if ("S" in value && "S" in condition.value) {
|
|
1029
1035
|
return value.S.startsWith(condition.value.S);
|
|
@@ -1047,7 +1053,7 @@ function compareValues2(a, b) {
|
|
|
1047
1053
|
return a.S.localeCompare(b.S);
|
|
1048
1054
|
}
|
|
1049
1055
|
if ("N" in a && "N" in b) {
|
|
1050
|
-
return
|
|
1056
|
+
return cmp3(parse3(a.N), parse3(b.N));
|
|
1051
1057
|
}
|
|
1052
1058
|
if ("B" in a && "B" in b) {
|
|
1053
1059
|
return a.B.localeCompare(b.B);
|
|
@@ -1073,6 +1079,7 @@ function applyProjection(item, projectionExpression, expressionAttributeNames) {
|
|
|
1073
1079
|
}
|
|
1074
1080
|
|
|
1075
1081
|
// src/expressions/update.ts
|
|
1082
|
+
import { add, parse as parse4, string, sub } from "@awsless/big-float";
|
|
1076
1083
|
function parseUpdateExpression(expression) {
|
|
1077
1084
|
const actions = [];
|
|
1078
1085
|
let remaining = expression.trim();
|
|
@@ -1307,15 +1314,13 @@ function applySetAction(item, action, context) {
|
|
|
1307
1314
|
const left = resolveOperand(item, action.operands[0], context);
|
|
1308
1315
|
const right = resolveOperand(item, action.operands[1], context);
|
|
1309
1316
|
if (left && "N" in left && right && "N" in right) {
|
|
1310
|
-
|
|
1311
|
-
value = { N: String(result) };
|
|
1317
|
+
value = { N: string(add(parse4(left.N), parse4(right.N))) };
|
|
1312
1318
|
}
|
|
1313
1319
|
} else if (action.operation === "minus") {
|
|
1314
1320
|
const left = resolveOperand(item, action.operands[0], context);
|
|
1315
1321
|
const right = resolveOperand(item, action.operands[1], context);
|
|
1316
1322
|
if (left && "N" in left && right && "N" in right) {
|
|
1317
|
-
|
|
1318
|
-
value = { N: String(result) };
|
|
1323
|
+
value = { N: string(sub(parse4(left.N), parse4(right.N))) };
|
|
1319
1324
|
}
|
|
1320
1325
|
} else {
|
|
1321
1326
|
value = resolveOperand(item, action.value, context);
|
|
@@ -1337,8 +1342,7 @@ function applyAddAction(item, action, context) {
|
|
|
1337
1342
|
}
|
|
1338
1343
|
if ("N" in addValue) {
|
|
1339
1344
|
if (existingValue && "N" in existingValue) {
|
|
1340
|
-
|
|
1341
|
-
setValueAtPath(item, segments, { N: String(result) });
|
|
1345
|
+
setValueAtPath(item, segments, { N: string(add(parse4(existingValue.N), parse4(addValue.N))) });
|
|
1342
1346
|
} else if (!existingValue) {
|
|
1343
1347
|
setValueAtPath(item, segments, addValue);
|
|
1344
1348
|
}
|
|
@@ -2313,6 +2317,7 @@ function createServer(store, port) {
|
|
|
2313
2317
|
}
|
|
2314
2318
|
|
|
2315
2319
|
// src/store/table.ts
|
|
2320
|
+
import { cmp as cmp4, parse as parse5 } from "@awsless/big-float";
|
|
2316
2321
|
var sequenceCounter = 0;
|
|
2317
2322
|
function generateSequenceNumber() {
|
|
2318
2323
|
return String(++sequenceCounter).padStart(21, "0");
|
|
@@ -2632,8 +2637,8 @@ var Table = class {
|
|
|
2632
2637
|
if (!aVal && !bVal) return 0;
|
|
2633
2638
|
if (!aVal) return 1;
|
|
2634
2639
|
if (!bVal) return -1;
|
|
2635
|
-
const
|
|
2636
|
-
return options?.scanIndexForward === false ? -
|
|
2640
|
+
const cmp5 = this.compareAttributes(aVal, bVal);
|
|
2641
|
+
return options?.scanIndexForward === false ? -cmp5 : cmp5;
|
|
2637
2642
|
});
|
|
2638
2643
|
}
|
|
2639
2644
|
let startIdx = 0;
|
|
@@ -2685,8 +2690,8 @@ var Table = class {
|
|
|
2685
2690
|
if (!aVal && !bVal) return 0;
|
|
2686
2691
|
if (!aVal) return 1;
|
|
2687
2692
|
if (!bVal) return -1;
|
|
2688
|
-
const
|
|
2689
|
-
return options?.scanIndexForward === false ? -
|
|
2693
|
+
const cmp5 = this.compareAttributes(aVal, bVal);
|
|
2694
|
+
return options?.scanIndexForward === false ? -cmp5 : cmp5;
|
|
2690
2695
|
});
|
|
2691
2696
|
}
|
|
2692
2697
|
let startIdx = 0;
|
|
@@ -2789,7 +2794,7 @@ var Table = class {
|
|
|
2789
2794
|
}
|
|
2790
2795
|
compareAttributes(a, b) {
|
|
2791
2796
|
if ("S" in a && "S" in b) return a.S.localeCompare(b.S);
|
|
2792
|
-
if ("N" in a && "N" in b) return
|
|
2797
|
+
if ("N" in a && "N" in b) return cmp4(parse5(a.N), parse5(b.N));
|
|
2793
2798
|
if ("B" in a && "B" in b) return a.B.localeCompare(b.B);
|
|
2794
2799
|
return 0;
|
|
2795
2800
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awsless/dynamodb-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@aws-sdk/client-dynamodb": "3.363.0",
|
|
27
|
-
"@aws-sdk/lib-dynamodb": "3.363.0"
|
|
27
|
+
"@aws-sdk/lib-dynamodb": "3.363.0",
|
|
28
|
+
"@awsless/big-float": "^0.1.5"
|
|
28
29
|
},
|
|
29
30
|
"optionalDependencies": {
|
|
30
31
|
"dynamo-db-local": "^10.3.0"
|