-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdbWrite.ts
More file actions
126 lines (115 loc) · 3.22 KB
/
dbWrite.ts
File metadata and controls
126 lines (115 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import {
PutCommand,
DeleteCommand,
UpdateCommand,
} from "@aws-sdk/lib-dynamodb";
import {
DynamoObject,
getMeta,
removeMeta,
sharedDynamoClient,
} from "./dynamoObject";
export async function putObject<T extends DynamoObject<T>>(object: T) {
return sharedDynamoClient.get().send(
new PutCommand({
TableName: getMeta(object).tableName,
Item: removeMeta(object),
})
);
}
export async function deleteObject<T extends DynamoObject<T>>(object: T) {
const {
tableName: TableName,
partitionKey: partitionKeyName,
sortKey: sortKeyName,
} = getMeta(object);
const Key: Record<string, any> = {};
Key[partitionKeyName as string] = object[partitionKeyName];
sortKeyName !== undefined &&
(Key[sortKeyName as string] = object[sortKeyName]);
return sharedDynamoClient.get().send(
new DeleteCommand({
TableName,
Key,
})
);
}
/// This will perform a partial update. Only setting the keys that are present.
/// Works with all keys regardless of being in the schema as attributes or not.
export async function updateObject<T extends DynamoObject<T>>(
object: T,
keyFilter?: (keyof T)[]
) {
const {
tableName: TableName,
partitionKey: partitionKeyName,
sortKey: sortKeyName,
} = getMeta(object);
object = removeMeta(object);
const keys = (keyFilter as string[]) ?? Object.keys(object);
let expr = "";
let ExpressionAttributeValues: any = {};
let ExpressionAttributeNames: any = {};
for (const key of keys) {
if (!key) continue;
if (typeof object[key as keyof T] === "function") continue;
if (typeof object[key as keyof T] === "undefined") continue;
if (key === partitionKeyName || key === sortKeyName) {
continue;
}
expr += `, #k_${key} = :${key}`;
ExpressionAttributeValues[`:${key}`] = object[key as keyof T];
ExpressionAttributeNames[`#k_${key}`] = key;
}
const Key = {
[partitionKeyName]: object[partitionKeyName],
};
if (sortKeyName) {
Key[sortKeyName as string] = object[sortKeyName];
}
const params = {
TableName,
Key,
UpdateExpression: `set${expr.slice(1)}`,
ExpressionAttributeValues,
ExpressionAttributeNames,
};
return sharedDynamoClient.get().send(new UpdateCommand(params));
}
/// This method will increment a key atomically even if it's not part of the schema.
export async function incrementObject<
T extends DynamoObject<T>,
K extends keyof T
>(
object: T,
incrementVariable: T[K] extends number ? K : never,
incrementValue = 1
) {
const {
partitionKey: partitionKeyName,
sortKey: sortKeyName,
tableName: TableName,
} = getMeta(object);
const Key: Record<string, any> = {
[partitionKeyName]: object[partitionKeyName],
};
if (sortKeyName) {
Key[sortKeyName as string] = object[sortKeyName];
}
return (
await sharedDynamoClient.get().send(
new UpdateCommand({
TableName,
Key,
UpdateExpression: `add #key :val`,
ExpressionAttributeNames: {
"#key": incrementVariable as string,
},
ExpressionAttributeValues: {
":val": incrementValue,
},
ReturnValues: "UPDATED_NEW",
})
)
).Attributes?.[incrementVariable as string] as number | undefined;
}