@@ -175,12 +175,12 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
175
175
_ = try await dynamodb. executeTransaction ( input: transactionInput)
176
176
}
177
177
178
- private func writeTransactionItems (
179
- _ entries: [ some PolymorphicWriteEntry ] , constraints: [ some PolymorphicTransactionConstraintEntry ] ) async throws
178
+ private func getExecuteTransactionInput (
179
+ _ entries: [ some PolymorphicWriteEntry ] , constraints: [ some PolymorphicTransactionConstraintEntry ] ) throws -> ExecuteTransactionInput ?
180
180
{
181
181
// if there are no items, there is nothing to update
182
182
guard entries. count > 0 else {
183
- return
183
+ return nil
184
184
}
185
185
186
186
let context = StandardPolymorphicWriteEntryContext < AWSDynamoDBPolymorphicWriteEntryTransform ,
@@ -199,9 +199,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
199
199
return DynamoDBClientTypes . ParameterizedStatement ( statement: statement)
200
200
}
201
201
202
- let transactionInput = ExecuteTransactionInput ( transactStatements: entryStatements + requiredItemsStatements)
203
-
204
- _ = try await dynamodb. executeTransaction ( input: transactionInput)
202
+ return ExecuteTransactionInput ( transactStatements: entryStatements + requiredItemsStatements)
205
203
}
206
204
207
205
func transactWrite( _ entries: [ WriteEntry < some Any , some Any > ] ) async throws {
@@ -216,16 +214,29 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
216
214
retriesRemaining: self . retryConfiguration. numRetries)
217
215
}
218
216
219
- func polymorphicTransactWrite( _ entries: [ some PolymorphicWriteEntry ] ) async throws {
217
+ func polymorphicTransactWrite( _ entries: sending [ some PolymorphicWriteEntry ] ) async throws {
220
218
let noConstraints : [ EmptyPolymorphicTransactionConstraintEntry ] = [ ]
221
- return try await self . polymorphicTransactWrite ( entries, constraints: noConstraints,
222
- retriesRemaining: self . retryConfiguration. numRetries)
219
+
220
+ guard let transactionInput = try getExecuteTransactionInput ( entries, constraints: noConstraints) else {
221
+ // nothing to do
222
+ return
223
+ }
224
+ let inputKeys = entries. map ( \. compositePrimaryKey)
225
+
226
+ try await self . polymorphicTransactWrite ( transactionInput, inputKeys: inputKeys,
227
+ retriesRemaining: self . retryConfiguration. numRetries)
223
228
}
224
229
225
230
func polymorphicTransactWrite(
226
- _ entries: [ some PolymorphicWriteEntry ] , constraints: [ some PolymorphicTransactionConstraintEntry ] ) async throws
231
+ _ entries: sending [ some PolymorphicWriteEntry ] , constraints: sending [ some PolymorphicTransactionConstraintEntry ] ) async throws
227
232
{
228
- try await self . polymorphicTransactWrite ( entries, constraints: constraints,
233
+ guard let transactionInput = try getExecuteTransactionInput ( entries, constraints: constraints) else {
234
+ // nothing to do
235
+ return
236
+ }
237
+ let inputKeys = entries. map ( \. compositePrimaryKey) + constraints. map ( \. compositePrimaryKey)
238
+
239
+ try await self . polymorphicTransactWrite ( transactionInput, inputKeys: inputKeys,
229
240
retriesRemaining: self . retryConfiguration. numRetries)
230
241
}
231
242
@@ -336,31 +347,24 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
336
347
return try await self . transactWrite ( entries, constraints: constraints, retriesRemaining: retriesRemaining - 1 )
337
348
}
338
349
339
- private func polymorphicTransactWrite(
340
- _ entries: [ some PolymorphicWriteEntry ] , constraints: [ some PolymorphicTransactionConstraintEntry ] ,
341
- retriesRemaining: Int ) async throws
342
- {
343
- let entryCount = entries. count + constraints. count
344
-
345
- if entryCount > AWSDynamoDBLimits . maximumUpdatesPerTransactionStatement {
346
- throw DynamoDBTableError . transactionSizeExceeded ( attemptedSize: entryCount,
350
+ private func polymorphicTransactWrite( _ transactionInput: ExecuteTransactionInput , inputKeys: [ StandardCompositePrimaryKey ? ] , retriesRemaining: Int ) async throws {
351
+ if inputKeys. count > AWSDynamoDBLimits . maximumUpdatesPerTransactionStatement {
352
+ throw DynamoDBTableError . transactionSizeExceeded ( attemptedSize: inputKeys. count,
347
353
maximumSize: AWSDynamoDBLimits . maximumUpdatesPerTransactionStatement)
348
354
}
349
355
350
356
let result : Swift . Result < Void , DynamoDBTableError >
351
357
do {
352
- try await self . writeTransactionItems ( entries , constraints : constraints )
358
+ _ = try await dynamodb . executeTransaction ( input : transactionInput )
353
359
354
360
result = . success( ( ) )
355
361
} catch let exception as TransactionCanceledException {
356
362
guard let cancellationReasons = exception. properties. cancellationReasons else {
357
363
throw DynamoDBTableError . transactionCanceled ( reasons: [ ] )
358
364
}
359
365
360
- let keys = entries. map ( \. compositePrimaryKey) + constraints. map ( \. compositePrimaryKey)
361
-
362
366
var isTransactionConflict = false
363
- let reasons = try zip ( cancellationReasons, keys ) . compactMap { cancellationReason, entryKey -> DynamoDBTableError ? in
367
+ let reasons = try zip ( cancellationReasons, inputKeys ) . compactMap { cancellationReason, entryKey -> DynamoDBTableError ? in
364
368
let key : StandardCompositePrimaryKey ?
365
369
if let item = cancellationReason. item {
366
370
key = try DynamoDBDecoder ( ) . decode ( . m( item) )
@@ -383,7 +387,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
383
387
return DynamoDBTableError . duplicateItem ( partitionKey: partitionKey, sortKey: sortKey,
384
388
message: cancellationReason. message)
385
389
case " ItemCollectionSizeLimitExceeded " :
386
- return DynamoDBTableError . transactionSizeExceeded ( attemptedSize: entryCount ,
390
+ return DynamoDBTableError . transactionSizeExceeded ( attemptedSize: inputKeys . count ,
387
391
maximumSize: AWSDynamoDBLimits . maximumUpdatesPerTransactionStatement)
388
392
case " TransactionConflict " :
389
393
isTransactionConflict = true
@@ -403,13 +407,13 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
403
407
}
404
408
405
409
if isTransactionConflict, retriesRemaining > 0 {
406
- return try await retryPolymorphicTransactWrite ( entries , constraints : constraints , retriesRemaining: retriesRemaining)
410
+ return try await retryPolymorphicTransactWrite ( transactionInput , inputKeys : inputKeys , retriesRemaining: retriesRemaining)
407
411
}
408
412
409
413
result = . failure( DynamoDBTableError . transactionCanceled ( reasons: reasons) )
410
414
} catch let exception as TransactionConflictException {
411
415
if retriesRemaining > 0 {
412
- return try await retryPolymorphicTransactWrite ( entries , constraints : constraints , retriesRemaining: retriesRemaining)
416
+ return try await retryPolymorphicTransactWrite ( transactionInput , inputKeys : inputKeys , retriesRemaining: retriesRemaining)
413
417
}
414
418
415
419
let reason = DynamoDBTableError . transactionConflict ( message: exception. message)
@@ -428,10 +432,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
428
432
}
429
433
}
430
434
431
- private func retryPolymorphicTransactWrite(
432
- _ entries: [ some PolymorphicWriteEntry ] , constraints: [ some PolymorphicTransactionConstraintEntry ] ,
433
- retriesRemaining: Int ) async throws
434
- {
435
+ private func retryPolymorphicTransactWrite( _ transactionInput: ExecuteTransactionInput , inputKeys: [ StandardCompositePrimaryKey ? ] , retriesRemaining: Int ) async throws {
435
436
// determine the required interval
436
437
let retryInterval = Int ( self . retryConfiguration. getRetryInterval ( retriesRemaining: retriesRemaining) )
437
438
@@ -440,7 +441,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
440
441
try await Task . sleep ( nanoseconds: UInt64 ( retryInterval) * millisecondsToNanoSeconds)
441
442
442
443
logger. trace ( " Reattempting request due to remaining retries: \( retryInterval) " )
443
- return try await self . polymorphicTransactWrite ( entries , constraints : constraints , retriesRemaining: retriesRemaining - 1 )
444
+ return try await self . polymorphicTransactWrite ( transactionInput , inputKeys : inputKeys , retriesRemaining: retriesRemaining - 1 )
444
445
}
445
446
446
447
private func writeChunkedItems( _ entries: [ some PolymorphicWriteEntry ] ) async throws {
@@ -464,7 +465,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
464
465
try self . throwOnBatchExecuteStatementErrors ( response: response)
465
466
}
466
467
467
- func polymorphicBulkWrite( _ entries: [ some PolymorphicWriteEntry ] ) async throws {
468
+ func polymorphicBulkWrite( _ entries: sending [ some PolymorphicWriteEntry ] ) async throws {
468
469
// BatchExecuteStatement has a maximum of 25 statements
469
470
// This function handles pagination internally.
470
471
let chunkedEntries = entries. chunked ( by: AWSDynamoDBLimits . maximumUpdatesPerExecuteStatement)
0 commit comments