Skip to content

Commit e042379

Browse files
committed
fix(lib-dynamodb): remove unnecessary copying
1 parent 619d70a commit e042379

File tree

2 files changed

+14
-66
lines changed

2 files changed

+14
-66
lines changed

lib/lib-dynamodb/src/baseCommand/DynamoDBDocumentClientCommand.ts

Lines changed: 11 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -43,32 +43,25 @@ export abstract class DynamoDBDocumentClientCommand<
4343
marshallOptions.convertTopLevelContainer = marshallOptions.convertTopLevelContainer ?? true;
4444
unmarshallOptions.convertWithoutMapWrapper = unmarshallOptions.convertWithoutMapWrapper ?? true;
4545

46-
this.clientCommand.middlewareStack.add(
46+
this.clientCommand.middlewareStack.addRelativeTo(
4747
(next: InitializeHandler<Input | BaseInput, Output | BaseOutput>, context: HandlerExecutionContext) =>
4848
async (
4949
args: InitializeHandlerArguments<Input | BaseInput>
5050
): Promise<InitializeHandlerOutput<Output | BaseOutput>> => {
51+
setFeature(context, "DDB_MAPPER", "d");
5152
return next({
5253
...args,
53-
input: this.getCommandInput(),
54+
/**
55+
* We overwrite `args.input` at this middleware, but do not
56+
* mutate the args object itself, which is initially the Command instance.
57+
*
58+
* The reason for this is to prevent mutations to the Command instance's inputs
59+
* from being carried over if the Command instance is reused in a new
60+
* request.
61+
*/
62+
input: marshallInput(args.input, this.inputKeyNodes, marshallOptions),
5463
});
5564
},
56-
{
57-
name: "DocumentInitCopyInput",
58-
step: "initialize",
59-
priority: "high",
60-
override: true,
61-
}
62-
);
63-
this.clientCommand.middlewareStack.addRelativeTo(
64-
(next: InitializeHandler<Input | BaseInput, Output | BaseOutput>, context: HandlerExecutionContext) =>
65-
async (
66-
args: InitializeHandlerArguments<Input | BaseInput>
67-
): Promise<InitializeHandlerOutput<Output | BaseOutput>> => {
68-
setFeature(context, "DDB_MAPPER", "d");
69-
args.input = marshallInput(args.input, this.inputKeyNodes, marshallOptions);
70-
return next(args);
71-
},
7265
{
7366
name: "DocumentMarshall",
7467
relation: "before",
@@ -93,46 +86,4 @@ export abstract class DynamoDBDocumentClientCommand<
9386
}
9487
);
9588
}
96-
97-
/**
98-
* For snapshotting the user input as the request starts.
99-
* The reason for this is to prevent mutations to the Command instance's inputs
100-
* from being carried over if the Command instance is reused in a new
101-
* request.
102-
*/
103-
private getCommandInput(): Input | BaseInput {
104-
return this.documentClone(this.input);
105-
}
106-
107-
/**
108-
* Recursive clone of types applicable to DynamoDBDocument.
109-
*/
110-
private documentClone(it: any): any {
111-
if (it === null || it === undefined) {
112-
return it;
113-
}
114-
if (it instanceof Set) {
115-
return new Set(it.values());
116-
}
117-
if (it instanceof Map) {
118-
return new Map(it.entries());
119-
}
120-
if (typeof it === "object") {
121-
if (it instanceof NumberValue) {
122-
return new NumberValue(it.value);
123-
}
124-
if (it instanceof Uint8Array) {
125-
return new Uint8Array(it);
126-
}
127-
if (Array.isArray(it)) {
128-
return it.map((i) => this.documentClone(i));
129-
}
130-
const out = {} as any;
131-
for (const [key, value] of Object.entries(it)) {
132-
out[key] = this.documentClone(value);
133-
}
134-
return out;
135-
}
136-
return it;
137-
}
13889
}

lib/lib-dynamodb/src/test/mutability.integ.spec.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,9 @@ describe("DynamoDBDocument command mutability", () => {
8888
await doc.send(command);
8989

9090
// params should remain what it was set to by the caller,
91-
// disregarding middleware modifications and mutations
92-
// applied by the marshaller.
91+
// disregarding mutations applied by the AttributeValue marshaller.
9392
expect(params).toEqual({
94-
TableName: "test",
93+
TableName: "modified-by-middleware",
9594
FilterExpression: "id = :id",
9695
ExpressionAttributeValues: {
9796
":id": "1",
@@ -184,7 +183,7 @@ describe("DynamoDBDocument command mutability", () => {
184183
await ddb.send(command);
185184

186185
// for regular clients, middleware modifications to the
187-
// args.input object persist beyond the request.
186+
// args.input object also persist beyond the request.
188187
expect(params).toEqual({
189188
TableName: "modified-by-middleware",
190189
FilterExpression: "id = :id",
@@ -250,8 +249,6 @@ describe("DynamoDBDocument command mutability", () => {
250249
params.Bucket = `bucket4`;
251250
await s3.send(command);
252251

253-
// for regular clients, middleware modifications to the
254-
// args.input object persist beyond the request.
255252
expect(params).toEqual({
256253
Bucket: "bucket4",
257254
ExpectedBucketOwner: "me",

0 commit comments

Comments
 (0)