@webda/aws 2.0.0-beta.1 → 2.0.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/deployers/cloudformation.d.ts +2 -2
- package/lib/deployers/cloudformation.js +672 -693
- package/lib/deployers/cloudformation.js.map +1 -1
- package/lib/deployers/cloudformation.spec.js +428 -477
- package/lib/deployers/cloudformation.spec.js.map +1 -1
- package/lib/deployers/index.js +282 -342
- package/lib/deployers/index.js.map +1 -1
- package/lib/deployers/index.spec.d.ts +1 -1
- package/lib/deployers/index.spec.js +445 -510
- package/lib/deployers/index.spec.js.map +1 -1
- package/lib/deployers/lambda-entrypoint.js +4 -16
- package/lib/deployers/lambda-entrypoint.js.map +1 -1
- package/lib/deployers/lambdapackager.js +13 -52
- package/lib/deployers/lambdapackager.js.map +1 -1
- package/lib/deployers/lambdapackager.spec.js +25 -61
- package/lib/deployers/lambdapackager.spec.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -17
- package/lib/index.js.map +1 -1
- package/lib/index.spec.d.ts +1 -1
- package/lib/index.spec.js +28 -75
- package/lib/index.spec.js.map +1 -1
- package/lib/services/aws-mixin.d.ts +2 -0
- package/lib/services/aws-mixin.js +2 -7
- package/lib/services/aws-mixin.js.map +1 -1
- package/lib/services/cloudwatchlogger.d.ts +4 -2
- package/lib/services/cloudwatchlogger.js +63 -103
- package/lib/services/cloudwatchlogger.js.map +1 -1
- package/lib/services/cloudwatchlogger.spec.js +57 -100
- package/lib/services/cloudwatchlogger.spec.js.map +1 -1
- package/lib/services/dynamodb.d.ts +5 -3
- package/lib/services/dynamodb.js +458 -498
- package/lib/services/dynamodb.js.map +1 -1
- package/lib/services/dynamodb.spec.d.ts +2 -2
- package/lib/services/dynamodb.spec.js +232 -302
- package/lib/services/dynamodb.spec.js.map +1 -1
- package/lib/services/index.d.ts +9 -9
- package/lib/services/index.js +8 -24
- package/lib/services/index.js.map +1 -1
- package/lib/services/lambdacaller.d.ts +3 -1
- package/lib/services/lambdacaller.js +16 -29
- package/lib/services/lambdacaller.js.map +1 -1
- package/lib/services/lambdacaller.spec.js +43 -81
- package/lib/services/lambdacaller.spec.js.map +1 -1
- package/lib/services/lambdaserver.d.ts +1 -8
- package/lib/services/lambdaserver.js +168 -206
- package/lib/services/lambdaserver.js.map +1 -1
- package/lib/services/lambdaserver.spec.js +266 -354
- package/lib/services/lambdaserver.spec.js.map +1 -1
- package/lib/services/route53.js +112 -137
- package/lib/services/route53.js.map +1 -1
- package/lib/services/route53.spec.js +56 -92
- package/lib/services/route53.spec.js.map +1 -1
- package/lib/services/s3binary.d.ts +6 -2
- package/lib/services/s3binary.js +189 -251
- package/lib/services/s3binary.js.map +1 -1
- package/lib/services/s3binary.spec.js +185 -254
- package/lib/services/s3binary.spec.js.map +1 -1
- package/lib/services/secretsmanager.d.ts +2 -0
- package/lib/services/secretsmanager.js +32 -56
- package/lib/services/secretsmanager.js.map +1 -1
- package/lib/services/secretsmanager.spec.js +50 -93
- package/lib/services/secretsmanager.spec.js.map +1 -1
- package/lib/services/sqsqueue.d.ts +6 -8
- package/lib/services/sqsqueue.js +70 -98
- package/lib/services/sqsqueue.js.map +1 -1
- package/lib/services/sqsqueue.spec.js +95 -145
- package/lib/services/sqsqueue.spec.js.map +1 -1
- package/lib/shell.js +19 -38
- package/lib/shell.js.map +1 -1
- package/package.json +12 -9
- package/webda.module.json +48 -0
package/lib/services/dynamodb.js
CHANGED
|
@@ -1,33 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.DynamoStore = exports.DynamoStoreParameters = void 0;
|
|
13
|
-
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
14
|
-
const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
|
|
15
|
-
const core_1 = require("@webda/core");
|
|
16
|
-
const _1 = require(".");
|
|
1
|
+
import { ConditionalCheckFailedException, DynamoDB, DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb";
|
|
3
|
+
import { CoreModel, Store, StoreNotFoundError, StoreParameters, UpdateConditionFailError, WebdaError, WebdaQL } from "@webda/core";
|
|
4
|
+
import { AWSServiceParameters } from "./index.js";
|
|
17
5
|
/**
|
|
18
6
|
* Define DynamoDB parameters
|
|
19
7
|
*/
|
|
20
|
-
class DynamoStoreParameters extends
|
|
8
|
+
export class DynamoStoreParameters extends AWSServiceParameters(StoreParameters) {
|
|
21
9
|
constructor(params, service) {
|
|
22
|
-
var _a;
|
|
23
10
|
super(params, service);
|
|
24
11
|
if (this.table === undefined) {
|
|
25
|
-
throw new
|
|
12
|
+
throw new WebdaError("DYNAMODB_TABLE_PARAMETER_REQUIRED", "Need to define a table at least");
|
|
26
13
|
}
|
|
27
|
-
|
|
14
|
+
this.globalIndexes ?? (this.globalIndexes = {});
|
|
28
15
|
}
|
|
29
16
|
}
|
|
30
|
-
exports.DynamoStoreParameters = DynamoStoreParameters;
|
|
31
17
|
/**
|
|
32
18
|
* DynamoStore handles the DynamoDB
|
|
33
19
|
*
|
|
@@ -39,7 +25,7 @@ exports.DynamoStoreParameters = DynamoStoreParameters;
|
|
|
39
25
|
*
|
|
40
26
|
* @WebdaModda
|
|
41
27
|
*/
|
|
42
|
-
class DynamoStore extends
|
|
28
|
+
export default class DynamoStore extends Store {
|
|
43
29
|
/**
|
|
44
30
|
* Load the parameters
|
|
45
31
|
*
|
|
@@ -53,11 +39,12 @@ class DynamoStore extends core_1.Store {
|
|
|
53
39
|
*/
|
|
54
40
|
resolve() {
|
|
55
41
|
super.resolve();
|
|
56
|
-
this._client =
|
|
42
|
+
this._client = DynamoDBDocument.from(new DynamoDBClient(this.parameters), {
|
|
57
43
|
marshallOptions: {
|
|
58
44
|
removeUndefinedValues: true
|
|
59
45
|
}
|
|
60
46
|
});
|
|
47
|
+
return this;
|
|
61
48
|
}
|
|
62
49
|
/**
|
|
63
50
|
* Copy one DynamoDB table to another
|
|
@@ -66,54 +53,48 @@ class DynamoStore extends core_1.Store {
|
|
|
66
53
|
* @param source
|
|
67
54
|
* @param target
|
|
68
55
|
*/
|
|
69
|
-
static copyTable(output, source, target) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
56
|
+
static async copyTable(output, source, target) {
|
|
57
|
+
let db = new DynamoDB({});
|
|
58
|
+
let ExclusiveStartKey;
|
|
59
|
+
let props = await db.describeTable({
|
|
60
|
+
TableName: source
|
|
61
|
+
});
|
|
62
|
+
output.startProgress("copyTable", props.Table.ItemCount, `Copying ${source} to ${target}`);
|
|
63
|
+
do {
|
|
64
|
+
let info = await db.scan({
|
|
65
|
+
TableName: source,
|
|
66
|
+
ExclusiveStartKey
|
|
75
67
|
});
|
|
76
|
-
output.startProgress("copyTable", props.Table.ItemCount, `Copying ${source} to ${target}`);
|
|
77
68
|
do {
|
|
78
|
-
let
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
yield db.batchWriteItem(params);
|
|
95
|
-
output.incrementProgress(items.length, "copyTable");
|
|
96
|
-
} while (true);
|
|
97
|
-
ExclusiveStartKey = info.LastEvaluatedKey;
|
|
98
|
-
} while (ExclusiveStartKey);
|
|
99
|
-
});
|
|
69
|
+
let items = [];
|
|
70
|
+
while (info.Items.length && items.length < 25) {
|
|
71
|
+
items.push(info.Items.shift());
|
|
72
|
+
}
|
|
73
|
+
if (!items.length) {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
let params = {
|
|
77
|
+
RequestItems: {}
|
|
78
|
+
};
|
|
79
|
+
params.RequestItems[target] = items.map(Item => ({ PutRequest: { Item } }));
|
|
80
|
+
await db.batchWriteItem(params);
|
|
81
|
+
output.incrementProgress(items.length, "copyTable");
|
|
82
|
+
} while (true);
|
|
83
|
+
ExclusiveStartKey = info.LastEvaluatedKey;
|
|
84
|
+
} while (ExclusiveStartKey);
|
|
100
85
|
}
|
|
101
86
|
/**
|
|
102
87
|
* @inheritdoc
|
|
103
88
|
*/
|
|
104
|
-
exists(uid) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return (yield this._get(uid)) !== undefined;
|
|
108
|
-
});
|
|
89
|
+
async exists(uid) {
|
|
90
|
+
// Should use find + limit 1
|
|
91
|
+
return (await this._get(uid)) !== undefined;
|
|
109
92
|
}
|
|
110
93
|
/**
|
|
111
94
|
* @inheritdoc
|
|
112
95
|
*/
|
|
113
|
-
_save(object, uid = object.uuid) {
|
|
114
|
-
return
|
|
115
|
-
return this._update(object, uid);
|
|
116
|
-
});
|
|
96
|
+
async _save(object, uid = object.uuid) {
|
|
97
|
+
return this._update(object, uid);
|
|
117
98
|
}
|
|
118
99
|
/**
|
|
119
100
|
* @override
|
|
@@ -121,160 +102,158 @@ class DynamoStore extends core_1.Store {
|
|
|
121
102
|
* @see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html
|
|
122
103
|
* @see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html
|
|
123
104
|
*/
|
|
124
|
-
find(query) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
105
|
+
async find(query) {
|
|
106
|
+
let scan = true;
|
|
107
|
+
let IndexName = undefined;
|
|
108
|
+
let result;
|
|
109
|
+
let primaryKeys = { uuid: null };
|
|
110
|
+
Object.keys(this.parameters.globalIndexes).forEach(name => {
|
|
111
|
+
primaryKeys[this.parameters.globalIndexes[name].key] = name;
|
|
112
|
+
});
|
|
113
|
+
// We could use PartQL but localstack is not compatible
|
|
114
|
+
let filter = new WebdaQL.AndExpression([]);
|
|
115
|
+
let KeyConditionExpression = "";
|
|
116
|
+
let ExpressionAttributeValues = {};
|
|
117
|
+
let FilterExpression = [];
|
|
118
|
+
let ExpressionAttributeNames = {};
|
|
119
|
+
let indexNode;
|
|
120
|
+
let sortOrder = "ASC";
|
|
121
|
+
let processingExpression;
|
|
122
|
+
if (!(query.filter instanceof WebdaQL.AndExpression)) {
|
|
123
|
+
processingExpression = new WebdaQL.AndExpression([query.filter]);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
processingExpression = query.filter;
|
|
127
|
+
}
|
|
128
|
+
// Search for the index
|
|
129
|
+
processingExpression.children.some(child => {
|
|
130
|
+
if (child instanceof WebdaQL.ComparisonExpression) {
|
|
131
|
+
// Primary key requires equal operator
|
|
132
|
+
if (child.operator === "=" && primaryKeys[child.attribute[0]] !== undefined) {
|
|
133
|
+
// Query not scan
|
|
134
|
+
scan = false;
|
|
135
|
+
IndexName = primaryKeys[child.attribute[0]];
|
|
136
|
+
indexNode = child;
|
|
137
|
+
KeyConditionExpression = `#${child.attribute[0]} = :${child.attribute[0]}`;
|
|
138
|
+
ExpressionAttributeNames[`#${child.attribute[0]}`] = child.attribute[0];
|
|
139
|
+
ExpressionAttributeValues[`:${child.attribute[0]}`] = child.value;
|
|
140
|
+
if (primaryKeys[child.attribute[0]] !== null &&
|
|
141
|
+
query.orderBy &&
|
|
142
|
+
this.parameters.globalIndexes[primaryKeys[child.attribute[0]]].sort) {
|
|
143
|
+
const sortKey = this.parameters.globalIndexes[primaryKeys[child.attribute[0]]].sort;
|
|
144
|
+
// Might update sort order
|
|
145
|
+
query.orderBy.some(order => {
|
|
146
|
+
if (order.field === sortKey) {
|
|
147
|
+
sortOrder = order.direction;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
144
153
|
}
|
|
145
|
-
|
|
146
|
-
|
|
154
|
+
});
|
|
155
|
+
let count = 1;
|
|
156
|
+
// Build the Query/Filter
|
|
157
|
+
processingExpression.children.forEach(child => {
|
|
158
|
+
if (child === indexNode) {
|
|
159
|
+
return;
|
|
147
160
|
}
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
IndexName = primaryKeys[child.attribute[0]];
|
|
156
|
-
indexNode = child;
|
|
157
|
-
KeyConditionExpression = `#${child.attribute[0]} = :${child.attribute[0]}`;
|
|
158
|
-
ExpressionAttributeNames[`#${child.attribute[0]}`] = child.attribute[0];
|
|
159
|
-
ExpressionAttributeValues[`:${child.attribute[0]}`] = child.value;
|
|
160
|
-
if (primaryKeys[child.attribute[0]] !== null &&
|
|
161
|
-
query.orderBy &&
|
|
162
|
-
this.parameters.globalIndexes[primaryKeys[child.attribute[0]]].sort) {
|
|
163
|
-
const sortKey = this.parameters.globalIndexes[primaryKeys[child.attribute[0]]].sort;
|
|
164
|
-
// Might update sort order
|
|
165
|
-
query.orderBy.some(order => {
|
|
166
|
-
if (order.field === sortKey) {
|
|
167
|
-
sortOrder = order.direction;
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
161
|
+
// Only work on Comparison Node for now
|
|
162
|
+
if (child instanceof WebdaQL.ComparisonExpression) {
|
|
163
|
+
let operator = child.operator;
|
|
164
|
+
// DynamoDB does not manage LIKE
|
|
165
|
+
if (child.operator === "LIKE") {
|
|
166
|
+
filter.children.push(child);
|
|
167
|
+
return;
|
|
173
168
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
169
|
+
// != is <> in Dynamo
|
|
170
|
+
if (operator === "!=") {
|
|
171
|
+
operator = "<>";
|
|
172
|
+
}
|
|
173
|
+
// DynamoDB does not allow more than 100 items in IN
|
|
174
|
+
if (child.operator === "IN" && child.value.length > 100) {
|
|
175
|
+
filter.children.push(child);
|
|
179
176
|
return;
|
|
180
177
|
}
|
|
181
|
-
//
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
let attr = `a${count++}`;
|
|
200
|
-
let fullAttr = `#${attr}`;
|
|
201
|
-
child.attribute.splice(1).forEach(v => {
|
|
202
|
-
let subAttr = `#a${count++}`;
|
|
203
|
-
fullAttr += `.${subAttr}`;
|
|
204
|
-
ExpressionAttributeNames[subAttr] = v;
|
|
178
|
+
// Subfields like team.id needs to be #a1.#a2
|
|
179
|
+
let attr = `a${count++}`;
|
|
180
|
+
let fullAttr = `#${attr}`;
|
|
181
|
+
child.attribute.splice(1).forEach(v => {
|
|
182
|
+
let subAttr = `#a${count++}`;
|
|
183
|
+
fullAttr += `.${subAttr}`;
|
|
184
|
+
ExpressionAttributeNames[subAttr] = v;
|
|
185
|
+
});
|
|
186
|
+
ExpressionAttributeNames[`#${attr}`] = child.attribute[0];
|
|
187
|
+
let valueExpression = `:${attr}`;
|
|
188
|
+
if (child.operator === "IN") {
|
|
189
|
+
// Need to follow `a IN (b, c, d)
|
|
190
|
+
valueExpression = "(" + valueExpression;
|
|
191
|
+
ExpressionAttributeValues[`:${attr}`] = child.value[0];
|
|
192
|
+
child.value.splice(1).forEach(v => {
|
|
193
|
+
let subAttr = `:a${count++}`;
|
|
194
|
+
valueExpression += `, ${subAttr}`;
|
|
195
|
+
ExpressionAttributeValues[subAttr] = v;
|
|
205
196
|
});
|
|
206
|
-
|
|
207
|
-
let valueExpression = `:${attr}`;
|
|
208
|
-
if (child.operator === "IN") {
|
|
209
|
-
// Need to follow `a IN (b, c, d)
|
|
210
|
-
valueExpression = "(" + valueExpression;
|
|
211
|
-
ExpressionAttributeValues[`:${attr}`] = child.value[0];
|
|
212
|
-
child.value.splice(1).forEach(v => {
|
|
213
|
-
let subAttr = `:a${count++}`;
|
|
214
|
-
valueExpression += `, ${subAttr}`;
|
|
215
|
-
ExpressionAttributeValues[subAttr] = v;
|
|
216
|
-
});
|
|
217
|
-
valueExpression += ")";
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
// For all other just give the value
|
|
221
|
-
ExpressionAttributeValues[`:${attr}`] = child.value;
|
|
222
|
-
}
|
|
223
|
-
// If this is a sort key
|
|
224
|
-
if (IndexName && this.parameters.globalIndexes[IndexName].sort === child.attribute[0]) {
|
|
225
|
-
// Sort key
|
|
226
|
-
KeyConditionExpression += ` AND ${fullAttr} ${operator} ${valueExpression}`;
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
// Otherwise fallback to normal Filter
|
|
230
|
-
FilterExpression.push(`${fullAttr} ${operator} ${valueExpression}`);
|
|
197
|
+
valueExpression += ")";
|
|
231
198
|
}
|
|
232
199
|
else {
|
|
233
|
-
|
|
200
|
+
// For all other just give the value
|
|
201
|
+
ExpressionAttributeValues[`:${attr}`] = child.value;
|
|
234
202
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
? JSON.parse(Buffer.from(query.continuationToken, "base64").toString())
|
|
244
|
-
: undefined;
|
|
245
|
-
// Scan if not primary key was provided
|
|
246
|
-
if (scan) {
|
|
247
|
-
// SHould log bad query
|
|
248
|
-
result = yield this._client.scan({
|
|
249
|
-
TableName: this.parameters.table,
|
|
250
|
-
FilterExpression: FilterExpression.length ? FilterExpression.join(" AND ") : undefined,
|
|
251
|
-
ExclusiveStartKey,
|
|
252
|
-
ExpressionAttributeNames,
|
|
253
|
-
ExpressionAttributeValues,
|
|
254
|
-
Limit: query.limit
|
|
255
|
-
});
|
|
203
|
+
// If this is a sort key
|
|
204
|
+
if (IndexName && this.parameters.globalIndexes[IndexName].sort === child.attribute[0]) {
|
|
205
|
+
// Sort key
|
|
206
|
+
KeyConditionExpression += ` AND ${fullAttr} ${operator} ${valueExpression}`;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
// Otherwise fallback to normal Filter
|
|
210
|
+
FilterExpression.push(`${fullAttr} ${operator} ${valueExpression}`);
|
|
256
211
|
}
|
|
257
212
|
else {
|
|
258
|
-
|
|
259
|
-
TableName: this.parameters.table,
|
|
260
|
-
IndexName,
|
|
261
|
-
ExclusiveStartKey,
|
|
262
|
-
KeyConditionExpression,
|
|
263
|
-
FilterExpression: FilterExpression.length ? FilterExpression.join(" AND ") : undefined,
|
|
264
|
-
ExpressionAttributeNames,
|
|
265
|
-
ExpressionAttributeValues,
|
|
266
|
-
Limit: query.limit,
|
|
267
|
-
ScanIndexForward: sortOrder === "ASC" ? true : false
|
|
268
|
-
});
|
|
213
|
+
filter.children.push(child);
|
|
269
214
|
}
|
|
270
|
-
return {
|
|
271
|
-
results: result.Items.map(c => this.initModel(c)),
|
|
272
|
-
filter,
|
|
273
|
-
continuationToken: result.Items.length >= query.limit
|
|
274
|
-
? Buffer.from(JSON.stringify(result.LastEvaluatedKey)).toString("base64")
|
|
275
|
-
: undefined
|
|
276
|
-
};
|
|
277
215
|
});
|
|
216
|
+
if (!Object.keys(ExpressionAttributeNames).length) {
|
|
217
|
+
ExpressionAttributeNames = undefined;
|
|
218
|
+
}
|
|
219
|
+
if (!Object.keys(ExpressionAttributeValues).length) {
|
|
220
|
+
ExpressionAttributeValues = undefined;
|
|
221
|
+
}
|
|
222
|
+
const ExclusiveStartKey = query.continuationToken
|
|
223
|
+
? JSON.parse(Buffer.from(query.continuationToken, "base64").toString())
|
|
224
|
+
: undefined;
|
|
225
|
+
// Scan if not primary key was provided
|
|
226
|
+
if (scan) {
|
|
227
|
+
// SHould log bad query
|
|
228
|
+
result = await this._client.scan({
|
|
229
|
+
TableName: this.parameters.table,
|
|
230
|
+
FilterExpression: FilterExpression.length ? FilterExpression.join(" AND ") : undefined,
|
|
231
|
+
ExclusiveStartKey,
|
|
232
|
+
ExpressionAttributeNames,
|
|
233
|
+
ExpressionAttributeValues,
|
|
234
|
+
Limit: query.limit
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
result = await this._client.query({
|
|
239
|
+
TableName: this.parameters.table,
|
|
240
|
+
IndexName,
|
|
241
|
+
ExclusiveStartKey,
|
|
242
|
+
KeyConditionExpression,
|
|
243
|
+
FilterExpression: FilterExpression.length ? FilterExpression.join(" AND ") : undefined,
|
|
244
|
+
ExpressionAttributeNames,
|
|
245
|
+
ExpressionAttributeValues,
|
|
246
|
+
Limit: query.limit,
|
|
247
|
+
ScanIndexForward: sortOrder === "ASC" ? true : false
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
results: result.Items.map(c => this.initModel(c)),
|
|
252
|
+
filter,
|
|
253
|
+
continuationToken: result.Items.length >= query.limit
|
|
254
|
+
? Buffer.from(JSON.stringify(result.LastEvaluatedKey)).toString("base64")
|
|
255
|
+
: undefined
|
|
256
|
+
};
|
|
278
257
|
}
|
|
279
258
|
/**
|
|
280
259
|
* Serialize a date for DynamoDB
|
|
@@ -296,10 +275,10 @@ class DynamoStore extends core_1.Store {
|
|
|
296
275
|
if (object instanceof Date) {
|
|
297
276
|
return this._serializeDate(object);
|
|
298
277
|
}
|
|
299
|
-
if (object instanceof
|
|
278
|
+
if (object instanceof CoreModel) {
|
|
300
279
|
object = object.toStoredJSON();
|
|
301
280
|
}
|
|
302
|
-
|
|
281
|
+
let res;
|
|
303
282
|
if (object instanceof Array) {
|
|
304
283
|
res = [];
|
|
305
284
|
}
|
|
@@ -317,139 +296,133 @@ class DynamoStore extends core_1.Store {
|
|
|
317
296
|
/**
|
|
318
297
|
* @inheritdoc
|
|
319
298
|
*/
|
|
320
|
-
_removeAttribute(uuid, attribute, itemWriteCondition, itemWriteConditionField) {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
uuid
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
var attrs = {};
|
|
329
|
-
attrs["#attr"] = attribute;
|
|
330
|
-
attrs["#lastUpdate"] = this._lastUpdateField;
|
|
331
|
-
params.ExpressionAttributeNames = attrs;
|
|
332
|
-
params.ConditionExpression = "attribute_exists(#uu)";
|
|
333
|
-
params.ExpressionAttributeValues = {
|
|
334
|
-
":lastUpdate": this._serializeDate(new Date())
|
|
335
|
-
};
|
|
336
|
-
params.UpdateExpression = "REMOVE #attr SET #lastUpdate = :lastUpdate";
|
|
337
|
-
if (itemWriteCondition) {
|
|
338
|
-
this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
|
|
339
|
-
}
|
|
340
|
-
else {
|
|
341
|
-
attrs["#uu"] = "uuid";
|
|
342
|
-
params.ConditionExpression = "attribute_exists(#uu)";
|
|
343
|
-
}
|
|
344
|
-
try {
|
|
345
|
-
yield this._client.update(params);
|
|
299
|
+
async _removeAttribute(uuid, attribute, itemWriteCondition, itemWriteConditionField) {
|
|
300
|
+
let params = {
|
|
301
|
+
TableName: this.parameters.table,
|
|
302
|
+
Key: {
|
|
303
|
+
uuid
|
|
346
304
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
305
|
+
};
|
|
306
|
+
let attrs = {};
|
|
307
|
+
attrs["#attr"] = attribute;
|
|
308
|
+
attrs["#lastUpdate"] = this._lastUpdateField;
|
|
309
|
+
params.ExpressionAttributeNames = attrs;
|
|
310
|
+
params.ConditionExpression = "attribute_exists(#uu)";
|
|
311
|
+
params.ExpressionAttributeValues = {
|
|
312
|
+
":lastUpdate": this._serializeDate(new Date())
|
|
313
|
+
};
|
|
314
|
+
params.UpdateExpression = "REMOVE #attr SET #lastUpdate = :lastUpdate";
|
|
315
|
+
if (itemWriteCondition) {
|
|
316
|
+
this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
attrs["#uu"] = "uuid";
|
|
320
|
+
params.ConditionExpression = "attribute_exists(#uu)";
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
await this._client.update(params);
|
|
324
|
+
}
|
|
325
|
+
catch (err) {
|
|
326
|
+
if (err instanceof ConditionalCheckFailedException) {
|
|
327
|
+
if (!itemWriteConditionField) {
|
|
328
|
+
throw new StoreNotFoundError(uuid, this.getName());
|
|
353
329
|
}
|
|
354
|
-
throw
|
|
330
|
+
throw new UpdateConditionFailError(uuid, itemWriteConditionField, itemWriteCondition);
|
|
355
331
|
}
|
|
356
|
-
|
|
332
|
+
throw err;
|
|
333
|
+
}
|
|
357
334
|
}
|
|
358
335
|
/**
|
|
359
336
|
* @inheritdoc
|
|
360
337
|
*/
|
|
361
|
-
_deleteItemFromCollection(uid, prop, index, itemWriteCondition, itemWriteConditionField, updateDate) {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
uuid: uid
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
var attrs = {};
|
|
370
|
-
attrs["#" + prop] = prop;
|
|
371
|
-
attrs["#lastUpdate"] = this._lastUpdateField;
|
|
372
|
-
params.ExpressionAttributeNames = attrs;
|
|
373
|
-
params.ExpressionAttributeValues = {
|
|
374
|
-
":lastUpdate": this._serializeDate(updateDate)
|
|
375
|
-
};
|
|
376
|
-
params.UpdateExpression = "REMOVE #" + prop + "[" + index + "] SET #lastUpdate = :lastUpdate";
|
|
377
|
-
if (itemWriteCondition) {
|
|
378
|
-
params.ExpressionAttributeValues[":condValue"] = itemWriteCondition;
|
|
379
|
-
attrs["#condName"] = prop;
|
|
380
|
-
attrs["#field"] = itemWriteConditionField;
|
|
381
|
-
params.ConditionExpression = "#condName[" + index + "].#field = :condValue";
|
|
338
|
+
async _deleteItemFromCollection(uid, prop, index, itemWriteCondition, itemWriteConditionField, updateDate) {
|
|
339
|
+
let params = {
|
|
340
|
+
TableName: this.parameters.table,
|
|
341
|
+
Key: {
|
|
342
|
+
uuid: uid
|
|
382
343
|
}
|
|
383
|
-
|
|
384
|
-
|
|
344
|
+
};
|
|
345
|
+
let attrs = {};
|
|
346
|
+
attrs["#" + prop] = prop;
|
|
347
|
+
attrs["#lastUpdate"] = this._lastUpdateField;
|
|
348
|
+
params.ExpressionAttributeNames = attrs;
|
|
349
|
+
params.ExpressionAttributeValues = {
|
|
350
|
+
":lastUpdate": this._serializeDate(updateDate)
|
|
351
|
+
};
|
|
352
|
+
params.UpdateExpression = "REMOVE #" + prop + "[" + index + "] SET #lastUpdate = :lastUpdate";
|
|
353
|
+
if (itemWriteCondition) {
|
|
354
|
+
params.ExpressionAttributeValues[":condValue"] = itemWriteCondition;
|
|
355
|
+
attrs["#condName"] = prop;
|
|
356
|
+
attrs["#field"] = itemWriteConditionField;
|
|
357
|
+
params.ConditionExpression = "#condName[" + index + "].#field = :condValue";
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
await this._client.update(params);
|
|
361
|
+
}
|
|
362
|
+
catch (err) {
|
|
363
|
+
if (err instanceof ConditionalCheckFailedException) {
|
|
364
|
+
throw new UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
|
|
385
365
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
throw new core_1.UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
|
|
389
|
-
}
|
|
390
|
-
else if (err.name === "ValidationException") {
|
|
391
|
-
throw new core_1.StoreNotFoundError(uid, this.getName());
|
|
392
|
-
}
|
|
393
|
-
throw err;
|
|
366
|
+
else if (err.name === "ValidationException") {
|
|
367
|
+
throw new StoreNotFoundError(uid, this.getName());
|
|
394
368
|
}
|
|
395
|
-
|
|
369
|
+
throw err;
|
|
370
|
+
}
|
|
396
371
|
}
|
|
397
372
|
/**
|
|
398
373
|
* @inheritdoc
|
|
399
374
|
*/
|
|
400
|
-
_upsertItemToCollection(uuid, prop, item, index, itemWriteCondition, itemWriteConditionField, updateDate) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
uuid
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
var attrValues = {};
|
|
409
|
-
var attrs = {};
|
|
410
|
-
attrs["#" + prop] = prop;
|
|
411
|
-
attrs["#lastUpdate"] = this._lastUpdateField;
|
|
412
|
-
attrValues[":" + prop] = this._cleanObject(item);
|
|
413
|
-
attrValues[":lastUpdate"] = this._serializeDate(updateDate);
|
|
414
|
-
attrValues[":uuid"] = uuid;
|
|
415
|
-
attrs["#uuid"] = this._uuidField;
|
|
416
|
-
params.ConditionExpression = "#uuid = :uuid";
|
|
417
|
-
params.ExpressionAttributeValues = attrValues;
|
|
418
|
-
params.ExpressionAttributeNames = attrs;
|
|
419
|
-
if (index === undefined) {
|
|
420
|
-
params.UpdateExpression =
|
|
421
|
-
"SET #" +
|
|
422
|
-
prop +
|
|
423
|
-
"= list_append(if_not_exists (#" +
|
|
424
|
-
prop +
|
|
425
|
-
", :empty_list),:" +
|
|
426
|
-
prop +
|
|
427
|
-
"), #lastUpdate = :lastUpdate";
|
|
428
|
-
attrValues[":" + prop] = [attrValues[":" + prop]];
|
|
429
|
-
attrValues[":empty_list"] = [];
|
|
375
|
+
async _upsertItemToCollection(uuid, prop, item, index, itemWriteCondition, itemWriteConditionField, updateDate) {
|
|
376
|
+
let params = {
|
|
377
|
+
TableName: this.parameters.table,
|
|
378
|
+
Key: {
|
|
379
|
+
uuid
|
|
430
380
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
381
|
+
};
|
|
382
|
+
let attrValues = {};
|
|
383
|
+
let attrs = {};
|
|
384
|
+
attrs["#" + prop] = prop;
|
|
385
|
+
attrs["#lastUpdate"] = this._lastUpdateField;
|
|
386
|
+
attrValues[":" + prop] = this._cleanObject(item);
|
|
387
|
+
attrValues[":lastUpdate"] = this._serializeDate(updateDate);
|
|
388
|
+
attrValues[":uuid"] = uuid;
|
|
389
|
+
attrs["#uuid"] = this._uuidField;
|
|
390
|
+
params.ConditionExpression = "#uuid = :uuid";
|
|
391
|
+
params.ExpressionAttributeValues = attrValues;
|
|
392
|
+
params.ExpressionAttributeNames = attrs;
|
|
393
|
+
if (index === undefined) {
|
|
394
|
+
params.UpdateExpression =
|
|
395
|
+
"SET #" +
|
|
396
|
+
prop +
|
|
397
|
+
"= list_append(if_not_exists (#" +
|
|
398
|
+
prop +
|
|
399
|
+
", :empty_list),:" +
|
|
400
|
+
prop +
|
|
401
|
+
"), #lastUpdate = :lastUpdate";
|
|
402
|
+
attrValues[":" + prop] = [attrValues[":" + prop]];
|
|
403
|
+
attrValues[":empty_list"] = [];
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
params.UpdateExpression = "SET #" + prop + "[" + index + "] = :" + prop + ", #lastUpdate = :lastUpdate";
|
|
407
|
+
if (itemWriteCondition) {
|
|
408
|
+
attrValues[":condValue"] = itemWriteCondition;
|
|
409
|
+
attrs["#condName"] = prop;
|
|
410
|
+
attrs["#field"] = itemWriteConditionField;
|
|
411
|
+
params.ConditionExpression = "#condName[" + index + "].#field = :condValue and #uuid = :uuid";
|
|
439
412
|
}
|
|
440
|
-
|
|
441
|
-
|
|
413
|
+
}
|
|
414
|
+
try {
|
|
415
|
+
await this._client.update(params);
|
|
416
|
+
}
|
|
417
|
+
catch (err) {
|
|
418
|
+
if (err instanceof ConditionalCheckFailedException) {
|
|
419
|
+
throw new UpdateConditionFailError(uuid, itemWriteConditionField, itemWriteCondition);
|
|
442
420
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
throw new core_1.UpdateConditionFailError(uuid, itemWriteConditionField, itemWriteCondition);
|
|
446
|
-
}
|
|
447
|
-
else if (err.name === "ValidationException") {
|
|
448
|
-
throw new core_1.StoreNotFoundError(uuid, this.getName());
|
|
449
|
-
}
|
|
450
|
-
throw err;
|
|
421
|
+
else if (err.name === "ValidationException") {
|
|
422
|
+
throw new StoreNotFoundError(uuid, this.getName());
|
|
451
423
|
}
|
|
452
|
-
|
|
424
|
+
throw err;
|
|
425
|
+
}
|
|
453
426
|
}
|
|
454
427
|
/**
|
|
455
428
|
* REturn the write condition as string
|
|
@@ -458,9 +431,8 @@ class DynamoStore extends core_1.Store {
|
|
|
458
431
|
* @returns
|
|
459
432
|
*/
|
|
460
433
|
setWriteCondition(params, writeCondition, field = this._lastUpdateField) {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
(_b = params.ExpressionAttributeValues) !== null && _b !== void 0 ? _b : (params.ExpressionAttributeValues = {});
|
|
434
|
+
params.ExpressionAttributeNames ?? (params.ExpressionAttributeNames = {});
|
|
435
|
+
params.ExpressionAttributeValues ?? (params.ExpressionAttributeValues = {});
|
|
464
436
|
params.ExpressionAttributeNames["#cf"] = field;
|
|
465
437
|
if (writeCondition instanceof Date) {
|
|
466
438
|
writeCondition = this._serializeDate(writeCondition);
|
|
@@ -471,199 +443,185 @@ class DynamoStore extends core_1.Store {
|
|
|
471
443
|
/**
|
|
472
444
|
* @inheritdoc
|
|
473
445
|
*/
|
|
474
|
-
_delete(uid, writeCondition, itemWriteConditionField) {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
uuid: uid
|
|
480
|
-
}
|
|
481
|
-
};
|
|
482
|
-
if (writeCondition) {
|
|
483
|
-
this.setWriteCondition(params, writeCondition, itemWriteConditionField);
|
|
484
|
-
}
|
|
485
|
-
try {
|
|
486
|
-
yield this._client.delete(params);
|
|
446
|
+
async _delete(uid, writeCondition, itemWriteConditionField) {
|
|
447
|
+
let params = {
|
|
448
|
+
TableName: this.parameters.table,
|
|
449
|
+
Key: {
|
|
450
|
+
uuid: uid
|
|
487
451
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
452
|
+
};
|
|
453
|
+
if (writeCondition) {
|
|
454
|
+
this.setWriteCondition(params, writeCondition, itemWriteConditionField);
|
|
455
|
+
}
|
|
456
|
+
try {
|
|
457
|
+
await this._client.delete(params);
|
|
458
|
+
}
|
|
459
|
+
catch (err) {
|
|
460
|
+
if (err instanceof ConditionalCheckFailedException) {
|
|
461
|
+
throw new UpdateConditionFailError(uid, itemWriteConditionField, writeCondition);
|
|
493
462
|
}
|
|
494
|
-
|
|
463
|
+
throw err;
|
|
464
|
+
}
|
|
495
465
|
}
|
|
496
466
|
/**
|
|
497
467
|
* @inheritdoc
|
|
498
468
|
*/
|
|
499
|
-
_patch(object, uid, itemWriteCondition, itemWriteConditionField) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
continue;
|
|
511
|
-
}
|
|
512
|
-
skipUpdate = false;
|
|
513
|
-
expr += sep + "#a" + i + " = :v" + i;
|
|
514
|
-
attrValues[":v" + i] = object[attr];
|
|
515
|
-
attrs["#a" + i] = attr;
|
|
516
|
-
sep = ",";
|
|
517
|
-
i++;
|
|
518
|
-
}
|
|
519
|
-
if (skipUpdate) {
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
var params = {
|
|
523
|
-
TableName: this.parameters.table,
|
|
524
|
-
Key: {
|
|
525
|
-
uuid: uid
|
|
526
|
-
},
|
|
527
|
-
UpdateExpression: expr,
|
|
528
|
-
ExpressionAttributeValues: attrValues,
|
|
529
|
-
ExpressionAttributeNames: attrs
|
|
530
|
-
};
|
|
531
|
-
// The Write Condition checks the value before writing
|
|
532
|
-
if (itemWriteCondition) {
|
|
533
|
-
this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
|
|
534
|
-
}
|
|
535
|
-
try {
|
|
536
|
-
yield this._client.update(params);
|
|
469
|
+
async _patch(object, uid, itemWriteCondition, itemWriteConditionField) {
|
|
470
|
+
object = this._cleanObject(object);
|
|
471
|
+
let expr = "SET ";
|
|
472
|
+
let sep = "";
|
|
473
|
+
let attrValues = {};
|
|
474
|
+
let attrs = {};
|
|
475
|
+
let skipUpdate = true;
|
|
476
|
+
let i = 1;
|
|
477
|
+
for (let attr in object) {
|
|
478
|
+
if (attr === "uuid" || object[attr] === undefined) {
|
|
479
|
+
continue;
|
|
537
480
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
481
|
+
skipUpdate = false;
|
|
482
|
+
expr += sep + "#a" + i + " = :v" + i;
|
|
483
|
+
attrValues[":v" + i] = object[attr];
|
|
484
|
+
attrs["#a" + i] = attr;
|
|
485
|
+
sep = ",";
|
|
486
|
+
i++;
|
|
487
|
+
}
|
|
488
|
+
if (skipUpdate) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
let params = {
|
|
492
|
+
TableName: this.parameters.table,
|
|
493
|
+
Key: {
|
|
494
|
+
uuid: uid
|
|
495
|
+
},
|
|
496
|
+
UpdateExpression: expr,
|
|
497
|
+
ExpressionAttributeValues: attrValues,
|
|
498
|
+
ExpressionAttributeNames: attrs
|
|
499
|
+
};
|
|
500
|
+
// The Write Condition checks the value before writing
|
|
501
|
+
if (itemWriteCondition) {
|
|
502
|
+
this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
|
|
503
|
+
}
|
|
504
|
+
try {
|
|
505
|
+
await this._client.update(params);
|
|
506
|
+
}
|
|
507
|
+
catch (err) {
|
|
508
|
+
if (err instanceof ConditionalCheckFailedException) {
|
|
509
|
+
throw new UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
|
|
543
510
|
}
|
|
544
|
-
|
|
511
|
+
throw err;
|
|
512
|
+
}
|
|
545
513
|
}
|
|
546
514
|
/**
|
|
547
515
|
* @inheritdoc
|
|
548
516
|
*/
|
|
549
|
-
_update(object, uid, itemWriteCondition, itemWriteConditionField) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
throw new core_1.UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
|
|
568
|
-
}
|
|
569
|
-
throw err;
|
|
517
|
+
async _update(object, uid, itemWriteCondition, itemWriteConditionField) {
|
|
518
|
+
object = this._cleanObject(object);
|
|
519
|
+
object.uuid = uid;
|
|
520
|
+
let params = {
|
|
521
|
+
TableName: this.parameters.table,
|
|
522
|
+
Item: object
|
|
523
|
+
};
|
|
524
|
+
// The Write Condition checks the value before writing
|
|
525
|
+
if (itemWriteCondition) {
|
|
526
|
+
this.setWriteCondition(params, itemWriteCondition, itemWriteConditionField);
|
|
527
|
+
}
|
|
528
|
+
try {
|
|
529
|
+
await this._client.put(params);
|
|
530
|
+
return object;
|
|
531
|
+
}
|
|
532
|
+
catch (err) {
|
|
533
|
+
if (err instanceof ConditionalCheckFailedException) {
|
|
534
|
+
throw new UpdateConditionFailError(uid, itemWriteConditionField, itemWriteCondition);
|
|
570
535
|
}
|
|
571
|
-
|
|
536
|
+
throw err;
|
|
537
|
+
}
|
|
572
538
|
}
|
|
573
539
|
/**
|
|
574
540
|
* @inheritdoc
|
|
575
541
|
*/
|
|
576
|
-
_scan(items = [], paging = undefined) {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
ExclusiveStartKey: paging
|
|
582
|
-
});
|
|
583
|
-
for (let i in data.Items) {
|
|
584
|
-
items.push(this.initModel(data.Items[i]));
|
|
585
|
-
}
|
|
586
|
-
if (data.LastEvaluatedKey) {
|
|
587
|
-
return this._scan(items, data.LastEvaluatedKey);
|
|
588
|
-
}
|
|
589
|
-
return items;
|
|
542
|
+
async _scan(items = [], paging = undefined) {
|
|
543
|
+
let data = await this._client.scan({
|
|
544
|
+
TableName: this.parameters.table,
|
|
545
|
+
Limit: this.parameters.scanPage,
|
|
546
|
+
ExclusiveStartKey: paging
|
|
590
547
|
});
|
|
548
|
+
for (let i in data.Items) {
|
|
549
|
+
items.push(this.initModel(data.Items[i]));
|
|
550
|
+
}
|
|
551
|
+
if (data.LastEvaluatedKey) {
|
|
552
|
+
return this._scan(items, data.LastEvaluatedKey);
|
|
553
|
+
}
|
|
554
|
+
return items;
|
|
591
555
|
}
|
|
592
556
|
/**
|
|
593
557
|
* @inheritdoc
|
|
594
558
|
*/
|
|
595
|
-
getAll(uids) {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
return result.Responses[this.parameters.table].map(this.initModel, this);
|
|
612
|
-
});
|
|
559
|
+
async getAll(uids) {
|
|
560
|
+
if (!uids) {
|
|
561
|
+
return this._scan([]);
|
|
562
|
+
}
|
|
563
|
+
let params = {
|
|
564
|
+
RequestItems: {}
|
|
565
|
+
};
|
|
566
|
+
params["RequestItems"][this.parameters.table] = {
|
|
567
|
+
Keys: uids.map(value => {
|
|
568
|
+
return {
|
|
569
|
+
uuid: value
|
|
570
|
+
};
|
|
571
|
+
})
|
|
572
|
+
};
|
|
573
|
+
let result = await this._client.batchGet(params);
|
|
574
|
+
return result.Responses[this.parameters.table].map(this.initModel, this);
|
|
613
575
|
}
|
|
614
576
|
/**
|
|
615
577
|
* @inheritdoc
|
|
616
578
|
*/
|
|
617
|
-
_get(uid, raiseIfNotFound = false) {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
uuid: uid
|
|
623
|
-
}
|
|
624
|
-
};
|
|
625
|
-
let item = (yield this._client.get(params)).Item;
|
|
626
|
-
if (!item) {
|
|
627
|
-
if (raiseIfNotFound) {
|
|
628
|
-
throw new core_1.StoreNotFoundError(uid, this.getName());
|
|
629
|
-
}
|
|
630
|
-
return undefined;
|
|
579
|
+
async _get(uid, raiseIfNotFound = false) {
|
|
580
|
+
let params = {
|
|
581
|
+
TableName: this.parameters.table,
|
|
582
|
+
Key: {
|
|
583
|
+
uuid: uid
|
|
631
584
|
}
|
|
632
|
-
|
|
633
|
-
|
|
585
|
+
};
|
|
586
|
+
let item = (await this._client.get(params)).Item;
|
|
587
|
+
if (!item) {
|
|
588
|
+
if (raiseIfNotFound) {
|
|
589
|
+
throw new StoreNotFoundError(uid, this.getName());
|
|
590
|
+
}
|
|
591
|
+
return undefined;
|
|
592
|
+
}
|
|
593
|
+
return this.initModel(item);
|
|
634
594
|
}
|
|
635
595
|
/**
|
|
636
596
|
* @inheritdoc
|
|
637
597
|
*/
|
|
638
|
-
_incrementAttribute(uid, prop, value, updateDate) {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
"#uu": "uuid"
|
|
655
|
-
}
|
|
656
|
-
};
|
|
657
|
-
try {
|
|
658
|
-
return yield this._client.update(params);
|
|
598
|
+
async _incrementAttribute(uid, prop, value, updateDate) {
|
|
599
|
+
let params = {
|
|
600
|
+
TableName: this.parameters.table,
|
|
601
|
+
Key: {
|
|
602
|
+
uuid: uid
|
|
603
|
+
},
|
|
604
|
+
UpdateExpression: "SET #a2 = :v2 ADD #a1 :v1",
|
|
605
|
+
ConditionExpression: "attribute_exists(#uu)",
|
|
606
|
+
ExpressionAttributeValues: {
|
|
607
|
+
":v1": value,
|
|
608
|
+
":v2": this._serializeDate(updateDate)
|
|
609
|
+
},
|
|
610
|
+
ExpressionAttributeNames: {
|
|
611
|
+
"#a1": prop,
|
|
612
|
+
"#a2": this._lastUpdateField,
|
|
613
|
+
"#uu": "uuid"
|
|
659
614
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
615
|
+
};
|
|
616
|
+
try {
|
|
617
|
+
return await this._client.update(params);
|
|
618
|
+
}
|
|
619
|
+
catch (err) {
|
|
620
|
+
if (err instanceof ConditionalCheckFailedException) {
|
|
621
|
+
throw new StoreNotFoundError(uid, this.getName());
|
|
665
622
|
}
|
|
666
|
-
|
|
623
|
+
throw err;
|
|
624
|
+
}
|
|
667
625
|
}
|
|
668
626
|
/**
|
|
669
627
|
* @inheritdoc
|
|
@@ -691,18 +649,16 @@ class DynamoStore extends core_1.Store {
|
|
|
691
649
|
/**
|
|
692
650
|
* @inheritdoc
|
|
693
651
|
*/
|
|
694
|
-
__clean() {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
yield Promise.all(promises);
|
|
705
|
-
});
|
|
652
|
+
async __clean() {
|
|
653
|
+
let params = {
|
|
654
|
+
TableName: this.parameters.table
|
|
655
|
+
};
|
|
656
|
+
let result = await this._client.scan(params);
|
|
657
|
+
let promises = [];
|
|
658
|
+
for (let i in result.Items) {
|
|
659
|
+
promises.push(this._delete(result.Items[i].uuid));
|
|
660
|
+
}
|
|
661
|
+
await Promise.all(promises);
|
|
706
662
|
}
|
|
707
663
|
/**
|
|
708
664
|
* @inheritdoc
|
|
@@ -721,13 +677,17 @@ class DynamoStore extends core_1.Store {
|
|
|
721
677
|
AttributeDefinitions.push({ AttributeName: "uuid", AttributeType: "S" });
|
|
722
678
|
resources[this._name + "DynamoTable"] = {
|
|
723
679
|
Type: "AWS::DynamoDB::Table",
|
|
724
|
-
Properties:
|
|
725
|
-
|
|
680
|
+
Properties: {
|
|
681
|
+
...this.parameters.CloudFormation.Table,
|
|
682
|
+
TableName: this.parameters.table,
|
|
683
|
+
KeySchema,
|
|
684
|
+
AttributeDefinitions,
|
|
685
|
+
Tags: deployer.getDefaultTags(this.parameters.CloudFormation.Table.Tags)
|
|
686
|
+
}
|
|
726
687
|
};
|
|
727
688
|
// Add any Other resources with prefix of the service
|
|
728
689
|
return resources;
|
|
729
690
|
}
|
|
730
691
|
}
|
|
731
|
-
|
|
732
|
-
exports.DynamoStore = DynamoStore;
|
|
692
|
+
export { DynamoStore };
|
|
733
693
|
//# sourceMappingURL=dynamodb.js.map
|