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