@Override public String getHashKeyName() { return model.hashKey().name(); }
/** * {@inheritDoc} */ @Override public Map<String,AttributeValue> convert(final T object) { final Map<String,AttributeValue> map = new LinkedHashMap<String,AttributeValue>(); for (final DynamoDBMapperFieldModel<T,Object> field : fields()) { try { final AttributeValue value = field.getAndConvert(object); if (value != null) { map.put(field.name(), value); } } catch (final RuntimeException e) { throw new DynamoDBMappingException( targetType.getSimpleName() + "[" + field.name() + "]; could not convert attribute", e ); } } return map; }
@Override public String getRangeKeyName() { return model.rangeKeyIfExists() == null ? null : model.rangeKey().name(); } }
/** * Creates a new key map from the specified hash and range key. * @param <H> The hash key type. * @param <R> The range key type. * @param hashKey The hash key. * @param rangeKey The range key (optional if not present on table). * @return The key map. */ public <H,R> Map<String,AttributeValue> convertKey(final H hashKey, final R rangeKey) { final Map<String,AttributeValue> key = new LinkedHashMap<String,AttributeValue>(4); final DynamoDBMapperFieldModel<T,H> hk = this.<H>hashKey(); final AttributeValue hkValue = hashKey == null ? null : hk.convert(hashKey); if (hkValue != null) { key.put(hk.name(), hkValue); } else { throw new DynamoDBMappingException( targetType.getSimpleName() + "[" + hk.name() + "]; no HASH key value present" ); } final DynamoDBMapperFieldModel<T,R> rk = this.<R>rangeKeyIfExists(); final AttributeValue rkValue = rangeKey == null ? null : rk.convert(rangeKey); if (rkValue != null) { key.put(rk.name(), rkValue); } else if (rk != null) { throw new DynamoDBMappingException( targetType.getSimpleName() + "[" + rk.name() + "]; no RANGE key value present" ); } return key; }
/** * Auto-generates the key. */ private void onAutoGenerateAssignableKey(DynamoDBMapperFieldModel<Object, Object> field) { // Generate the new key value first, then ensure it doesn't exist. onAutoGenerate(field); if (getLocalSaveBehavior() != SaveBehavior.CLOBBER && !internalExpectedValueAssertions.containsKey(field.name()) && field.getGenerateStrategy() != DynamoDBAutoGenerateStrategy.ALWAYS) { // Add an expect clause to make sure that the item // doesn't already exist, since it's supposed to be new internalExpectedValueAssertions.put(field.name(), new ExpectedAttributeValue().withExists(false)); } }
/** * {@inheritDoc} */ @Override public T unconvert(final Map<String,AttributeValue> object) { final T result = StandardBeanProperties.DeclaringReflect.<T>newInstance(targetType); if (!object.isEmpty()) { for (final DynamoDBMapperFieldModel<T,Object> field : fields()) { try { final AttributeValue value = object.get(field.name()); if (value != null) { field.unconvertAndSet(result, value); } } catch (final RuntimeException e) { throw new DynamoDBMappingException( targetType.getSimpleName() + "[" + field.name() + "]; could not unconvert attribute", e ); } } } return result; }
public Map<String,LocalSecondaryIndex> localSecondaryIndexes() { final Map<String,LocalSecondaryIndex> map = new LinkedHashMap<String,LocalSecondaryIndex>(); for (final DynamoDBMapperFieldModel<T,Object> field : fields.values()) { for (final String indexName : field.localSecondaryIndexNames()) { final LocalSecondaryIndex lsi = new LocalSecondaryIndex().withIndexName(indexName); if (map.put(indexName, lsi) != null) { throw new DynamoDBMappingException( targetType.getSimpleName() + "[" + field.name() + "]; must not duplicate LSI " + indexName ); } lsi.withProjection(new Projection().withProjectionType(KEYS_ONLY)); lsi.withKeySchema(new KeySchemaElement(keys.get(HASH).name(), HASH)); lsi.withKeySchema(new KeySchemaElement(field.name(), RANGE)); } } if (map.isEmpty()) { return Collections.<String,LocalSecondaryIndex>emptyMap(); } return Collections.unmodifiableMap(map); }
public final DynamoDBMapperFieldModel<T,V> build() { final DynamoDBMapperFieldModel<T,V> result = new DynamoDBMapperFieldModel<T,V>(this); if ((result.keyType() != null || result.indexed()) && !result.attributeType().name().matches("[BNS]")) { throw new DynamoDBMappingException(String.format( "%s[%s]; only scalar (B, N, or S) type allowed for key", targetType.getSimpleName(), result.name() )); } else if (result.keyType() != null && result.getGenerateStrategy() == ALWAYS) { throw new DynamoDBMappingException(String.format( "%s[%s]; auto-generated key and ALWAYS not allowed", targetType.getSimpleName(), result.name() )); } return result; } }
/** * Auto-generates the version. * @param mapping The mapping details. */ private void onVersionAttribute(DynamoDBMapperFieldModel<Object,Object> field) { if ( getLocalSaveBehavior() != SaveBehavior.CLOBBER && !internalExpectedValueAssertions.containsKey(field.name())) { // First establish the expected (current) value for the // update call // For new objects, insist that the value doesn't exist. // For existing ones, insist it has the old value. final Object current = field.get(object); if (current == null) { internalExpectedValueAssertions.put(field.name(), new ExpectedAttributeValue().withExists(false)); } else { internalExpectedValueAssertions.put(field.name(), new ExpectedAttributeValue().withExists(true).withValue(field.convert(current))); } } // Generate the new version value onAutoGenerate(field); }
public Map<String,GlobalSecondaryIndex> globalSecondaryIndexes() { final Map<String,GlobalSecondaryIndex> map = new LinkedHashMap<String,GlobalSecondaryIndex>(); for (final DynamoDBMapperFieldModel<T,Object> field : fields.values()) { for (final String indexName : field.globalSecondaryIndexNames(HASH)) { final GlobalSecondaryIndex gsi = new GlobalSecondaryIndex().withIndexName(indexName); if (map.put(indexName, gsi) != null) { throw new DynamoDBMappingException( targetType.getSimpleName() + "[" + field.name() + "]; must not duplicate GSI " + indexName ); } gsi.withProjection(new Projection().withProjectionType(KEYS_ONLY)); gsi.withKeySchema(new KeySchemaElement(field.name(), HASH)); } } for (final DynamoDBMapperFieldModel<T,Object> field : fields.values()) { for (final String indexName : field.globalSecondaryIndexNames(RANGE)) { final GlobalSecondaryIndex gsi = map.get(indexName); if (gsi == null) { throw new DynamoDBMappingException( targetType.getSimpleName() + "[" + field.name() + "]; no HASH key for GSI " + indexName ); } gsi.withKeySchema(new KeySchemaElement(field.name(), RANGE)); } } if (map.isEmpty()) { return Collections.<String,GlobalSecondaryIndex>emptyMap(); } return Collections.unmodifiableMap(map); }
/** * Auto-generates the attribute value. * @param mapping The mapping details. */ private void onAutoGenerate(DynamoDBMapperFieldModel<Object,Object> field) { AttributeValue value = field.convert(field.generate(field.get(object))); updateValues.put(field.name(), new AttributeValueUpdate().withAction("PUT").withValue(value)); inMemoryUpdates.add(new ValueUpdate(field, value, object)); }
/** * Saves the object given into DynamoDB with the condition that the hash * and if applicable, the range key, does not already exist. * @param object The object to create. * @throws ConditionalCheckFailedException If the object exists. * @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#save * @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression * @see com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue */ public void saveIfNotExists(T object) throws ConditionalCheckFailedException { final DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression(); for (final DynamoDBMapperFieldModel<T,Object> key : model.keys()) { saveExpression.withExpectedEntry(key.name(), new ExpectedAttributeValue() .withExists(false)); } mapper.<T>save(object, saveExpression); }
if ( newAttributeValue == null ) { throw new DynamoDBMappingException( clazz.getSimpleName() + "[" + field.name() + "]; null or empty value for primary key" ); onPrimaryKeyAttributeValue(field.name(), newAttributeValue); } else { AttributeValue currentValue = field.convert(field.get(object)); if ( currentValue != null ) { onNonKeyAttribute(field.name(), currentValue); } else { onNullNonKeyAttribute(field.name());
/** * Saves the object given into DynamoDB with the condition that the hash * and, if applicable, the range key, already exist. * @param object The object to update. * @throws ConditionalCheckFailedException If the object does not exist. * @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#save * @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression * @see com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue */ public void saveIfExists(T object) throws ConditionalCheckFailedException { final DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression(); for (final DynamoDBMapperFieldModel<T,Object> key : model.keys()) { saveExpression.withExpectedEntry(key.name(), new ExpectedAttributeValue() .withExists(true).withValue(key.convert(key.get(object)))); } mapper.<T>save(object, saveExpression); }
/** * Deletes the given object from its DynamoDB table with the condition that * the hash and, if applicable, the range key, already exist. * @param object The object to delete. * @throws ConditionalCheckFailedException If the object does not exist. * @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper#delete * @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDeleteExpression * @see com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue */ public void deleteIfExists(T object) throws ConditionalCheckFailedException { final DynamoDBDeleteExpression deleteExpression = new DynamoDBDeleteExpression(); for (final DynamoDBMapperFieldModel<T,Object> key : model.keys()) { deleteExpression.withExpectedEntry(key.name(), new ExpectedAttributeValue() .withExists(true).withValue(key.convert(key.get(object)))); } mapper.delete(object, deleteExpression); }
@Override public <T> CreateTableRequest generateCreateTableRequest(Class<T> clazz, DynamoDBMapperConfig config) { config = mergeConfig(config); final DynamoDBMapperTableModel<T> model = getTableModel(clazz, config); final CreateTableRequest request = new CreateTableRequest(); request.setTableName(getTableName(clazz, config)); request.withKeySchema(new KeySchemaElement(model.hashKey().name(), HASH)); if (model.rangeKeyIfExists() != null) { request.withKeySchema(new KeySchemaElement(model.rangeKey().name(), RANGE)); } request.setGlobalSecondaryIndexes(model.globalSecondaryIndexes()); request.setLocalSecondaryIndexes(model.localSecondaryIndexes()); for (final DynamoDBMapperFieldModel<T,Object> field : model.fields()) { if (field.keyType() != null || field.indexed()) { request.withAttributeDefinitions(new AttributeDefinition() .withAttributeType(ScalarAttributeType.valueOf(field.attributeType().name())) .withAttributeName(field.name()) ); } } return request; }
attributeValues.put(field.name(), currentValue);