mboudreau / Alternator

A mock DynamoDB that runs locally for testing purposes - DEPRECATED, PLEASE USE DYNAMODB LOCAL: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html
Apache License 2.0
78 stars 39 forks source link

Support multiple items with different Range Keys for the same Hash Key. #46

Closed rrutt closed 12 years ago

rrutt commented 12 years ago

Added support for multiple items with different Range Key values for a single Hash Key value.

This involved replacing the Table.items collection with Table.itemRangeGroups. Each entry in this collection holds one or more items that share the same Hash Key value.

old: private Map<String, Map<String, AttributeValue>> items = new HashMap<String, Map<String, AttributeValue>>(); new: private Map<String, ItemRangeGroup> itemRangeGroups = new HashMap<String, ItemRangeGroup>();

ItemRangeGroup is a new model class with an items collection that contains all the items in a table with the same Hash Key value.

private SortedMap<String, Map<String, AttributeValue>> items = new TreeMap<String, Map<String, AttributeValue>>();

The Range Key value is used as the index into a sorted collection. This allows queries to return the items in Range Key order as described by the DynamoDB documentation. If a table has no Range Key defined for its schema, an empty String is used as the TreeMap index.

Various AlternatorDBHandler methods were revised to add awareness of this "nested collection" for the items. Any iteration that previously scanned the Table.items collection was converted to a nested loop for the Table.itemRangeGroups and then each itemRangeGroup.items value.

The AlternatorDBHandler.query method now supports RangeKeyCondition queries. The ItemRangeGroup.getItems method will filter its returned item list when passed a non-null rangeKeyCondition argument.

The following statement was added to the AlternatorDBHandler.query method to avoid an infinite paging loop when accessed via the DynamoDBMapper:

queryResult.setLastEvaluatedKey(null)

A new AlternatorDBInProcessClient variant of AlternatorDBClient bypasses the cross-process Jetty service call and instead directly invokes the AlternatorDBHandler methods. This allows breakpoints within AlternatorDBHandler to debug the logic when invoked by unit tests.

To activate the AlternatorDBInProcessClient for the unit tests, change the value of this constant to false within AlternatorTest:

private static final boolean RUN_DB_AS_SERVICE = true;

In order to support this option, all unit tests had "client." references changed to "getClient()."

Questions on this update can be addressed to Rick Rutt (RRutt@Live.com)

mboudreau commented 12 years ago

Pulling this in, but will need to revise code to see how well it works and if the architecture matches the project's.