internal static ItemStorageConfig CreateStorageConfig(Type type) { if (type == null) { throw new ArgumentNullException("type"); } ItemStorageConfig config = new ItemStorageConfig(); DynamoDBTableAttribute tableAttribute = EntityUtils.GetTableAttribute(type); if (tableAttribute == null || string.IsNullOrEmpty(tableAttribute.TableName)) { throw new InvalidOperationException("No DynamoDBTableAttribute on type"); } if (string.IsNullOrEmpty(tableAttribute.TableName)) { throw new InvalidOperationException("DynamoDBTableAttribute.Table is empty or null"); } config.TableName = tableAttribute.TableName; config.LowerCamelCaseProperties = tableAttribute.LowerCamelCaseProperties; foreach (var member in type.GetMembers()) { // filter out non-fields and non-properties if (!(member is FieldInfo || member is PropertyInfo)) { continue; } // filter out properties that aren't both read and write if (!EntityUtils.IsReadWrite(member)) { continue; } DynamoDBAttribute attribute = EntityUtils.GetAttribute(member); // filter out ignored properties if (attribute is DynamoDBIgnoreAttribute) { continue; } Type memberType = EntityUtils.GetType(member); string attributeName = GetAccurateCase(config, member.Name); string propertyName = member.Name; PropertyStorage propertyStorage = new PropertyStorage { Member = member, MemberType = memberType, }; if (attribute is DynamoDBVersionAttribute) { EntityUtils.ValidateVersionType(memberType); // no conversion is possible, so type must be a nullable primitive if (!string.IsNullOrEmpty(config.VersionPropertyName)) { throw new InvalidOperationException("Multiple version attributes defined"); } config.VersionPropertyName = propertyName; propertyStorage.IsVersion = true; } DynamoDBPropertyAttribute propertyAttribute = attribute as DynamoDBPropertyAttribute; if (propertyAttribute != null) { if (!string.IsNullOrEmpty(propertyAttribute.AttributeName)) { attributeName = GetAccurateCase(config, propertyAttribute.AttributeName); } if (propertyAttribute is DynamoDBHashKeyAttribute) { if (propertyAttribute.Converter == null && !EntityUtils.IsPrimitive(memberType)) { throw new InvalidOperationException("Hash key " + propertyName + " must be of primitive type"); } if (!string.IsNullOrEmpty(config.HashKeyPropertyName)) { throw new InvalidOperationException("Multiple hash keys defined"); } config.HashKeyPropertyName = propertyName; propertyStorage.IsHashKey = true; } if (propertyAttribute is DynamoDBRangeKeyAttribute) { if (propertyAttribute.Converter == null && !EntityUtils.IsPrimitive(memberType)) { throw new InvalidOperationException("Range key " + propertyName + " must be of primitive type"); } if (!string.IsNullOrEmpty(config.RangeKeyPropertyName)) { throw new InvalidOperationException("Multiple range keys defined"); } config.RangeKeyPropertyName = propertyName; propertyStorage.IsRangeKey = true; } if (propertyAttribute.Converter != null) { if (!EntityUtils.CanInstantiate(propertyAttribute.Converter) || !EntityUtils.ImplementsInterface(propertyAttribute.Converter, typeof(IPropertyConverter))) { throw new InvalidOperationException("Converter for " + propertyName + " must be instantiable with no parameters and must implement IPropertyConverter"); } propertyStorage.Converter = EntityUtils.Instantiate(propertyAttribute.Converter) as IPropertyConverter; } } propertyStorage.PropertyName = propertyName; propertyStorage.AttributeName = attributeName; config.AttributesToGet.Add(attributeName); config.AddPropertyStorage(propertyStorage); } if (string.IsNullOrEmpty(config.HashKeyPropertyName)) { throw new InvalidOperationException("No hash key configured on type"); } return(config); }
public ItemStorage(ItemStorageConfig storageConfig) { Document = new Document(); Config = storageConfig; }
private static string GetAccurateCase(ItemStorageConfig config, string value) { return(config.LowerCamelCaseProperties ? EntityUtils.ToLowerCamelCase(value) : value); }
// Key creation private static DynamoDBEntry ValueToDynamoDBEntry(string propertyName, object value, ItemStorageConfig storageConfig) { PropertyStorage propertyStorage = storageConfig.GetPropertyStorage(propertyName); var entry = ToDynamoDBEntry(propertyStorage.MemberType, value, propertyStorage.Converter); return(entry); }
private static RangeFilter ComposeRangeFilter(QueryOperator op, IEnumerable <object> values, ItemStorageConfig storageConfig) { RangeFilter filter; if (values != null) { PropertyStorage propertyStorage = storageConfig.RangePropertyStorage; List <AttributeValue> attributeValues = new List <AttributeValue>(); foreach (var value in values) { var entry = ToDynamoDBEntry(propertyStorage.MemberType, value, propertyStorage.Converter); AttributeValue nativeValue = entry.ConvertToAttributeValue(); if (nativeValue != null) { attributeValues.Add(nativeValue); } } filter = new RangeFilter(op, attributeValues); } else { filter = new RangeFilter(); } return(filter); }
// Query/Scan filter creation private static ScanFilter ComposeScanFilter(IEnumerable <ScanCondition> conditions, ItemStorageConfig storageConfig) { ScanFilter filter = new ScanFilter(); foreach (var condition in conditions) { PropertyStorage propertyStorage = storageConfig.GetPropertyStorage(condition.PropertyName); List <AttributeValue> attributeValues = new List <AttributeValue>(); foreach (var value in condition.Values) { var entry = ToDynamoDBEntry(propertyStorage.MemberType, value, propertyStorage.Converter, true); if (entry == null) { throw new InvalidOperationException( string.Format("Unable to convert value corresponding to property [{0}] to DynamoDB representation", condition.PropertyName)); } AttributeValue nativeValue = entry.ConvertToAttributeValue(); if (nativeValue != null) { attributeValues.Add(nativeValue); } } filter.AddCondition(propertyStorage.AttributeName, condition.Operator, attributeValues); } return(filter); }
internal static ItemStorage ObjectToItemStorage <T>(T toStore, bool keysOnly, bool ignoreNullValues, ItemStorageConfig config) { ItemStorage storage = new ItemStorage(config); PopulateItemStorage(toStore, keysOnly, ignoreNullValues, storage); return(storage); }