From 4844b91fe9a0b2aecf3b918f5d8c26978f2924bb Mon Sep 17 00:00:00 2001 From: mkoterba-agorapulse <138458417+mkoterba-agorapulse@users.noreply.github.com> Date: Wed, 10 Jul 2024 10:21:32 +0200 Subject: [PATCH] [sc130691] add a function to micronaut-aws-sdk dynamo lib to update multiple attributes (#236) * [sc130691] add a function to micronaut-aws-sdk dynamo libs to update multiple attributes * fix codenarc * fix generated doc --- .../dynamodb/DefaultDynamoDBService.groovy | 36 +++++++++++++++---- .../aws/dynamodb/DynamoDBService.java | 2 ++ .../DefaultDynamoDBServiceSpec.groovy | 25 ++++++++++++- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBService.groovy b/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBService.groovy index 8613876be..25ddb26ee 100644 --- a/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBService.groovy +++ b/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBService.groovy @@ -736,22 +736,46 @@ class DefaultDynamoDBService implements DynamoDBService String attributeName, Object attributeValue, AttributeAction action + ) { + return this.updateItemAttributes(hashKey, rangeKey, Map.of(attributeName, attributeValue), action) + } + + /** + * Update a multiple item attributes + * + * @param hashKey + * @param rangeKey + * @param valueByAttributeKey + * @param action + * @return + */ + UpdateItemResult updateItemAttributes( + Object hashKey, + Object rangeKey, + Map valueByAttributeKey, + AttributeAction action ) { Map key = [(hashKeyName): buildAttributeValue(hashKey)] if (rangeKey) { key[rangeKeyName] = buildAttributeValue(rangeKey) } + UpdateItemRequest request = new UpdateItemRequest( tableName: metadata.mainTable.tableName(), key: key, returnValues: ReturnValue.UPDATED_NEW - ).addAttributeUpdatesEntry( - attributeName, - new AttributeValueUpdate( - action: action, - value: buildAttributeValue(attributeValue) - ) ) + + valueByAttributeKey.entrySet().forEach { entry -> + request.addAttributeUpdatesEntry( + entry.key, + new AttributeValueUpdate( + action: action, + value: buildAttributeValue(entry.value) + ) + ) + } + return client.updateItem(request) } diff --git a/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DynamoDBService.java b/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DynamoDBService.java index 5394bdd55..8c4e084f4 100644 --- a/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DynamoDBService.java +++ b/subprojects/micronaut-aws-sdk-dynamodb/src/main/groovy/com/agorapulse/micronaut/aws/dynamodb/DynamoDBService.java @@ -773,6 +773,8 @@ default UpdateItemResult deleteItemAttribute(Object hashKey, String attributeNam */ UpdateItemResult updateItemAttribute(Object hashKey, Object rangeKey, String attributeName, Object attributeValue, AttributeAction action); + UpdateItemResult updateItemAttributes(Object hashKey, Object rangeKey, Map values, AttributeAction action); + /** * Update a single item attribute * diff --git a/subprojects/micronaut-aws-sdk-dynamodb/src/test/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBServiceSpec.groovy b/subprojects/micronaut-aws-sdk-dynamodb/src/test/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBServiceSpec.groovy index 505574f70..93c4e3cd8 100644 --- a/subprojects/micronaut-aws-sdk-dynamodb/src/test/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBServiceSpec.groovy +++ b/subprojects/micronaut-aws-sdk-dynamodb/src/test/groovy/com/agorapulse/micronaut/aws/dynamodb/DefaultDynamoDBServiceSpec.groovy @@ -25,15 +25,17 @@ import com.amazonaws.services.dynamodbv2.AmazonDynamoDB import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression import com.amazonaws.services.dynamodbv2.datamodeling.IDynamoDBMapper +import com.amazonaws.services.dynamodbv2.model.AttributeAction import com.amazonaws.services.dynamodbv2.model.CreateTableResult +import com.amazonaws.services.dynamodbv2.model.UpdateItemResult import io.micronaut.test.extensions.spock.annotation.MicronautTest +import jakarta.inject.Inject import org.joda.time.DateTime import org.reactivestreams.Publisher import reactor.core.publisher.Flux import spock.lang.Specification import spock.lang.Stepwise -import jakarta.inject.Inject import java.time.Instant import java.time.temporal.ChronoUnit @@ -364,6 +366,27 @@ class DefaultDynamoDBServiceSpec extends Specification { ]) == 0 } + void 'updateItemAttributes should correctly update specified attribute'() { + given: + s.save(new DynamoDBEntity(parentId: '0', id: '1', rangeIndex: 'foo', number: 0)) + Map valueByAttributeKey = Map.of('rangeIndex', 'bar') + when: + UpdateItemResult result = s.updateItemAttributes('0', '1', valueByAttributeKey, AttributeAction.PUT) + then: + assert result.attributes.size() == 1 + assert result.attributes.get('rangeIndex').s == 'bar' + when: + valueByAttributeKey = Map.of( + 'rangeIndex', 'randomRangeIndex', + 'number', 1 + ) + result = s.updateItemAttributes('0', '1', valueByAttributeKey, AttributeAction.PUT) + then: + assert result.attributes.size() == 2 + assert result.attributes.get('rangeIndex').s == 'randomRangeIndex' + assert result.attributes.get('number').n == '1' + } + private static List toList(Publisher publisher) { return Flux.from(publisher).collectList().block() }