public virtual AttributeValue ToMapAttributeValue(IPocoDynamo db, object oMap)
        {
            var map = oMap as IDictionary
                      ?? oMap.ToObjectDictionary();

            var meta = DynamoMetadata.GetType(oMap.GetType());

            var to = new Dictionary <string, AttributeValue>();

            foreach (var key in map.Keys)
            {
                var value = map[key];
                if (value != null)
                {
                    value = ApplyFieldBehavior(db,
                                               meta,
                                               meta?.GetField((string)key),
                                               oMap,
                                               value);
                }

                to[key.ToString()] = value != null
                    ? ToAttributeValue(db, value.GetType(), GetFieldType(value.GetType()), value)
                    : new AttributeValue
                {
                    NULL = true
                };
            }
            return(new AttributeValue {
                M = to, IsMSet = true
            });
        }
Esempio n. 2
0
        public async Task <List <T> > GetItemsAsync <T>(IEnumerable <DynamoId> ids, CancellationToken token = default)
        {
            var to = new List <T>();

            var table        = DynamoMetadata.GetTable <T>();
            var remainingIds = ids.ToList();

            while (remainingIds.Count > 0)
            {
                var batchSize = Math.Min(remainingIds.Count, MaxReadBatchSize);
                var nextBatch = remainingIds.GetRange(0, batchSize);
                remainingIds.RemoveRange(0, batchSize);

                var getItems = new KeysAndAttributes
                {
                    ConsistentRead = ConsistentRead,
                };
                nextBatch.Each(id =>
                               getItems.Keys.Add(Converters.ToAttributeKeyValue(this, table, id)));

                to.AddRange(await ConvertBatchGetItemResponseAsync <T>(table, getItems, token).ConfigAwait());
            }

            return(to);
        }
Esempio n. 3
0
        public void PutItems <T>(IEnumerable <T> items)
        {
            var table     = DynamoMetadata.GetTable <T>();
            var remaining = items.ToList();

            PopulateMissingHashes(table, remaining);

            while (remaining.Count > 0)
            {
                var batchSize = Math.Min(remaining.Count, MaxWriteBatchSize);
                var nextBatch = remaining.GetRange(0, batchSize);
                remaining.RemoveRange(0, batchSize);

                var putItems = nextBatch.Map(x => new WriteRequest(
                                                 new PutRequest(Converters.ToAttributeValues(this, x, table))));

                var request = new BatchWriteItemRequest(new Dictionary <string, List <WriteRequest> > {
                    { table.Name, putItems }
                });

                var response = Exec(() => DynamoDb.BatchWriteItem(request));

                var i = 0;
                while (response.UnprocessedItems.Count > 0)
                {
                    response = Exec(() => DynamoDb.BatchWriteItem(new BatchWriteItemRequest(response.UnprocessedItems)));

                    if (response.UnprocessedItems.Count > 0)
                    {
                        i.SleepBackOffMultiplier();
                    }
                }
            }
        }
Esempio n. 4
0
        public long DescribeItemCount <T>()
        {
            var table    = DynamoMetadata.GetTable <T>();
            var response = Exec(() => DynamoDb.DescribeTable(new DescribeTableRequest(table.Name)));

            return(response.Table.ItemCount);
        }
Esempio n. 5
0
        public long Increment <T>(object hash, string fieldName, long amount = 1)
        {
            var type    = DynamoMetadata.GetType <T>();
            var request = new UpdateItemRequest
            {
                TableName        = type.Name,
                Key              = Converters.ToAttributeKeyValue(this, type.HashKey, hash),
                AttributeUpdates = new Dictionary <string, AttributeValueUpdate> {
                    {
                        fieldName,
                        new AttributeValueUpdate {
                            Action = AttributeAction.ADD,
                            Value  = new AttributeValue {
                                N = amount.ToString()
                            }
                        }
                    }
                },
                ReturnValues = ReturnValue.ALL_NEW,
            };

            var response = DynamoDb.UpdateItem(request);

            return(response.Attributes.Count > 0
                ? Convert.ToInt64(response.Attributes[fieldName].N)
                : 0);
        }
Esempio n. 6
0
        public List <T> GetItems <T>(IEnumerable <DynamoId> ids)
        {
            var to = new List <T>();

            var table        = DynamoMetadata.GetTable <T>();
            var remainingIds = ids.ToList();

            while (remainingIds.Count > 0)
            {
                var batchSize = Math.Min(remainingIds.Count, MaxReadBatchSize);
                var nextBatch = remainingIds.GetRange(0, batchSize);
                remainingIds.RemoveRange(0, batchSize);

                var getItems = new KeysAndAttributes
                {
                    ConsistentRead = ConsistentRead,
                };
                nextBatch.Each(id =>
                               getItems.Keys.Add(Converters.ToAttributeKeyValue(this, table, id)));

                to.AddRange(ConvertBatchGetItemResponse <T>(table, getItems));
            }

            return(to);
        }
Esempio n. 7
0
        public long ScanItemCount <T>()
        {
            var table    = DynamoMetadata.GetTable <T>();
            var request  = new ScanRequest(table.Name);
            var response = Scan(request, r => new[] { r.Count });

            return(response.Sum());
        }
 public PocoDynamoExpression(Type type)
 {
     Type             = type;
     Table            = DynamoMetadata.GetType(type);
     ParamPrefix      = "p";
     Params           = new Dictionary <string, object>();
     ReferencedFields = new List <string>();
     Aliases          = new Dictionary <string, string>();
 }
Esempio n. 9
0
        protected void OnVisitMemberType(Type modelType)
        {
            var tableDef = DynamoMetadata.TryGetTable(modelType);

            if (tableDef != null)
            {
                VisitedExpressionIsTable = true;
            }
        }
Esempio n. 10
0
        public void UpdateItem <T>(DynamoUpdateItem update)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new UpdateItemRequest
            {
                TableName        = table.Name,
                Key              = Converters.ToAttributeKeyValue(this, table, update.Hash, update.Range),
                AttributeUpdates = new Dictionary <string, AttributeValueUpdate>(),
                ReturnValues     = ReturnValue.NONE,
            };

            if (update.Put != null)
            {
                foreach (var entry in update.Put)
                {
                    var field = table.GetField(entry.Key);
                    if (field == null)
                    {
                        continue;
                    }

                    request.AttributeUpdates[field.Name] = new AttributeValueUpdate(
                        Converters.ToAttributeValue(this, field.Type, field.DbType, entry.Value), DynamoAttributeAction.Put);
                }
            }

            if (update.Add != null)
            {
                foreach (var entry in update.Add)
                {
                    var field = table.GetField(entry.Key);
                    if (field == null)
                    {
                        continue;
                    }

                    request.AttributeUpdates[field.Name] = new AttributeValueUpdate(
                        Converters.ToAttributeValue(this, field.Type, field.DbType, entry.Value), DynamoAttributeAction.Add);
                }
            }

            if (update.Delete != null)
            {
                foreach (var key in update.Delete)
                {
                    var field = table.GetField(key);
                    if (field == null)
                    {
                        continue;
                    }

                    request.AttributeUpdates[field.Name] = new AttributeValueUpdate(null, DynamoAttributeAction.Delete);
                }
            }

            Exec(() => DynamoDb.UpdateItem(request));
        }
Esempio n. 11
0
        public IEnumerable <T> ScanAll <T>()
        {
            var type    = DynamoMetadata.GetType <T>();
            var request = new ScanRequest
            {
                Limit     = PagingLimit,
                TableName = type.Name,
            };

            return(Scan(request, r => r.ConvertAll <T>()));
        }
Esempio n. 12
0
        public void DeleteRelatedItems <T>(object hash, IEnumerable <object> ranges)
        {
            var table = DynamoMetadata.GetTable <T>();

            if (table.HashKey == null || table.RangeKey == null)
            {
                throw new ArgumentException($"Related table '{typeof(T).Name}' needs both a HashKey and RangeKey");
            }

            DeleteItems <T>(ranges.Map(range => new DynamoId(hash, range)));
        }
Esempio n. 13
0
        public async Task DeleteRelatedItemsAsync <T>(object hash, IEnumerable <object> ranges, CancellationToken token = default)
        {
            var table = DynamoMetadata.GetTable <T>();

            if (table.HashKey == null || table.RangeKey == null)
            {
                throw new ArgumentException($"Related table '{typeof(T).Name}' needs both a HashKey and RangeKey");
            }

            await DeleteItemsAsync <T>(ranges.Map(range => new DynamoId(hash, range)), token).ConfigAwait();
        }
Esempio n. 14
0
        public T GetItem <T>(object hash, object range)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new GetItemRequest
            {
                TableName      = table.Name,
                Key            = Converters.ToAttributeKeyValue(this, table, hash, range),
                ConsistentRead = ConsistentRead,
            };

            return(ConvertGetItemResponse <T>(request, table));
        }
Esempio n. 15
0
        public async Task <T> GetItemAsync <T>(object hash, object range, CancellationToken token = default)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new GetItemRequest
            {
                TableName      = table.Name,
                Key            = Converters.ToAttributeKeyValue(this, table, hash, range),
                ConsistentRead = ConsistentRead,
            };

            return(await ConvertGetItemResponseAsync <T>(request, table, token).ConfigAwait());
        }
Esempio n. 16
0
        public void PutRelatedItem <T>(object hash, T item)
        {
            var table = DynamoMetadata.GetTable <T>();

            if (table.HashKey == null || table.RangeKey == null)
            {
                throw new ArgumentException($"Related table '{typeof(T).Name}' needs both a HashKey and RangeKey");
            }

            table.HashKey.SetValue(item, hash);
            PutItem(item);
        }
Esempio n. 17
0
        public void PutRelatedItems <T>(object hash, IEnumerable <T> items)
        {
            var table = DynamoMetadata.GetTable <T>();

            if (table.HashKey == null || table.RangeKey == null)
            {
                throw new ArgumentException($"Related table '{typeof(T).Name}' needs both a HashKey and RangeKey");
            }

            var related = items.ToList();

            related.Each(x => table.HashKey.SetValue(x, hash));
            PutItems(related);
        }
Esempio n. 18
0
        public static DynamoMetadataType GetIndexTable(this Type indexType)
        {
            var genericIndex = indexType.GetTypeWithGenericInterfaceOf(typeof(IDynamoIndex <>));

            if (genericIndex == null)
            {
                return(null);
            }

            var tableType = genericIndex.GetGenericArguments().FirstOrDefault();

            return(tableType != null
                ? DynamoMetadata.GetTable(tableType)
                : null);
        }
Esempio n. 19
0
        public T PutItem <T>(T value, bool returnOld = false)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new PutItemRequest
            {
                TableName    = table.Name,
                Item         = Converters.ToAttributeValues(this, value, table),
                ReturnValues = returnOld ? ReturnValue.ALL_OLD : ReturnValue.NONE,
            };

            var response = Exec(() => DynamoDb.PutItem(request));

            if (response.Attributes.IsEmpty())
            {
                return(default);
Esempio n. 20
0
        public async Task <T> UpdateItemNonDefaultsAsync <T>(T value, bool returnOld = false, CancellationToken token = default)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new UpdateItemRequest
            {
                TableName        = table.Name,
                Key              = Converters.ToAttributeKey(this, table, value),
                AttributeUpdates = Converters.ToNonDefaultAttributeValueUpdates(this, value, table),
                ReturnValues     = returnOld ? ReturnValue.ALL_OLD : ReturnValue.NONE,
            };

            var response = await ExecAsync(async() =>
                                           await DynamoDb.UpdateItemAsync(request, token).ConfigAwait()).ConfigAwait();

            if (response.Attributes.IsEmpty())
            {
                return(default);
Esempio n. 21
0
        public Table GetTableSchema(Type type)
        {
            var table = DynamoMetadata.GetTable(type);

            return(Exec(() =>
            {
                try
                {
                    Table.TryLoadTable(DynamoDb, table.Name, out var awsTable);
                    return awsTable;
                }
                catch (ResourceNotFoundException)
                {
                    return null;
                }
            }, throwNotFoundExceptions));
        }
Esempio n. 22
0
        public IEnumerable <T> GetRelatedItems <T>(object hash)
        {
            var table = DynamoMetadata.GetTable <T>();

            var argType = hash.GetType();
            var dbType  = Converters.GetFieldType(argType);
            var request = new QueryRequest(table.Name)
            {
                Limit = PagingLimit,
                KeyConditionExpression    = $"{table.HashKey.Name} = :k1",
                ExpressionAttributeValues = new Dictionary <string, AttributeValue> {
                    { ":k1", Converters.ToAttributeValue(this, argType, dbType, hash) }
                }
            };

            return(Query(request, r => r.ConvertAll <T>()));
        }
Esempio n. 23
0
        public void DeleteItems <T>(IEnumerable <DynamoId> ids)
        {
            var table        = DynamoMetadata.GetTable <T>();
            var remainingIds = ids.ToList();

            while (remainingIds.Count > 0)
            {
                var batchSize = Math.Min(remainingIds.Count, MaxWriteBatchSize);
                var nextBatch = remainingIds.GetRange(0, batchSize);
                remainingIds.RemoveRange(0, batchSize);

                var deleteItems = nextBatch.Map(id => new WriteRequest(
                                                    new DeleteRequest(Converters.ToAttributeKeyValue(this, table, id))));

                ExecBatchWriteItemResponse <T>(table, deleteItems);
            }
        }
        public virtual object FromMapAttributeValue(Dictionary <string, AttributeValue> map, Type type)
        {
            var from = new Dictionary <string, object>();

            var metaType = DynamoMetadata.GetType(type);

            if (metaType == null)
            {
                var toMap       = (IDictionary)type.CreateInstance();
                var genericDict = type.GetTypeWithGenericTypeDefinitionOf(typeof(IDictionary <,>));
                if (genericDict != null)
                {
                    var genericArgs = genericDict.GetGenericArguments();
                    var keyType     = genericArgs[0];
                    var valueType   = genericArgs[1];

                    foreach (var entry in map)
                    {
                        var key = ConvertValue(entry.Key, keyType);
                        toMap[key] = FromAttributeValue(entry.Value, valueType);
                    }

                    return(toMap);
                }

                throw new ArgumentException("Unknown Map Type " + type.Name);
            }

            foreach (var field in metaType.Fields)
            {
                AttributeValue attrValue;
                if (!map.TryGetValue(field.Name, out attrValue))
                {
                    continue;
                }

                from[field.Name] = FromAttributeValue(attrValue, field.Type);
            }

            var to = from.FromObjectDictionary(type);

            return(to);
        }
Esempio n. 25
0
        public T DeleteItem <T>(object hash, object range, ReturnItem returnItem = ReturnItem.None)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new DeleteItemRequest
            {
                TableName    = table.Name,
                Key          = Converters.ToAttributeKeyValue(this, table, hash, range),
                ReturnValues = returnItem.ToReturnValue(),
            };

            var response = Exec(() => DynamoDb.DeleteItem(request));

            if (response.Attributes.IsEmpty())
            {
                return(default(T));
            }

            return(Converters.FromAttributeValues <T>(table, response.Attributes));
        }
Esempio n. 26
0
        public async Task <T> PutItemAsync <T>(T value, bool returnOld = false, CancellationToken token = default)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new PutItemRequest
            {
                TableName    = table.Name,
                Item         = Converters.ToAttributeValues(this, value, table),
                ReturnValues = returnOld ? ReturnValue.ALL_OLD : ReturnValue.NONE,
            };

            var response = await ExecAsync(async() =>
                                           await DynamoDb.PutItemAsync(request, token).ConfigAwait()).ConfigAwait();

            if (response.Attributes.IsEmpty())
            {
                return(default(T));
            }

            return(Converters.FromAttributeValues <T>(table, response.Attributes));
        }
Esempio n. 27
0
        public T UpdateItemNonDefaults <T>(T value, bool returnOld = false)
        {
            var table   = DynamoMetadata.GetTable <T>();
            var request = new UpdateItemRequest
            {
                TableName        = table.Name,
                Key              = Converters.ToAttributeKey(this, table, value),
                AttributeUpdates = Converters.ToNonDefaultAttributeValueUpdates(this, value, table),
                ReturnValues     = returnOld ? ReturnValue.ALL_OLD : ReturnValue.NONE,
            };

            var response = Exec(() => DynamoDb.UpdateItem(request));

            if (response.Attributes.IsEmpty())
            {
                return(default(T));
            }

            return(Converters.FromAttributeValues <T>(table, response.Attributes));
        }
        public virtual AttributeValue ToListAttributeValue(IPocoDynamo db, object oList)
        {
            var list = ((IEnumerable)oList).Map(x => x);

            if (list.Count <= 0)
            {
                return new AttributeValue {
                           L = new List <AttributeValue>(), IsLSet = true
                }
            }
            ;

            var elType = list[0].GetType();
            var elMeta = DynamoMetadata.GetType(elType);

            if (elMeta != null)
            {
                var autoIncrFields = elMeta.Fields.Where(x => x.IsAutoIncrement).ToList();

                foreach (var field in autoIncrFields)
                {
                    //Avoid N+1 by fetching a batch of ids
                    var autoIds = db.Sequences.GetNextSequences(elMeta, list.Count);
                    for (var i = 0; i < list.Count; i++)
                    {
                        var instance = list[i];
                        var value    = field.GetValue(instance);
                        if (IsNumberDefault(value))
                        {
                            field.SetValue(instance, autoIds[i]);
                        }
                    }
                }
            }

            var values = list.Map(x => ToAttributeValue(db, x.GetType(), GetFieldType(x.GetType()), x));

            return(new AttributeValue {
                L = values
            });
        }
Esempio n. 29
0
        public async Task <List <T> > GetRelatedItemsAsync <T>(object hash, CancellationToken token = default)
        {
            var table = DynamoMetadata.GetTable <T>();

            var argType = hash.GetType();
            var dbType  = Converters.GetFieldType(argType);
            var request = new QueryRequest(table.Name)
            {
                Limit = PagingLimit,
                KeyConditionExpression    = $"{table.HashKey.Name} = :k1",
                ExpressionAttributeValues = new Dictionary <string, AttributeValue> {
                    { ":k1", Converters.ToAttributeValue(this, argType, dbType, hash) }
                }
            };

#if NET472 || NETCORE
            return(await QueryAsync(request, r => r.ConvertAll <T>(), token).ToListAsync(token));
#else
            return(await QueryAsync(request, r => r.ConvertAll <T>(), token).ConfigAwait());
#endif
        }
Esempio n. 30
0
 public static List <T> ConvertAll <T>(this QueryResponse response)
 {
     return(response.Items
            .Select(values => DynamoMetadata.GetType <T>().ConvertTo <T>(values))
            .ToList());
 }