package implementations;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import model.Attribute;
import model.Filter;
import model.Key;
import model.Row;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.BatchGetItemRequest;
import com.amazonaws.services.dynamodbv2.model.BatchGetItemResult;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.DeleteTableRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;
import com.amazonaws.services.dynamodbv2.model.ListTablesResult;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.ResourceInUseException;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.ScanResult;
public class DynamoDbQueryHandler {
// Provide initial provisioned throughput values as Java long data types
private static ProvisionedThroughput DEFAULT_PROVISIONED_THROUGHPUT = new ProvisionedThroughput()
.withReadCapacityUnits(5L).withWriteCapacityUnits(5L);
/**
* Create a table with the given hashKey as row id
*
* @param tableName
* @param primaryKey
*/
public static void createTable(String tableName, String primaryKey) {
ArrayList<KeySchemaElement> ks = new ArrayList<KeySchemaElement>();
ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
ks.add(new KeySchemaElement().withAttributeName(primaryKey)
.withKeyType(KeyType.HASH));
attributeDefinitions.add(new AttributeDefinition().withAttributeName(
primaryKey).withAttributeType("S"));
CreateTableRequest request = new CreateTableRequest()
.withTableName(tableName).withKeySchema(ks)
.withProvisionedThroughput(DEFAULT_PROVISIONED_THROUGHPUT);
request.setAttributeDefinitions(attributeDefinitions);
try {
DynamoDbHandler.CLIENT.createTable(request);
} catch (ResourceInUseException e) {
//System.err.println("Table '" + tableName + "' already exists");
}
}
public static void createTable(String tableName, long readCapacityUnits,
long writeCapacityUnits, String hashKeyName, String hashKeyType,
String rangeKeyName, String rangeKeyType) {
}
public static ListTablesResult listTables() {
return DynamoDbHandler.CLIENT.listTables();
}
/**
* Delete the table with given name
*
* @param tableName
*/
public static void deleteTable(String tableName) {
try {
DynamoDbHandler.CLIENT
.deleteTable(new DeleteTableRequest(tableName));
} catch (Exception e) {
//Table does not exist
}
}
/**
* Insert values into the given table. Items are stored as blobs in the
* database.
*
* @param tableName
* @param items
*/
public static void insertItems(String tableName, List<Row> items) {
Map<String, AttributeValue> transformedItem = new HashMap<>();
for (Row item : items) {
for (Attribute attribute : item.getAttributes()) {
transformedItem.put(attribute.getName(),
new AttributeValue().withS(attribute.getValue()));
}
transformedItem.put(item.getKey().getName(),
new AttributeValue().withS(item.getKey().getValue()));
PutItemRequest itemRequest = new PutItemRequest().withTableName(
tableName).withItem(transformedItem);
DynamoDbHandler.CLIENT.putItem(itemRequest);
transformedItem.clear();
}
//
// for (Map<String, String> item : items) {
// for (String key : item.keySet()) {
// transformedItem.put(key, new
// AttributeValue().withB(ByteBuffer.wrap(item.get(key).getBytes())));
// }
// PutItemRequest itemRequest = new
// PutItemRequest().withTableName(tableName).withItem(transformedItem);
// DynamoDbHandler.CLIENT.putItem(itemRequest);
// transformedItem.clear();
// }
}
/**
* Get item of table with provided key-value.
*
* @param tableName
* @param combinedKey
* @return
*/
public static Row getRowByKey(String tableName, Key... combinedKey) {
Map<String, AttributeValue> transformedKey = new HashMap<>();
for (Key key : combinedKey) {
transformedKey.put(key.getName(),
new AttributeValue().withS(key.getValue()));
}
GetItemResult result = DynamoDbHandler.CLIENT
.getItem(new GetItemRequest(tableName, transformedKey));
List<Attribute> attributes = new ArrayList<>();
for (String resultKey : result.getItem().keySet()) {
attributes.add(new Attribute(resultKey, result.getItem()
.get(resultKey).getS()));
}
return new Row(attributes);
}
/**
* Get items from different tables by values of their key.
*
* @param tableName
* @param combinedKey
* @return
*/
@Deprecated
public static List<Row> getItemsByKeys(
Map<String, ArrayList<Map<String, String>>> tableNamesWithKeys) {
HashMap<String, KeysAndAttributes> requestItems = new HashMap<String, KeysAndAttributes>();
for (String tableName : tableNamesWithKeys.keySet()) {
ArrayList<Map<String, String>> keyList = tableNamesWithKeys
.get(tableName);
ArrayList<Map<String, AttributeValue>> transformedKeyList = new ArrayList<>();
for (Map<String, String> keyValueMap : keyList) {
Map<String, AttributeValue> transformedItem = new HashMap<>();
for (String key : keyValueMap.keySet()) {
transformedItem.put(key,
new AttributeValue().withS(keyValueMap.get(key)));
}
transformedKeyList.add(transformedItem);
}
requestItems.put(tableName,
new KeysAndAttributes().withKeys(transformedKeyList));
}
BatchGetItemResult result = DynamoDbHandler.CLIENT
.batchGetItem(new BatchGetItemRequest()
.withRequestItems(requestItems));
List<Row> items = new ArrayList<>();
for (String tableName : tableNamesWithKeys.keySet()) {
List<Map<String, AttributeValue>> tableResults = result
.getResponses().get(tableName);
List<Attribute> attributes = null;
for (Map<String, AttributeValue> tableResult : tableResults) {
attributes = new ArrayList<>();
for (String key : tableResult.keySet()) {
attributes.add(new Attribute(key, tableResult.get(key)
.getS()));
}
items.add(new Row(attributes));
}
}
return items;
}
/**
* Returns the the result of the scanned table with the applied filters. The
* filters are connected via the conditionalOperator. It can either be AND
* or OR.
*
* @param tableName
* The table to be scanned.
* @param filters
* A list with Filter objects.
* @param conditionalOperator
* AND | OR - Conditional clauses in DynamoDb can either have AND
* or OR connectors, no mix.
* @return
*/
public static List<Row> scanTable(String tableName, Filter[] filters,
String conditionalOperator) {
Map<String, Condition> scanFilter = new HashMap<>();
for (Filter filter : filters) {
scanFilter.put(
filter.getAttribute().getName(),
new Condition().withComparisonOperator(
filter.getComparisonOperator())
.withAttributeValueList(
new AttributeValue().withS(filter
.getAttribute().getValue())));
}
ScanResult scanResult;
if (filters.length == 1) {
scanResult = DynamoDbHandler.CLIENT.scan(new ScanRequest(tableName)
.withScanFilter(scanFilter));
} else {
scanResult = DynamoDbHandler.CLIENT.scan(new ScanRequest(tableName)
.withConditionalOperator(conditionalOperator)
.withScanFilter(scanFilter));
}
ArrayList<Row> items = new ArrayList<>();
List<Attribute> attributes = null;
for (Map<String, AttributeValue> result : scanResult.getItems()) {
attributes = new ArrayList<>();
for (String key : result.keySet()) {
attributes.add(new Attribute(key, result.get(key).getS()));
}
items.add(new Row(attributes));
}
return items;
}
}