@@ -175,12 +175,12 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
175175 _ = try await dynamodb. executeTransaction ( input: transactionInput)
176176 }
177177
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 ?
180180 {
181181 // if there are no items, there is nothing to update
182182 guard entries. count > 0 else {
183- return
183+ return nil
184184 }
185185
186186 let context = StandardPolymorphicWriteEntryContext < AWSDynamoDBPolymorphicWriteEntryTransform ,
@@ -199,9 +199,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
199199 return DynamoDBClientTypes . ParameterizedStatement ( statement: statement)
200200 }
201201
202- let transactionInput = ExecuteTransactionInput ( transactStatements: entryStatements + requiredItemsStatements)
203-
204- _ = try await dynamodb. executeTransaction ( input: transactionInput)
202+ return ExecuteTransactionInput ( transactStatements: entryStatements + requiredItemsStatements)
205203 }
206204
207205 func transactWrite( _ entries: [ WriteEntry < some Any , some Any > ] ) async throws {
@@ -216,16 +214,29 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
216214 retriesRemaining: self . retryConfiguration. numRetries)
217215 }
218216
219- func polymorphicTransactWrite( _ entries: [ some PolymorphicWriteEntry ] ) async throws {
217+ func polymorphicTransactWrite( _ entries: sending [ some PolymorphicWriteEntry ] ) async throws {
220218 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)
223228 }
224229
225230 func polymorphicTransactWrite(
226- _ entries: [ some PolymorphicWriteEntry ] , constraints: [ some PolymorphicTransactionConstraintEntry ] ) async throws
231+ _ entries: sending [ some PolymorphicWriteEntry ] , constraints: sending [ some PolymorphicTransactionConstraintEntry ] ) async throws
227232 {
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,
229240 retriesRemaining: self . retryConfiguration. numRetries)
230241 }
231242
@@ -336,31 +347,24 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
336347 return try await self . transactWrite ( entries, constraints: constraints, retriesRemaining: retriesRemaining - 1 )
337348 }
338349
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,
347353 maximumSize: AWSDynamoDBLimits . maximumUpdatesPerTransactionStatement)
348354 }
349355
350356 let result : Swift . Result < Void , DynamoDBTableError >
351357 do {
352- try await self . writeTransactionItems ( entries , constraints : constraints )
358+ _ = try await dynamodb . executeTransaction ( input : transactionInput )
353359
354360 result = . success( ( ) )
355361 } catch let exception as TransactionCanceledException {
356362 guard let cancellationReasons = exception. properties. cancellationReasons else {
357363 throw DynamoDBTableError . transactionCanceled ( reasons: [ ] )
358364 }
359365
360- let keys = entries. map ( \. compositePrimaryKey) + constraints. map ( \. compositePrimaryKey)
361-
362366 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
364368 let key : StandardCompositePrimaryKey ?
365369 if let item = cancellationReason. item {
366370 key = try DynamoDBDecoder ( ) . decode ( . m( item) )
@@ -383,7 +387,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
383387 return DynamoDBTableError . duplicateItem ( partitionKey: partitionKey, sortKey: sortKey,
384388 message: cancellationReason. message)
385389 case " ItemCollectionSizeLimitExceeded " :
386- return DynamoDBTableError . transactionSizeExceeded ( attemptedSize: entryCount ,
390+ return DynamoDBTableError . transactionSizeExceeded ( attemptedSize: inputKeys . count ,
387391 maximumSize: AWSDynamoDBLimits . maximumUpdatesPerTransactionStatement)
388392 case " TransactionConflict " :
389393 isTransactionConflict = true
@@ -403,13 +407,13 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
403407 }
404408
405409 if isTransactionConflict, retriesRemaining > 0 {
406- return try await retryPolymorphicTransactWrite ( entries , constraints : constraints , retriesRemaining: retriesRemaining)
410+ return try await retryPolymorphicTransactWrite ( transactionInput , inputKeys : inputKeys , retriesRemaining: retriesRemaining)
407411 }
408412
409413 result = . failure( DynamoDBTableError . transactionCanceled ( reasons: reasons) )
410414 } catch let exception as TransactionConflictException {
411415 if retriesRemaining > 0 {
412- return try await retryPolymorphicTransactWrite ( entries , constraints : constraints , retriesRemaining: retriesRemaining)
416+ return try await retryPolymorphicTransactWrite ( transactionInput , inputKeys : inputKeys , retriesRemaining: retriesRemaining)
413417 }
414418
415419 let reason = DynamoDBTableError . transactionConflict ( message: exception. message)
@@ -428,10 +432,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
428432 }
429433 }
430434
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 {
435436 // determine the required interval
436437 let retryInterval = Int ( self . retryConfiguration. getRetryInterval ( retriesRemaining: retriesRemaining) )
437438
@@ -440,7 +441,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
440441 try await Task . sleep ( nanoseconds: UInt64 ( retryInterval) * millisecondsToNanoSeconds)
441442
442443 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 )
444445 }
445446
446447 private func writeChunkedItems( _ entries: [ some PolymorphicWriteEntry ] ) async throws {
@@ -464,7 +465,7 @@ public extension AWSDynamoDBCompositePrimaryKeyTable {
464465 try self . throwOnBatchExecuteStatementErrors ( response: response)
465466 }
466467
467- func polymorphicBulkWrite( _ entries: [ some PolymorphicWriteEntry ] ) async throws {
468+ func polymorphicBulkWrite( _ entries: sending [ some PolymorphicWriteEntry ] ) async throws {
468469 // BatchExecuteStatement has a maximum of 25 statements
469470 // This function handles pagination internally.
470471 let chunkedEntries = entries. chunked ( by: AWSDynamoDBLimits . maximumUpdatesPerExecuteStatement)
0 commit comments