diff --git a/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj b/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj index 5249862..58dc39b 100644 --- a/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj +++ b/Esyur.Stores.MongoDB/Esyur.Stores.MongoDB.csproj @@ -11,7 +11,7 @@ http://www.esyur.com https://github.com/esyur/esyur-dotnet/ True - 1.2.9 + 1.3.0 diff --git a/Esyur.Stores.MongoDB/MongoDBStore.cs b/Esyur.Stores.MongoDB/MongoDBStore.cs index e9cfa92..79deb66 100644 --- a/Esyur.Stores.MongoDB/MongoDBStore.cs +++ b/Esyur.Stores.MongoDB/MongoDBStore.cs @@ -24,21 +24,24 @@ namespace Esyur.Stores.MongoDB IMongoDatabase database; IMongoCollection resourcesCollection; - //List storeParents = new List(); - //List storeChildren = new List(); - //string collectionName; - //string dbName; Dictionary resources = new Dictionary(); - public long Count + [ResourceEvent] + public event ResourceEventHanlder ResourceAdded; + + [ResourceEvent] + public event ResourceEventHanlder ResourceRemoved; + + [ResourceProperty] + public virtual int Count { get { - return resourcesCollection.CountDocuments(x => true); - }// resources.Count; } + return (int)resourcesCollection.CountDocuments(x => true); + } } public void Destroy() @@ -73,6 +76,7 @@ namespace Esyur.Stores.MongoDB return true; } + [ResourceFunction] public bool Remove(IResource resource) { var objectId = resource.Instance.Attributes["objectId"].ToString(); @@ -81,9 +85,15 @@ namespace Esyur.Stores.MongoDB this.database.DropCollection("record_" + objectId); resourcesCollection.DeleteOne(filter); + ResourceRemoved?.Invoke(resource); + + Instance.Modified("Count"); + return true; } + + AsyncReply Fetch(string id) where T : IResource { @@ -304,6 +314,10 @@ namespace Esyur.Stores.MongoDB PutResource(resource).Wait(); + ResourceAdded?.Invoke(resource); + + Instance.Modified("Count"); + return true; } @@ -773,6 +787,8 @@ namespace Esyur.Stores.MongoDB public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime) { + if (resource == this) + return true; var objectId = resource.Instance.Attributes["objectId"].ToString(); diff --git a/Esyur.Stores.MongoDB/MongoDBStoreGeneric.cs b/Esyur.Stores.MongoDB/MongoDBStoreGeneric.cs new file mode 100644 index 0000000..6f6bab5 --- /dev/null +++ b/Esyur.Stores.MongoDB/MongoDBStoreGeneric.cs @@ -0,0 +1,28 @@ +using Esyur.Core; +using Esyur.Data; +using Esyur.Proxy; +using Esyur.Resource; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Esyur.Stores.MongoDB +{ + public class MongoDBStore : MongoDBStore where T:IResource + { + [ResourceFunction] + public T Create(string name, Structure values) + { + return Warehouse.New(name, this, null, null, null, null, values); + } + + [ResourceFunction] + public async AsyncReply Slice(int index, int limit) + { + var list = await this.Instance.Children(); + return list.Skip(index).Take(limit).ToArray(); + } + + } +} diff --git a/Esyur.Stores.MySql/Esyur.Stores.MySql.csproj b/Esyur.Stores.MySql/Esyur.Stores.MySql.csproj index bb0d4d5..3953db9 100644 --- a/Esyur.Stores.MySql/Esyur.Stores.MySql.csproj +++ b/Esyur.Stores.MySql/Esyur.Stores.MySql.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -9,7 +9,7 @@ - + diff --git a/Esyur/Core/AsyncBag.cs b/Esyur/Core/AsyncBag.cs index 0c72bb6..c27ab99 100644 --- a/Esyur/Core/AsyncBag.cs +++ b/Esyur/Core/AsyncBag.cs @@ -90,6 +90,8 @@ namespace Esyur.Core Add(r); } + + public AsyncBag() { diff --git a/Esyur/Esyur.csproj b/Esyur/Esyur.csproj index 7e8bbe0..3cd7563 100644 --- a/Esyur/Esyur.csproj +++ b/Esyur/Esyur.csproj @@ -7,7 +7,7 @@ https://github.com/Esyur/Esyur-dotnet/blob/master/LICENSE http://www.esyur.com true - 1.4.3 + 1.4.5 https://github.com/esyur/esyur-dotnet Ahmed Kh. Zamil 1.3.1.0 diff --git a/Esyur/Net/HTTP/HTTPConnection.cs b/Esyur/Net/HTTP/HTTPConnection.cs index 116ed26..51a3861 100644 --- a/Esyur/Net/HTTP/HTTPConnection.cs +++ b/Esyur/Net/HTTP/HTTPConnection.cs @@ -286,7 +286,7 @@ namespace Esyur.Net.HTTP //base.Send(fd); - using (var fs = new FileStream(filename, FileMode.Open)) + using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { var buffer = new byte[5000]; diff --git a/Esyur/Net/NetworkConnection.cs b/Esyur/Net/NetworkConnection.cs index fcd2b4b..248f0c6 100644 --- a/Esyur/Net/NetworkConnection.cs +++ b/Esyur/Net/NetworkConnection.cs @@ -177,8 +177,9 @@ namespace Esyur.Net public void Close() { //if (!connected) - // return; + // return; + try { if (sock != null) diff --git a/Esyur/Proxy/ResourceProxy.cs b/Esyur/Proxy/ResourceProxy.cs index b68c584..cd82404 100644 --- a/Esyur/Proxy/ResourceProxy.cs +++ b/Esyur/Proxy/ResourceProxy.cs @@ -111,20 +111,45 @@ namespace Esyur.Proxy ILGenerator g = builder.GetILGenerator(); var getInstance = resourceType.GetTypeInfo().GetProperty("Instance").GetGetMethod(); - + + + //g.Emit(OpCodes.Ldarg_0); + //g.Emit(OpCodes.Ldarg_1); + //g.Emit(OpCodes.Call, pi.GetSetMethod()); + //g.Emit(OpCodes.Nop); + + //g.Emit(OpCodes.Ldarg_0); + //g.Emit(OpCodes.Call, getInstance); + //g.Emit(OpCodes.Ldstr, pi.Name); + //g.Emit(OpCodes.Call, modifyMethod); + //g.Emit(OpCodes.Nop); + + //g.Emit(OpCodes.Ret); + + Label exitMethod = g.DefineLabel(); + Label callModified = g.DefineLabel(); g.Emit(OpCodes.Ldarg_0); g.Emit(OpCodes.Ldarg_1); g.Emit(OpCodes.Call, pi.GetSetMethod()); - g.Emit(OpCodes.Nop); + //g.Emit(OpCodes.Nop); - g.Emit(OpCodes.Nop); g.Emit(OpCodes.Ldarg_0); g.Emit(OpCodes.Call, getInstance); + g.Emit(OpCodes.Dup); + + g.Emit(OpCodes.Brtrue_S, callModified); + + g.Emit(OpCodes.Pop); + g.Emit(OpCodes.Br_S, exitMethod); + + g.MarkLabel(callModified); + g.Emit(OpCodes.Ldstr, pi.Name); g.Emit(OpCodes.Call, modifyMethod); g.Emit(OpCodes.Nop); + g.MarkLabel(exitMethod); g.Emit(OpCodes.Ret); propertyBuilder.SetSetMethod(builder); diff --git a/Esyur/Resource/Instance.cs b/Esyur/Resource/Instance.cs index 44e2509..08f3717 100644 --- a/Esyur/Resource/Instance.cs +++ b/Esyur/Resource/Instance.cs @@ -816,10 +816,10 @@ namespace Esyur.Resource Type t = ResourceProxy.GetBaseType(resource); #if NETSTANDARD - var events = t.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + var events = t.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); #else - var events = t.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + var events = t.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); #endif foreach (var evt in events) diff --git a/Esyur/Resource/Template/ResourceTemplate.cs b/Esyur/Resource/Template/ResourceTemplate.cs index 1d80714..2aedeb1 100644 --- a/Esyur/Resource/Template/ResourceTemplate.cs +++ b/Esyur/Resource/Template/ResourceTemplate.cs @@ -140,14 +140,14 @@ namespace Esyur.Resource.Template #if NETSTANDARD - PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); - EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); - MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); + EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); + MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance); // | BindingFlags.DeclaredOnly); #else - PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); - EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); - MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); + PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); + EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); + MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly); #endif //byte currentIndex = 0; diff --git a/Esyur/Resource/Warehouse.cs b/Esyur/Resource/Warehouse.cs index 774a4d0..f91f833 100644 --- a/Esyur/Resource/Warehouse.cs +++ b/Esyur/Resource/Warehouse.cs @@ -52,12 +52,14 @@ namespace Esyur.Resource public delegate void StoreConnectedEvent(IStore store, string name); public delegate void StoreDisconnectedEvent(IStore store); - + public static event StoreConnectedEvent StoreConnected; public static event StoreDisconnectedEvent StoreDisconnected; public static KeyList> Protocols { get; } = getSupportedProtocols(); + private static Regex urlRegex = new Regex(@"^(?:([\S]*)://([^/]*)/?)"); + static KeyList> getSupportedProtocols() { @@ -92,7 +94,7 @@ namespace Esyur.Resource if (resources[id].TryGetTarget(out r)) return new AsyncReply(r); else - return new AsyncReply(null); + return new AsyncReply(null); } else return new AsyncReply(null); @@ -106,7 +108,7 @@ namespace Esyur.Resource public static async AsyncReply Open() { - foreach(var rk in resources) + foreach (var rk in resources) { IResource r; if (rk.Value.TryGetTarget(out r)) @@ -296,7 +298,7 @@ namespace Esyur.Resource */ - + public static async AsyncReply Query(string path) { var rt = new AsyncReply(); @@ -314,8 +316,8 @@ namespace Esyur.Resource var res = await store.Get(String.Join("/", p.Skip(1).ToArray())); if (res != null) return new IResource[] { res }; - - + + resource = store; for (var i = 1; i < p.Length; i++) { @@ -348,35 +350,42 @@ namespace Esyur.Resource public static AsyncReply Get(string path, object attributes = null, IResource parent = null, IPermissionsManager manager = null) { var rt = new AsyncReply(); - + // Should we create a new store ? - if (path.Contains("://")) + if (urlRegex.IsMatch(path)) { - var url = path.Split(new string[] { "://" }, 2, StringSplitOptions.None); - var hostname = url[1].Split(new char[] { '/' }, 2)[0]; - var pathname = string.Join("/", url[1].Split(new char[] { '/' }).Skip(1)); + + //if (path.Contains("://")) + //{ + var url = urlRegex.Split(path); + //var url = path.Split(new string[] { "://" }, 2, StringSplitOptions.None); + //var hostname = url[1].Split(new char[] { '/' }, 2)[0]; + //var pathname = string.Join("/", url[1].Split(new char[] { '/' }).Skip(1)); - if (Protocols.ContainsKey(url[0])) + if (Protocols.ContainsKey(url[1])) { - var handler = Protocols[url[0]]; + var handler = Protocols[url[1]]; var store = handler(); - Put(store, hostname, null, parent, null, 0, manager, attributes); + Put(store, url[2], null, parent, null, 0, manager, attributes); - store.Trigger(ResourceTrigger.Open).Then(x => { + store.Trigger(ResourceTrigger.Open).Then(x => + { warehouseIsOpen = true; - if (pathname.Length > 0 && pathname != "") - store.Get(pathname).Then(r => { + if (url[3].Length > 0 && url[3] != "") + store.Get(url[3]).Then(r => + { rt.Trigger(r); }).Error(e => rt.TriggerError(e)); else rt.Trigger(store); - }).Error(e => { + }).Error(e => + { rt.TriggerError(e); Warehouse.Remove(store); }); @@ -384,19 +393,19 @@ namespace Esyur.Resource return rt; } } - - + + Query(path).Then(rs => { - // rt.TriggerError(new Exception()); + // rt.TriggerError(new Exception()); if (rs != null && rs.Length > 0) rt.Trigger(rs.First()); else rt.Trigger(null); }); - + return rt; - + } @@ -449,9 +458,9 @@ namespace Esyur.Resource else parent.Instance.Children.Add(resource); */ - - if (resource is IStore) + + if (resource is IStore) StoreConnected?.Invoke(resource as IStore, name); //else store.Put(resource); @@ -468,15 +477,59 @@ namespace Esyur.Resource resources.Add(resource.Instance.Id, new WeakReference(resource)); if (warehouseIsOpen) - resource.Trigger(ResourceTrigger.Initialize); + resource.Trigger(ResourceTrigger.Initialize); } - public static T New(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null) - where T:IResource + public static T New(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null, Structure arguments = null, Structure properties = null) + where T : IResource { var type = ResourceProxy.GetProxy(); + + + /* + if (arguments != null) + { + var constructors = type.GetConstructors(System.Reflection.BindingFlags.Public); + + foreach(var constructor in constructors) + { + var pi = constructor.GetParameters(); + if (pi.Length == constructor.le) + } + + // cast arguments + ParameterInfo[] pi = fi.GetParameters(); + + object[] args = new object[pi.Length]; + + for (var i = 0; i < pi.Length; i++) + { + if (pi[i].ParameterType == typeof(DistributedConnection)) + { + args[i] = this; + } + else if (namedArgs.ContainsKey(pi[i].Name)) + { + args[i] = DC.CastConvert(namedArgs[pi[i].Name], pi[i].ParameterType); + } + } + + constructors[0]. + } + */ var res = Activator.CreateInstance(type) as IResource; + + if (properties != null) + { + foreach (var p in properties) + { + var pi = typeof(T).GetProperty(p.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly); + if (pi != null) + pi.SetValue(res, p.Value); + } + } + Put(res, name, store, parent, null, 0, manager, attributes); return (T)res; } @@ -533,7 +586,7 @@ namespace Esyur.Resource if (t.ClassName == className) return new AsyncReply(t); - return null; + return null; } public static bool Remove(IResource resource) @@ -542,7 +595,7 @@ namespace Esyur.Resource if (resource.Instance == null) return false; - if (resources.ContainsKey(resource.Instance.Id)) + if (resources.ContainsKey(resource.Instance.Id)) resources.Remove(resource.Instance.Id); else return false; @@ -552,7 +605,8 @@ namespace Esyur.Resource stores.Remove(resource as IStore); // remove all objects associated with the store - var toBeRemoved = resources.Values.Where(x => { + var toBeRemoved = resources.Values.Where(x => + { IResource r; return x.TryGetTarget(out r) && r.Instance.Store == resource; }).ToArray(); @@ -566,13 +620,13 @@ namespace Esyur.Resource StoreDisconnected?.Invoke(resource as IStore); } - + if (resource.Instance.Store != null) resource.Instance.Store.Remove(resource); resource.Destroy(); return true; - } + } } }