예제 #1
0
        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);
            }
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #6
0
        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));
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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));
        }
예제 #9
0
        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);
        }
예제 #10
0
        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));
        }
예제 #11
0
        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));
        }
예제 #12
0
        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));
        }
예제 #13
0
        // 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);
        }
예제 #14
0
        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));
        }
예제 #15
0
        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);
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
        }
예제 #19
0
        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));
        }
예제 #20
0
        // 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);
        }
예제 #21
0
        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);
        }
예제 #22
0
        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);
        }
예제 #23
0
        // 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));
        }
예제 #24
0
        /// <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);
        }
예제 #25
0
        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));
        }
예제 #26
0
        /// <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);
        }
예제 #27
0
        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);
        }
예제 #28
0
        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);
        }
예제 #29
0
 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);
 }
예제 #30
0
        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);
        }
예제 #31
0
 internal BatchGet(DynamoDBContext context, DynamoDBFlatConfig config)
 {
     Context = context;
     Config = config;
     Keys = new List<Key>();
 }
예제 #32
0
 internal BatchWrite(DynamoDBContext context, DynamoDBFlatConfig config)
 {
     Context = context;
     Config = config;
 }