public ItemStorageConfig GetConfig(Type type, DynamoDBFlatConfig flatConfig, bool conversionOnly = false) { lock (Cache) { ConfigTableCache tableCache; if (!Cache.TryGetValue(type, out tableCache)) { var baseStorageConfig = CreateStorageConfig(type, actualTableName: null, flatConfig: flatConfig); tableCache = new ConfigTableCache(baseStorageConfig); Cache[type] = tableCache; } // If this type is only used for conversion, do not attempt to populate the config from the table if (conversionOnly) { return(tableCache.BaseTypeConfig); } string actualTableName = DynamoDBContext.GetTableName(tableCache.BaseTableName, flatConfig); ItemStorageConfig config; if (!tableCache.Cache.TryGetValue(actualTableName, out config)) { config = CreateStorageConfig(type, actualTableName, flatConfig); tableCache.Cache[actualTableName] = config; } return(config); } }
private QueryFilter ComposeQueryFilter(DynamoDBFlatConfig currentConfig, object hashKeyValue, IEnumerable <QueryCondition> conditions, ItemStorageConfig storageConfig, out List <string> indexNames) { if (hashKeyValue == null) { throw new ArgumentNullException("hashKeyValue"); } // Set hash key property name // In case of index queries, if GSI, different key could be used string hashKeyProperty = storageConfig.HashKeyPropertyNames[0]; hashKeyProperty = storageConfig.GetCorrectHashKeyProperty(currentConfig, hashKeyProperty); PropertyStorage propertyStorage = storageConfig.GetPropertyStorage(hashKeyProperty); string hashAttributeName = propertyStorage.AttributeName; DynamoDBEntry hashKeyEntry = ValueToDynamoDBEntry(propertyStorage, hashKeyValue, currentConfig); if (hashKeyEntry == null) { throw new InvalidOperationException("Unable to convert hash key value for property " + hashKeyProperty); } Document hashKey = new Document(); hashKey[hashAttributeName] = hashKeyEntry; return(ComposeQueryFilterHelper(currentConfig, hashKey, conditions, storageConfig, out indexNames)); }
private void DeleteHelper <T>(T value, DynamoDBOperationConfig operationConfig, bool isAsync) { if (value == null) { throw new ArgumentNullException("value"); } ItemStorage storage = ObjectToItemStorage <T>(value, true, true); if (storage == null) { return; } DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.config); Table table = GetTargetTable(storage.Config, flatConfig); if (flatConfig.SkipVersionCheck.Value || !storage.Config.HasVersion) { table.DeleteHelper(table.MakeKey(storage.Document), null, isAsync); } else { Document expectedDocument = CreateExpectedDocumentForVersion(storage); table.DeleteHelper( table.MakeKey(storage.Document), new DeleteItemOperationConfig { Expected = expectedDocument }, isAsync); } }
private void PopulateInstance(ItemStorage storage, object instance, DynamoDBFlatConfig flatConfig) { ItemStorageConfig config = storage.Config; Document document = storage.Document; using (flatConfig.State.Track(document)) { foreach (PropertyStorage propertyStorage in config.AllPropertyStorage) { string propertyName = propertyStorage.PropertyName; string attributeName = propertyStorage.AttributeName; DynamoDBEntry entry; if (document.TryGetValue(attributeName, out entry)) { if (ShouldSave(entry, true)) { object value = FromDynamoDBEntry(propertyStorage, entry, flatConfig); if (!TrySetValue(instance, propertyStorage.Member, value)) { throw new InvalidOperationException("Unable to retrieve value from " + attributeName); } } if (propertyStorage.IsVersion) { storage.CurrentVersion = entry as Primitive; } } } } }
private List <QueryCondition> CreateQueryConditions(DynamoDBOperationConfig config, QueryOperator op, IEnumerable <object> values, ItemStorageConfig storageConfig) { string rangeKeyPropertyName; var flatConfig = new DynamoDBFlatConfig(config, this.config); string indexName = flatConfig.IndexName; if (string.IsNullOrEmpty(indexName)) { rangeKeyPropertyName = storageConfig.RangeKeyPropertyNames.FirstOrDefault(); } else { List <string> rangeProperties; if (!storageConfig.IndexNameToRangePropertiesMapping.TryGetValue(indexName, out rangeProperties)) { rangeProperties = null; } if (rangeProperties == null || rangeProperties.Count != 1) { throw new InvalidOperationException("Unable to determine range key from index name"); } rangeKeyPropertyName = rangeProperties[0]; } List <QueryCondition> conditions = new List <QueryCondition> { new QueryCondition(rangeKeyPropertyName, op, values.ToArray()) }; return(conditions); }
private Task DeleteHelperAsync <T>(T value, DynamoDBOperationConfig operationConfig, CancellationToken cancellationToken) { if (value == null) { throw new ArgumentNullException("value"); } DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.Config); flatConfig.IgnoreNullValues = true; ItemStorage storage = ObjectToItemStorage(value, true, flatConfig); if (storage == null) { return(CompletedTask); } Table table = GetTargetTable(storage.Config, flatConfig); if (flatConfig.SkipVersionCheck.Value || !storage.Config.HasVersion) { return(table.DeleteHelperAsync(table.MakeKey(storage.Document), null, cancellationToken)); } else { Document expectedDocument = CreateExpectedDocumentForVersion(storage); return(table.DeleteHelperAsync( table.MakeKey(storage.Document), new DeleteItemOperationConfig { Expected = expectedDocument }, cancellationToken)); } }
private void SaveHelper <T>(T value, DynamoDBOperationConfig operationConfig) { if (value == null) { return; } DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.Config); ItemStorage storage = ObjectToItemStorage(value, false, flatConfig); if (storage == null) { return; } Table table = GetTargetTable(storage.Config, flatConfig); if ((flatConfig.SkipVersionCheck.HasValue && flatConfig.SkipVersionCheck.Value) || !storage.Config.HasVersion) { table.UpdateHelper(storage.Document, table.MakeKey(storage.Document), null); } else { Document expectedDocument = CreateExpectedDocumentForVersion(storage); SetNewVersion(storage); var updateItemOperationConfig = new UpdateItemOperationConfig { Expected = expectedDocument, ReturnValues = ReturnValues.None, }; table.UpdateHelper(storage.Document, table.MakeKey(storage.Document), updateItemOperationConfig); PopulateInstance(storage, value, flatConfig); } }
private ContextSearch ConvertQueryHelper <T>(DynamoDBFlatConfig currentConfig, ItemStorageConfig storageConfig, QueryFilter filter, List <string> indexNames) { Table table = GetTargetTable(storageConfig, currentConfig); string indexName = GetQueryIndexName(currentConfig, indexNames); var queryConfig = new QueryOperationConfig { Filter = filter, ConsistentRead = currentConfig.ConsistentRead.Value, BackwardSearch = currentConfig.BackwardQuery.Value, IndexName = indexName, ConditionalOperator = currentConfig.ConditionalOperator }; if (string.IsNullOrEmpty(indexName)) { queryConfig.Select = SelectValues.SpecificAttributes; List <string> attributesToGet = storageConfig.AttributesToGet; queryConfig.AttributesToGet = attributesToGet; } else { queryConfig.Select = SelectValues.AllProjectedAttributes; } Search query = table.Query(queryConfig); return(new ContextSearch(query, currentConfig)); }
private bool TryFromMap(Type targetType, Document map, DynamoDBFlatConfig flatConfig, out object output) { output = null; if (!Utils.CanInstantiate(targetType)) { return(false); } Type valueType; if (!IsSupportedDictionaryType(targetType, out valueType)) { return(false); } var dictionary = Utils.Instantiate(targetType); var idictionary = dictionary as IDictionary; var propertyStorage = new SimplePropertyStorage(valueType); foreach (var kvp in map) { var key = kvp.Key; var entry = kvp.Value; var item = FromDynamoDBEntry(propertyStorage, entry, flatConfig); idictionary.Add(key, item); } output = dictionary; return(true); }
private ContextSearch ConvertFromQuery <T>(QueryOperationConfig queryConfig, DynamoDBOperationConfig operationConfig) { DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, Config); Table table = GetTargetTableInternal <T>(operationConfig); Search search = table.Query(queryConfig); return(new ContextSearch(search, flatConfig)); }
private ContextSearch ConvertFromScan <T>(ScanOperationConfig scanConfig, DynamoDBOperationConfig operationConfig) { DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, Config); Table table = GetTargetTableInternal <T>(operationConfig); Search search = table.Scan(scanConfig); return(new ContextSearch(search, flatConfig)); }
private T LoadHelper <T>(T keyObject, DynamoDBOperationConfig operationConfig, bool isAsync) { DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig <T>(flatConfig); Key key = MakeKey <T>(keyObject, storageConfig, flatConfig); return(LoadHelper <T>(key, flatConfig, storageConfig, isAsync)); }
// Serializes a given value to Document // Use only for property conversions, not for full item conversion private Document SerializeToDocument(object value, Type type, DynamoDBFlatConfig flatConfig) { ItemStorageConfig config = StorageConfigCache.GetConfig(type, flatConfig, conversionOnly: true); var itemStorage = ObjectToItemStorageHelper(value, config, flatConfig, keysOnly: false, ignoreNullValues: flatConfig.IgnoreNullValues.Value); var doc = itemStorage.Document; return(doc); }
private Task <T> LoadHelperAsync <T>(T keyObject, DynamoDBOperationConfig operationConfig, CancellationToken cancellationToken) { DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig <T>(flatConfig); Key key = MakeKey <T>(keyObject, storageConfig, flatConfig); return(LoadHelperAsync <T>(key, flatConfig, storageConfig, cancellationToken)); }
private T LoadHelper <T>(object hashKey, object rangeKey, DynamoDBOperationConfig operationConfig) { DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig <T>(flatConfig); Key key = MakeKey(hashKey, rangeKey, storageConfig, flatConfig); return(LoadHelper <T>(key, flatConfig, storageConfig)); }
internal Table GetTargetTableInternal <T>(DynamoDBOperationConfig operationConfig) { Type type = typeof(T); DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig(type, flatConfig); Table table = GetTargetTable(storageConfig, flatConfig); return(table); }
private ContextSearch ConvertQueryByValue <T>(object hashKeyValue, QueryOperator op, IEnumerable <object> values, DynamoDBOperationConfig operationConfig) { DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig <T>(flatConfig); List <QueryCondition> conditions = CreateQueryConditions(flatConfig, op, values, storageConfig); ContextSearch query = ConvertQueryByValue <T>(hashKeyValue, conditions, operationConfig, storageConfig); return(query); }
private void DeleteHelper <T>(object hashKey, object rangeKey, DynamoDBOperationConfig operationConfig, bool isAsync) { DynamoDBFlatConfig config = new DynamoDBFlatConfig(operationConfig, this.config); ItemStorageConfig storageConfig = ItemStorageConfigCache.GetConfig <T>(); Key key = MakeKey(hashKey, rangeKey, storageConfig); Table table = GetTargetTable(storageConfig, config); table.DeleteHelper(key, null, isAsync); }
private Task DeleteHelperAsync <T>(object hashKey, object rangeKey, DynamoDBOperationConfig operationConfig, CancellationToken cancellationToken) { DynamoDBFlatConfig config = new DynamoDBFlatConfig(operationConfig, this.Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig <T>(config); Key key = MakeKey(hashKey, rangeKey, storageConfig, config); Table table = GetTargetTable(storageConfig, config); return(table.DeleteHelperAsync(key, null, cancellationToken)); }
// Deserializes a given Document to instance of targetType // Use only for property conversions, not for full item conversion private object DeserializeFromDocument(Document document, Type targetType, DynamoDBFlatConfig flatConfig) { ItemStorageConfig storageConfig = StorageConfigCache.GetConfig(targetType, flatConfig, conversionOnly: true); ItemStorage storage = new ItemStorage(storageConfig); storage.Document = document; object value = DocumentToObject(targetType, storage, flatConfig); return(value); }
internal T FromDocumentHelper <T>(Document document, DynamoDBFlatConfig flatConfig) { ItemStorageConfig storageConfig = StorageConfigCache.GetConfig <T>(flatConfig); ItemStorage storage = new ItemStorage(storageConfig); storage.Document = document; T instance = DocumentToObject <T>(storage, flatConfig); return(instance); }
internal Table GetTargetTableInternal <T>(DynamoDBOperationConfig operationConfig) { Type type = typeof(T); DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, this.Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig(type, flatConfig); Table table = GetTargetTable(storageConfig, flatConfig); //Table copy = table.Copy(Table.DynamoDBConsumer.DocumentModel); return(table); }
// Serializing an object into a DynamoDB document private ItemStorage ObjectToItemStorage <T>(T toStore, bool keysOnly, DynamoDBFlatConfig flatConfig) { if (toStore == null) { return(null); } Type objectType = typeof(T); return(ObjectToItemStorage(toStore, objectType, keysOnly, flatConfig)); }
/// <summary> /// Deserializes a document to an instance of type T. /// </summary> /// <typeparam name="T">Type to populate.</typeparam> /// <param name="document">Document with properties to use.</param> /// <returns> /// Object of type T, populated with properties from the document. /// </returns> public T FromDocument <T>(Document document) { DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(null, Config); ItemStorageConfig storageConfig = StorageConfigCache.GetConfig <T>(flatConfig); ItemStorage storage = new ItemStorage(storageConfig); storage.Document = document; T instance = DocumentToObject <T>(storage); return(instance); }
private Search ConvertQueryByValue <T>(object hashKeyValue, IEnumerable <QueryCondition> conditions, DynamoDBOperationConfig operationConfig, ItemStorageConfig storageConfig = null) { if (storageConfig == null) { storageConfig = ItemStorageConfigCache.GetConfig <T>(); } List <string> indexNames; DynamoDBFlatConfig currentConfig = new DynamoDBFlatConfig(operationConfig, this.config); QueryFilter filter = ComposeQueryFilter(currentConfig, hashKeyValue, conditions, storageConfig, out indexNames); return(ConvertQueryHelper <T>(currentConfig, storageConfig, filter, indexNames)); }
/// <summary> /// Creates a strongly-typed BatchWrite object, allowing /// a batch-write operation against DynamoDB. /// </summary> /// <typeparam name="T">Type of objects to write</typeparam> /// <param name="operationConfig">Config object which can be used to override that table used.</param> /// <param name="callback">The callback that will be invoked when the asynchronous operation completes.</param> /// <param name="asyncOptions">An instance of AsyncOptions that specifies how the async method should be executed.</param> public void CreateBatchWriteAsync <T>(DynamoDBOperationConfig operationConfig, AmazonDynamoDBCallback <BatchWrite <T> > callback, AsyncOptions asyncOptions = null) { asyncOptions = asyncOptions ?? new AsyncOptions(); DynamoDBAsyncExecutor.ExecuteAsync( () => { DynamoDBFlatConfig config = new DynamoDBFlatConfig(operationConfig, this.Config); return(new BatchWrite <T>(this, config));; }, asyncOptions, callback); }
internal Key MakeKey <T>(T keyObject, ItemStorageConfig storageConfig, DynamoDBFlatConfig flatConfig) { ItemStorage keyAsStorage = ObjectToItemStorageHelper(keyObject, storageConfig, flatConfig, keysOnly: true, ignoreNullValues: true); if (storageConfig.HasVersion) // if version field is defined, it would have been returned, so remove before making the key { keyAsStorage.Document[storageConfig.VersionPropertyStorage.AttributeName] = null; } Key key = new Key(keyAsStorage.Document.ToAttributeMap(flatConfig.Conversion)); ValidateKey(key, storageConfig); return(key); }
internal Table GetTargetTable(ItemStorageConfig storageConfig, DynamoDBFlatConfig flatConfig) { if (flatConfig == null) { throw new ArgumentNullException("flatConfig"); } string tableName = GetTableName(storageConfig.TableName, flatConfig); Table table = GetTable(tableName, flatConfig); ValidateConfigAgainstTable(storageConfig, table); return(table); }
public string GetCorrectHashKeyProperty(DynamoDBFlatConfig currentConfig, string hashKeyProperty) { if (currentConfig.IsIndexOperation) { string indexName = currentConfig.IndexName; GSIConfig gsiConfig = this.GetGSIConfig(indexName); // Use GSI hash key if GSI is found AND GSI hash-key is set if (gsiConfig != null && !string.IsNullOrEmpty(gsiConfig.HashKeyPropertyName)) { hashKeyProperty = gsiConfig.HashKeyPropertyName; } } return(hashKeyProperty); }
internal Table GetTable(string tableName, DynamoDBFlatConfig flatConfig) { Table table; lock (tablesMapLock) { if (!tablesMap.TryGetValue(tableName, out table)) { table = Table.LoadTable(Client, tableName, Table.DynamoDBConsumer.DataModel, flatConfig.Conversion); tablesMap[tableName] = table; } } return(table); }
internal BatchGet(DynamoDBContext context, DynamoDBFlatConfig config) { Context = context; Config = config; Keys = new List<Key>(); }
internal BatchWrite(DynamoDBContext context, DynamoDBFlatConfig config) { Context = context; Config = config; }