public abstract Task RestoreCounterAsync(IDatabase redisDatabase, RedisKeyObject key, string table = "demgelcounter", CancellationToken token = default(CancellationToken));
public HashEntry[] RestoreHash(IDatabase redisDatabase, RedisKeyObject hashKey) { return(Task.Run(async() => await RestoreHashAsync(redisDatabase, hashKey)).Result); }
public static void GenerateId(this IDatabase database, RedisKeyObject key, object argument, IRedisBackup redisBackup) { var redisIdAttr = argument.GetType().GetProperties().SingleOrDefault( x => x.HasAttribute <RedisIdKey>()); // This is a TEST will fix later if (redisIdAttr == null) { redisIdAttr = argument.GetType().BaseType?.GetProperties().SingleOrDefault( x => x.HasAttribute <RedisIdKey>()); } if (redisIdAttr == null) { return; // Throw error } object value; if (argument is IProxyTargetAccessor) { var generalInterceptor = ((IProxyTargetAccessor)argument).GetInterceptors().SingleOrDefault(x => x is GeneralGetInterceptor) as GeneralGetInterceptor; if (generalInterceptor == null) { throw new Exception("Interceptor cannot be null"); } value = generalInterceptor.GetId(); } else { value = redisIdAttr.GetValue(argument, null); } if (redisIdAttr.PropertyType == typeof(string)) { var currentValue = (string)value; if (string.IsNullOrEmpty(currentValue)) { redisBackup?.RestoreCounter(database, key); var newId = database.StringIncrement($"demgelcounter:{key.CounterKey}"); redisBackup?.UpdateCounter(database, key); key.Id = newId.ToString(); redisIdAttr.SetValue(argument, key.Id); } else { key.Id = currentValue; } } else if (redisIdAttr.PropertyType == typeof(Guid)) { var guid = (Guid)value; if (guid == Guid.Empty) { guid = Guid.NewGuid(); key.Id = guid.ToString(); redisIdAttr.SetValue(argument, guid); } else { key.Id = guid.ToString(); } } else { throw new ArgumentException("RedisIdKey needs to be either Guid or String"); } }
public void AddListItem(RedisKeyObject key, RedisValue value) { Task.Run(async() => await AddListItemAsync(key, value)).Wait(); }
public void Intercept(IInvocation invocation) { var prop = ((IProxyTargetAccessor)invocation.Proxy).GetTargetPropertyInfo(); var hashKey = new RedisKeyObject(prop, _commonData.Id); _commonData.RedisObjectManager.RedisBackup?.RestoreHash(_commonData.RedisDatabase, hashKey); object dictKey = null, dictValue = null; // Determine if this is a KeyValuePair or a 2 argument if (invocation.Arguments.Length == 2) { dictKey = invocation.Arguments[0]; dictValue = invocation.Arguments[1]; } else { var valuePairType = invocation.Arguments[0].GetType(); if (valuePairType.Name.StartsWith("KeyValuePair", StringComparison.Ordinal)) { dictKey = valuePairType.GetProperty("Key").GetValue(invocation.Arguments[0]); dictValue = valuePairType.GetProperty("Value").GetValue(invocation.Arguments[0]); } } if (dictKey == null || dictValue == null) { throw new NullReferenceException("Key or Value cannot be null"); } var containsKeyMethod = invocation.Proxy.GetType().GetMethod("ContainsKey", new[] { dictKey.GetType() }); if ((bool)containsKeyMethod.Invoke(invocation.Proxy, new[] { dictKey })) { invocation.Proceed(); return; } var redisObject = dictValue as IRedisObject; if (redisObject != null) { RedisKeyObject key; if (!(dictValue is IProxyTargetAccessor)) { var proxy = redisObject.CreateProxy(_commonData, out key); invocation.Arguments[1] = proxy; dictValue = proxy; } else { key = new RedisKeyObject(redisObject.GetType()); _commonData.RedisDatabase.GenerateId(key, dictValue, _commonData.RedisObjectManager.RedisBackup); } if (_commonData.Processing) { invocation.Proceed(); return; } HashEntry hashEntry; if (dictKey is RedisValue) { hashEntry = new HashEntry((RedisValue)dictKey, key.RedisKey); } else { RedisValue redisKey; if (!_commonData.RedisObjectManager.TryConvertToRedisValue(dictKey, out redisKey)) { throw new Exception("Invalid Key Type..."); } hashEntry = new HashEntry(redisKey, key.RedisKey); } _commonData.RedisObjectManager.RedisBackup?.UpdateHashValue(hashEntry, hashKey); _commonData.RedisDatabase.HashSet(hashKey.RedisKey, hashEntry.Name, hashEntry.Value); _commonData.RedisObjectManager.SaveObject(dictValue, key.Id, _commonData.RedisDatabase); } else { if (_commonData.Processing) { invocation.Proceed(); return; } // Converter can get rid of this too RedisValue newDictValue; if (!(dictValue is RedisValue)) { if (!_commonData.RedisObjectManager.TryConvertToRedisValue(dictValue, out newDictValue)) { throw new Exception("Cannot convert to RedisValue"); } } else { newDictValue = (RedisValue)dictValue; } HashEntry hashEntry; if (dictKey is RedisValue) { hashEntry = new HashEntry((RedisValue)dictKey, newDictValue); } else { RedisValue redisKey; if (!_commonData.RedisObjectManager.TryConvertToRedisValue(dictKey, out redisKey)) { throw new Exception("Cannot convert to RedisValue"); } hashEntry = new HashEntry(redisKey, newDictValue); } _commonData.RedisObjectManager.RedisBackup?.UpdateHashValue(hashEntry, hashKey); _commonData.RedisDatabase.HashSet(hashKey.RedisKey, hashEntry.Name, hashEntry.Value); } invocation.Proceed(); }
public override object Read(object obj, Type objType, IDatabase redisDatabase, string id, PropertyInfo basePropertyInfo, LimitObject limits = null) { var listKey = new RedisKeyObject(basePropertyInfo, id); var targetType = GetTarget(obj).GetType(); Type itemType = null; if (targetType.GetInterfaces().Any(interfaceType => interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable <>))) { if (targetType.GetGenericArguments().Any()) { itemType = targetType.GetGenericArguments()[0]; } } var method = objType.GetMethod("Add"); var clearMethod = objType.GetMethod("Clear"); if (itemType != null && itemType.GetInterfaces().Contains(typeof(IRedisObject))) { RedisObjectManager.RedisBackup?.RestoreList(redisDatabase, listKey); clearMethod.Invoke(obj, new object[] {}); RedisValue[] retlist; if (limits != null) { retlist = redisDatabase.ListRange(listKey.RedisKey, limits.StartLimit, (limits.TakeLimit - 1) <= 0 ? -1 : limits.TakeLimit - 1 + limits.StartLimit); } else { retlist = redisDatabase.ListRange(listKey.RedisKey); } foreach (var ret in retlist) { //var hashKey = new RedisKeyObject(itemType, ret.ParseKey()); //RedisObjectManager.RedisBackup?.RestoreHash(redisDatabase, hashKey); //// Detect if the base object exists in Redis //if (!redisDatabase.KeyExists((string) ret)) //{ // RedisObjectManager.RedisBackup?.RemoveListItem(listKey, ret); // redisDatabase.ListRemove(listKey.RedisKey, ret, 1); // continue; //} //var newObj = Activator.CreateInstance(itemType); //var newProxy = RedisObjectManager.RetrieveObjectProxy(itemType, hashKey.Id, redisDatabase, newObj); //var redisKeyProp = itemType.GetProperties().SingleOrDefault(x => x.GetCustomAttributes().Any(y => y is RedisIdKey)); //if (redisKeyProp != null) //{ // // Parse the key... // var key = ret.ParseKey(); // if (redisKeyProp.PropertyType == typeof(string)) // { // redisKeyProp.SetValue(newProxy, key); // } // else // { // redisKeyProp.SetValue(newProxy, Guid.Parse(key)); // } //} var newProxy = RedisObjectManager.GetRedisObjectWithType(redisDatabase, (string)ret, ret.ParseKey()); if (newProxy == null) { RedisObjectManager.RedisBackup?.RemoveListItem(listKey, ret); redisDatabase.ListRemove(listKey.RedisKey, ret, 1); } else { method.Invoke(obj, new[] { newProxy }); } } return(obj); } //if (itemType != typeof (RedisValue)) //{ // // Try to process each entry as a proxy, or fail // throw new InvalidCastException($"Use RedisValue instead of {itemType?.Name}."); //} RedisObjectManager.RedisBackup?.RestoreList(redisDatabase, listKey); var retList = redisDatabase.ListRange(listKey.RedisKey); foreach (var ret in retList) { object item; if (RedisObjectManager.TryConvertFromRedisValue(itemType, ret, out item)) { method.Invoke(obj, new[] { item }); } } return(obj); }
private string GetPartitionKey(RedisKeyObject key) { return(key.Suffix != null ? $"{key.Id}:{key.Suffix}" : key.Id); }
public abstract Task <List <RedisValue> > RestoreListAsync(IDatabase redisDatabase, RedisKeyObject listKey, CancellationToken token = default(CancellationToken));
public override async Task <List <RedisValue> > RestoreListAsync(IDatabase redisDatabase, RedisKeyObject listKey, CancellationToken token = default(CancellationToken)) { // Don't bother if a key already exists (Redis first) if (redisDatabase.KeyExists(listKey.RedisKey)) { return(new List <RedisValue>()); } var cloudTable = await GetCloudTableAsync(listKey.Prefix, token); var query = new TableQuery <DynamicTableEntity> { FilterString = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, GetPartitionKey(listKey)) }; var dynamicTableEntities = await cloudTable.ExecuteQuerySegmentedAsync(query, null, token); var listList = new List <RedisValue>(); do { foreach (var item in dynamicTableEntities) { var propType = item["Value"].PropertyType; for (int i = 0; i < item["Count"].Int32Value; i++) { switch (propType) { case EdmType.Binary: listList.Add(item["Value"].BinaryValue); break; case EdmType.String: listList.Add(item["Value"].StringValue); break; } } } dynamicTableEntities = await cloudTable.ExecuteQuerySegmentedAsync(query, dynamicTableEntities.ContinuationToken, token); } while (dynamicTableEntities.ContinuationToken != null); redisDatabase.ListLeftPush(listKey.RedisKey, listList.ToArray()); return(listList); }
public override async Task UpdateSetItemAsync(RedisKeyObject key, SortedSetEntry entry, SortedSetEntry oldValue, CancellationToken token = default(CancellationToken)) { // We remove the oldValue and add the newValue await DeleteSetItemAsync(key, oldValue.Score, token); await AddSetItemAsync(key, entry, token); }
/// <summary> /// Gets and restores the string to the redisDatabase given from table storage /// </summary> /// <param name="redisDatabase"></param> /// <param name="key"></param> /// <param name="table"></param> /// <returns></returns> public override async Task <string> RestoreStringAsync(IDatabase redisDatabase, RedisKeyObject key, string table = "string", CancellationToken token = default(CancellationToken)) { var cloudTable = await GetCloudTableAsync(table, token); var operation = TableOperation.Retrieve <DynamicTableEntity>(key.Prefix, GetPartitionKey(key)); var result = await cloudTable.ExecuteAsync(operation, token); var dynamicResult = result.Result as DynamicTableEntity; EntityProperty resultProperty; string value = dynamicResult != null && dynamicResult.Properties.TryGetValue("value", out resultProperty) ? resultProperty.StringValue : null; if (string.IsNullOrEmpty(value)) { return(value); } // Assume redis database is most upto date? if (redisDatabase.StringSet(key.RedisKey, value, null, When.NotExists)) { return(value); } // value already exists, so update the new value await UpdateStringAsync(redisDatabase, key, table, token); value = redisDatabase.StringGet(key.RedisKey); return(value); }
public override async Task <HashEntry[]> RestoreHashAsync(IDatabase redisDatabase, RedisKeyObject hashKey, CancellationToken token = default(CancellationToken)) { if (redisDatabase.KeyExists(hashKey.RedisKey)) { return(new HashEntry[0]); } var hashes = await GetHashAsync(hashKey, token); if (hashes.Length != 0) { await redisDatabase.HashSetAsync(hashKey.RedisKey, hashes); } return(hashes); }
public override async Task DeleteHashValueAsync(HashEntry entry, RedisKeyObject hashKey, CancellationToken token = default(CancellationToken)) { await DeleteHashValueAsync(entry.Name, hashKey, token); }
public abstract Task <HashEntry[]> RestoreHashAsync(IDatabase redisDatabase, RedisKeyObject hashKey, CancellationToken token = default(CancellationToken));
public void Intercept(IInvocation invocation) { var objectKey = new RedisKeyObject(invocation.InvocationTarget.GetType(), _commonData.Id); if (invocation.Arguments[0] is IRedisObject) { var redisObject = (IRedisObject)invocation.Arguments[0]; // Get or create the new key for the new RedisObject var key = new RedisKeyObject(redisObject.GetType(), string.Empty); _commonData.RedisDatabase.GenerateId(key, redisObject, _commonData.RedisObjectManager.RedisBackup); if (!(invocation.Arguments[0] is IProxyTargetAccessor)) { // Need to make it into a proxy, so it can be saved var proxy = _commonData.RedisObjectManager.RetrieveObjectProxy(redisObject.GetType(), key.Id, _commonData.RedisDatabase, redisObject); invocation.SetArgumentValue(0, proxy); redisObject = proxy as IRedisObject; } // Check to see if there is an ID set in the database (if not it has never been saved) if (!_commonData.Processed) { if (_commonData.RedisDatabase.KeyExists(key.RedisKey)) { invocation.Proceed(); return; } } var property = invocation.Method.ReflectedType?.GetProperties() .SingleOrDefault(x => x.SetMethod != null && x.SetMethod.Name == invocation.Method.Name); if (property != null) { bool deleteCascade = true; // Need to check if the item is currently set (ie are we replacing a value) if (property.HasAttribute <RedisDeleteCascade>()) { deleteCascade = property.GetAttribute <RedisDeleteCascade>().Cascade; } if (deleteCascade) { object currentValue = property.GetValue(invocation.Proxy); if (currentValue is IRedisObject) { RedisKeyObject originalKey = new RedisKeyObject(currentValue.GetType(), string.Empty); _commonData.RedisDatabase.GenerateId(originalKey, currentValue, _commonData.RedisObjectManager.RedisBackup); if (originalKey != key) { ((IRedisObject)currentValue).DeleteRedisObject(); } } } // Need to check is there is a RedisDeleteCascade on property _commonData.RedisObjectManager.RedisBackup?.UpdateHashValue(new HashEntry(property.Name, key.RedisKey), objectKey); _commonData.RedisDatabase.HashSet(objectKey.RedisKey, property.Name, key.RedisKey); _commonData.RedisObjectManager.SaveObject(redisObject, key.Id, _commonData.RedisDatabase); } } else { if (!_commonData.Processed) { if (!_commonData.Processing) { //invocation.Proceed(); //return; _commonData.Processing = true; // Process the proxy (do a retrieveObject) _commonData.RedisObjectManager.RetrieveObject(invocation.Proxy, _commonData.Id, _commonData.RedisDatabase, null); _commonData.Processed = true; _commonData.Processing = false; } } // Set the individual item var property = invocation.Method.ReflectedType?.GetProperties() .SingleOrDefault(x => x.SetMethod.Name == invocation.Method.Name); ITypeConverter converter; if (property != null && _commonData.RedisObjectManager.TypeConverters.TryGetValue(property.PropertyType, out converter)) { var ret = new HashEntry(property.Name, converter.ToWrite(invocation.Arguments[0])); //Need to check if the value already stored is different _commonData.RedisObjectManager.RedisBackup?.RestoreHash(_commonData.RedisDatabase, objectKey); if (_commonData.RedisDatabase.HashGet(objectKey.RedisKey, ret.Name) != ret.Value) { _commonData.RedisObjectManager.RedisBackup?.UpdateHashValue(ret, objectKey); _commonData.RedisDatabase.HashSet(objectKey.RedisKey, ret.Name, ret.Value); } } } invocation.Proceed(); }
public List <RedisValue> RestoreList(IDatabase redisDatabase, RedisKeyObject listKey) { return(Task.Run(async() => await RestoreListAsync(redisDatabase, listKey)).Result); }
public void Intercept(IInvocation invocation) { var prop = ((IProxyTargetAccessor)invocation.Proxy).GetTargetPropertyInfo(); var hashKey = new RedisKeyObject(prop, _commonData.Id); _commonData.RedisObjectManager.RedisBackup?.RestoreHash(_commonData.RedisDatabase, hashKey); // We will need the Original value no matter what var accessor = (IProxyTargetAccessor)invocation.Proxy; var original = (accessor.DynProxyGetTarget() as IDictionary)?[invocation.Arguments[0]]; if (original == null) { return; } object dictKey = null, dictValue = null; // Determine if this is a KeyValuePair or a 2 argument if (invocation.Arguments.Length == 2) { dictKey = invocation.Arguments[0]; dictValue = invocation.Arguments[1]; } else { var valuePairType = invocation.Arguments[0].GetType(); if (valuePairType.Name.StartsWith("KeyValuePair", StringComparison.Ordinal)) { dictKey = valuePairType.GetProperty("Key").GetValue(invocation.Arguments[0]); dictValue = valuePairType.GetProperty("Value").GetValue(invocation.Arguments[0]); } } if (dictKey == null || dictValue == null) { throw new NullReferenceException("Key or Value cannot be Null"); } var valueRedis = dictValue as IRedisObject; if (valueRedis != null) { RedisKeyObject key; if (!(dictValue is IProxyTargetAccessor)) { //var proxy = CreateProxy(valueRedis, out key); var proxy = valueRedis.CreateProxy(_commonData, out key); invocation.Arguments[1] = proxy; dictValue = proxy; } else { key = new RedisKeyObject(valueRedis.GetType(), string.Empty); _commonData.RedisDatabase.GenerateId(key, dictValue, _commonData.RedisObjectManager.RedisBackup); } if (_commonData.Processing) { invocation.Proceed(); return; } // TODO we will need to try to remove the old RedisObject var hashEntry = new HashEntry((string)dictKey, key.RedisKey); _commonData.RedisObjectManager.RedisBackup?.UpdateHashValue(hashEntry, hashKey); _commonData.RedisDatabase.HashSet(hashKey.RedisKey, hashEntry.Name, hashEntry.Value); _commonData.RedisObjectManager.SaveObject(dictValue, key.Id, _commonData.RedisDatabase); } else { if (_commonData.Processing) { invocation.Proceed(); return; } var hashValue = new HashEntry((string)dictKey, (RedisValue)dictValue); _commonData.RedisObjectManager.RedisBackup?.UpdateHashValue(hashValue, hashKey); _commonData.RedisDatabase.HashSet(hashKey.RedisKey, hashValue.Name, hashValue.Value); } invocation.Proceed(); }
public void RestoreSet(IDatabase redisDatabase, RedisKeyObject key) { Task.Run(async() => await RestoreSetAsync(redisDatabase, key)).Wait(); }
public override object Read(object obj, Type objType, IDatabase redisDatabase, string id, PropertyInfo basePropertyInfo, LimitObject limits = null) { var hashKey = new RedisKeyObject(basePropertyInfo, id); RedisObjectManager.RedisBackup?.RestoreHash(redisDatabase, hashKey); if (limits != null && limits.RestoreOnly) { return(obj); } var targetType = GetTarget(obj).GetType(); Type keyType = null; Type itemType = null; if (targetType.GetInterfaces().Any(interfaceType => interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable <>))) { if (targetType.GetGenericArguments().Any()) { keyType = targetType.GetGenericArguments()[0]; itemType = targetType.GetGenericArguments()[1]; } } var method = objType.GetMethod("Add", new [] { keyType, itemType }); // TODO working on this... if (itemType != null && (itemType.GetInterfaces().Contains(typeof(IRedisObject)) || typeof(IRedisObject) == itemType)) { // TODO this all needs to be changed to handle IRedisObjects in a Dictionary, shouldn't be to hard List <HashEntry> retlist; if (limits != null) { if (limits.KeyLimit != null && !limits.KeyLimit.IsNullOrEmpty()) { retlist = new List <HashEntry>(); foreach (var item in limits.KeyLimit) { var ret = redisDatabase.HashGet(hashKey.RedisKey, (string)item); if (!ret.IsNullOrEmpty) { retlist.Add(new HashEntry((string)item, ret)); } } } else if (limits.StartLimit != 0 || limits.TakeLimit != 0) { retlist = redisDatabase.HashScan(hashKey.RedisKey, default(RedisValue), (int)limits.TakeLimit, limits.StartLimit).ToList(); } else { retlist = new List <HashEntry>(); } } else { retlist = redisDatabase.HashGetAll(hashKey.RedisKey).ToList(); } foreach (var ret in retlist) { // We need to check to make sure the object exists (Overhead... it happens) if (!redisDatabase.KeyExists((string)ret.Value)) { redisDatabase.HashDelete(hashKey.RedisKey, ret.Name); continue; } var key = ret.Value.ParseKey(); var newProxy = RedisObjectManager.GetRedisObjectWithType(redisDatabase, (string)ret.Value, key); method.Invoke(obj, new[] { Convert.ChangeType(ret.Name, keyType), newProxy }); } return(obj); } var retList = redisDatabase.HashGetAll(hashKey.RedisKey); foreach (var ret in retList) { object convertedKey; object convertedValue; if (!RedisObjectManager.TryConvertFromRedisValue(keyType, ret.Name, out convertedKey) || !RedisObjectManager.TryConvertFromRedisValue(itemType, ret.Value, out convertedValue)) { throw new Exception("There was an error converting the objects to key/value"); } method.Invoke(obj, new[] { convertedKey, convertedValue }); } return(obj); }