public override object Read(object obj, Type objType, IDatabase redisDatabase, string id, PropertyInfo basePropertyInfo, LimitObject limits = null) { var setKey = new RedisKeyObject(basePropertyInfo, id); // TODO Workon RedisBackup if (limits != null && limits.RestoreOnly) { return(obj); } 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", BindingFlags.DeclaredOnly, null, new[] { itemType }, null); var method = objType.GetMethods() .SingleOrDefault(x => x.Name.Equals("Add") && x.ReturnType == typeof(bool)); if (itemType != null && (itemType.GetInterfaces().Contains(typeof(IRedisObject)) || typeof(IRedisObject) == itemType)) { List <RedisValue> retList; // TODO add limits to sets (for now we just grab everything) if (limits != null) { retList = redisDatabase.SortedSetRangeByScore(setKey.RedisKey, limits.StartLimit, limits.EndLimit, Exclude.None, limits.Order, limits.SkipLimit, limits.TakeLimit).ToList(); } else { retList = redisDatabase.SortedSetRangeByRank(setKey.RedisKey).ToList(); } foreach (var ret in retList) { if (!redisDatabase.KeyExists((string)ret)) { redisDatabase.SortedSetRemove(setKey.RedisKey, (string)ret); continue; } var key = ret.ParseKey(); var newProxy = RedisObjectManager.GetRedisObjectWithType(redisDatabase, (string)ret, key); var t = method.Invoke(obj, new[] { newProxy as IRedisObject }); } } return(obj); }
public override object Read(object obj, Type objType, IDatabase redisDatabase, string id, PropertyInfo basePropertyInfo, LimitObject limits = null) { if (id == null) { throw new Exception("Id can't be null"); } var redisKey = new RedisKeyObject(objType, id); RedisObjectManager.RedisBackup?.RestoreHash(redisDatabase, redisKey); var ret = redisDatabase.HashGetAll(redisKey.RedisKey); // Attempt to set all given properties obj = RedisObjectManager.ConvertToObject(obj, ret); // Do we continue here if it is a base system class? if (!(obj is IRedisObject)) { return(obj); } var props = obj.GetType().GetProperties(); foreach (var prop in props) { // If value is virtual assume it is lazy if (!prop.GetMethod.IsVirtual) { continue; } // Create proxies here if (prop.PropertyType.IsSealed) { continue; } if (!prop.PropertyType.IsClass && !prop.PropertyType.IsInterface) { continue; } try { // If the target is an IRedisObject we need to get the ID differently string objectKey = null; //RedisValue propKey = new RedisValue(); if (prop.PropertyType.GetInterfaces().Any(x => x == typeof(IRedisObject))) { // Try to get the property value from ret RedisValue propKey; if (ret.ToDictionary().TryGetValue(prop.Name, out propKey)) { objectKey = propKey.ParseKey(); if (prop.GetValue(obj, null) == null) { var pr = RedisObjectManager.GetRedisObjectWithType(redisDatabase, (string)propKey, objectKey); obj.GetType().GetProperty(prop.Name).SetValue(obj, pr); } } else { if (prop.PropertyType.IsInterface) { throw new Exception("Properties of type Interface need to be populated first"); } else { object baseObject = prop.GetValue(obj, null) ?? Activator.CreateInstance(prop.PropertyType); var key = new RedisKeyObject(baseObject.GetType(), string.Empty); redisDatabase.GenerateId(key, baseObject, null); objectKey = key.Id; if (!(baseObject is IProxyTargetAccessor)) { var pr = RedisObjectManager.RetrieveObjectProxy(prop.PropertyType, objectKey, redisDatabase, baseObject, obj); obj.GetType().GetProperty(prop.Name).SetValue(obj, pr); } } } } else { // Here we try to handle NON redisObjects object baseObject = prop.GetValue(obj, null) ?? Activator.CreateInstance(prop.PropertyType); objectKey = id; if (!(baseObject is IProxyTargetAccessor)) { var pr = RedisObjectManager.RetrieveObjectProxy(prop.PropertyType, objectKey, redisDatabase, baseObject, obj); obj.GetType().GetProperty(prop.Name).SetValue(obj, pr); } } } catch (Exception e) { Debug.WriteLine(e); } } return(obj); }
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); }
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); }