From 9d45ecbf7e79f609f4f5d56895383665466bfb33 Mon Sep 17 00:00:00 2001 From: Vladimir Orany Date: Fri, 23 Feb 2018 09:45:32 +0100 Subject: [PATCH 1/2] ability to query by custom global index --- .../persistence/DruDynamoDBMapper.groovy | 5 ++++- .../meta/DynamoDBClassMetadata.groovy | 11 +++++++++++ .../dru/dynamodb/persistence/DynamoDBSpec.groovy | 14 ++++++++++++++ .../dynamodb/persistence/DynamoDBTester.groovy | 4 ++++ .../src/main/groovy/avl/MissionLogEntry.groovy | 5 +++++ .../test/groovy/avl/DynamoDBSampleSpec.groovy | 16 ++++++++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) diff --git a/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/DruDynamoDBMapper.groovy b/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/DruDynamoDBMapper.groovy index e0aa8fe..5a46b82 100644 --- a/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/DruDynamoDBMapper.groovy +++ b/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/DruDynamoDBMapper.groovy @@ -286,7 +286,10 @@ class DruDynamoDBMapper extends DynamoDBMapper { List ret = new ArrayList<>(dataSet.findAllByType(type)) if (expression.hashKeyValues) { - PropertyMetadata property = DynamoDB.INSTANCE.getDynamoDBClassMetadata(type).hash + PropertyMetadata property = expression.indexName ? + DynamoDB.INSTANCE.getDynamoDBClassMetadata(type).getHashIndexProperty(expression.indexName) : + DynamoDB.INSTANCE.getDynamoDBClassMetadata(type).hash + ret = ret.findAll { it."$property.name" == expression.hashKeyValues."$property.name" } diff --git a/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/meta/DynamoDBClassMetadata.groovy b/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/meta/DynamoDBClassMetadata.groovy index dd35e22..2846525 100644 --- a/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/meta/DynamoDBClassMetadata.groovy +++ b/dru-client-dynamodb/src/main/groovy/com/agorapulse/dru/dynamodb/persistence/meta/DynamoDBClassMetadata.groovy @@ -5,6 +5,7 @@ import com.agorapulse.dru.persistence.meta.PropertyMetadata import com.agorapulse.dru.pojo.meta.PojoClassMetadata import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexHashKey import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey /** @@ -82,4 +83,14 @@ class DynamoDBClassMetadata extends PojoClassMetadata { } } } + + PropertyMetadata getHashIndexProperty(String index) { + for (PropertyMetadata property in persistentProperties) { + DynamoDBIndexHashKey annotation = getAnnotation(type, property.name, DynamoDBIndexHashKey) + if (annotation && (annotation.globalSecondaryIndexName() == index || index in annotation.globalSecondaryIndexNames())) { + return property + } + } + throw new IllegalArgumentException("Index $index in not associated to any property of $type") + } } diff --git a/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBSpec.groovy b/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBSpec.groovy index 74b840e..c6d139d 100644 --- a/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBSpec.groovy +++ b/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBSpec.groovy @@ -64,4 +64,18 @@ class DynamoDBSpec extends Specification { ':bar' | [theRange: 'bar'] null | [:] } + + void 'find hash index'() { + when: + ClassMetadata classMetadata = new DynamoDBClassMetadata(DynamoDBTester) + then: + classMetadata.getHashIndexProperty('foo') + classMetadata.getHashIndexProperty('bar') + classMetadata.getHashIndexProperty('baz') + + when: + classMetadata.getHashIndexProperty('boo') + then: + thrown(IllegalArgumentException) + } } diff --git a/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBTester.groovy b/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBTester.groovy index c4e2be2..bcd68de 100644 --- a/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBTester.groovy +++ b/dru-client-dynamodb/src/test/groovy/com/agorapulse/dru/dynamodb/persistence/DynamoDBTester.groovy @@ -2,6 +2,7 @@ package com.agorapulse.dru.dynamodb.persistence import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexHashKey import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable @@ -19,4 +20,7 @@ class DynamoDBTester { @DynamoDBIgnore String theIgnored + + @DynamoDBIndexHashKey(globalSecondaryIndexNames = ['foo', 'bar'], globalSecondaryIndexName = 'baz') + String theIndexed } diff --git a/examples/avl/src/main/groovy/avl/MissionLogEntry.groovy b/examples/avl/src/main/groovy/avl/MissionLogEntry.groovy index 2e14696..a6f8d3a 100644 --- a/examples/avl/src/main/groovy/avl/MissionLogEntry.groovy +++ b/examples/avl/src/main/groovy/avl/MissionLogEntry.groovy @@ -1,6 +1,8 @@ package avl +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexHashKey import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMarshalling import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable @@ -40,7 +42,10 @@ class MissionLogEntry { Map ext // end::ext[] + @DynamoDBIndexHashKey(globalSecondaryIndexName='agentIdMissionLogEntryIndex') + @DynamoDBAttribute Long agentId + Long villainId String itemName diff --git a/examples/avl/src/test/groovy/avl/DynamoDBSampleSpec.groovy b/examples/avl/src/test/groovy/avl/DynamoDBSampleSpec.groovy index 6191f8f..381691b 100644 --- a/examples/avl/src/test/groovy/avl/DynamoDBSampleSpec.groovy +++ b/examples/avl/src/test/groovy/avl/DynamoDBSampleSpec.groovy @@ -6,6 +6,7 @@ import com.agorapulse.dru.dynamodb.persistence.DynamoDB import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression +import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList import org.joda.time.DateTime import org.junit.Rule import spock.lang.Specification @@ -89,4 +90,19 @@ class DynamoDBSampleSpec extends Specification { service.query(7).count == 1 } // end::grailsService[] + + void 'use secondary global index'() { + when: + DynamoDBMapper mapper = DynamoDB.createMapper(dru) + + DynamoDBQueryExpression queryExpression = new DynamoDBQueryExpression() + .withHashKeyValues(new MissionLogEntry(agentId: 101)) + .withIndexName('agentIdMissionLogEntryIndex') + .withConsistentRead(false) + + PaginatedQueryList result = mapper.query(MissionLogEntry, queryExpression) + + then: + result.size() == 1 + } } From 733ecf6a3ea0cafac6bb284da8091bd710aadc42 Mon Sep 17 00:00:00 2001 From: Vladimir Orany Date: Fri, 23 Feb 2018 09:46:01 +0100 Subject: [PATCH 2/2] bumped version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 767cd4a..9a53088 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ dependencies { } -String currentVersion = '0.1.0' +String currentVersion = '0.1.1' version = currentVersion